├── .github └── workflows │ └── test.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── art ├── commit.png ├── logo.png └── pull_request.png ├── index.js ├── package-lock.json ├── package.json └── test.js /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Node.js CI 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | 9 | jobs: 10 | test: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: Setup node 17 | uses: actions/setup-node@v3 18 | with: 19 | cache: 'npm' 20 | - run: npm ci 21 | - run: GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }} SHA=${{github.sha}} npm test 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: trusty 2 | language: node_js 3 | node_js: 4 | - "node" 5 | - "6" 6 | cache: 7 | directories: 8 | - node_modules 9 | notifications: 10 | email: false 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Siddharth Kshetrapal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | Github builds/checks for CI 5 |

6 | 7 |

8 |

9 | 10 |
11 | 12 |

13 | 14 |   15 | 16 | [![Code Climate](https://lima.codeclimate.com/github/siddharthkp/github-build/badges/gpa.svg)](https://lima.codeclimate.com/github/siddharthkp/github-build) 17 | [![Known Vulnerabilities](https://snyk.io/test/github/siddharthkp/github-build/badge.svg)](https://snyk.io/test/github/siddharthkp/github-build) 18 | 19 |   20 | 21 | #### Install 22 | 23 | ``` 24 | npm install github-build --save 25 | ``` 26 | 27 | #### Usage 28 | 29 | ```js 30 | const Build = require('github-build') 31 | 32 | const data = { 33 | repo: 'siddharthkp/github-build', // (author/repo) 34 | sha: '6954e71d46be1ae9b0529aae6e00b64d7a1023d4', // (commit sha) 35 | token: 'secret', // (github oauth token: https://developer.github.com/v3/oauth) 36 | label: 'my CI service', 37 | description: 'checking some stuff', 38 | url: 'http://my-ci-service.com/builds/1', // details url 39 | } 40 | 41 | /* Create a build */ 42 | const build = new Build(data) 43 | 44 | /* When you call start, a pending status get's added on github (returns a promise) */ 45 | build.start() 46 | 47 | /* Run your tests */ 48 | 49 | /* If things go well, call pass, it will mark change the status to success ✅ (returns a promise) */ 50 | build.pass() 51 | 52 | /* Or if the tests fail, mark this build as failed ❌ (returns a promise) */ 53 | build.fail() 54 | 55 | /* If you could not run the tests because of incorrect config, just error out the build (returns a promise) */ 56 | build.error() // use when build errors out (returns a promise) 57 | 58 | ``` 59 | 60 |   61 | 62 | If you like it then [you should put a ⭐️ on it](https://www.youtube.com/watch?v=4m1EFMoRFvY) 63 | 64 |   65 | 66 | #### License 67 | 68 | MIT © siddharthkp 69 | -------------------------------------------------------------------------------- /art/commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siddharthkp/github-build/723b1cce3feff4bdded018c5dd604a0e02b9c420/art/commit.png -------------------------------------------------------------------------------- /art/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siddharthkp/github-build/723b1cce3feff4bdded018c5dd604a0e02b9c420/art/logo.png -------------------------------------------------------------------------------- /art/pull_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/siddharthkp/github-build/723b1cce3feff4bdded018c5dd604a0e02b9c420/art/pull_request.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const axios = require('axios') 2 | 3 | class Build { 4 | constructor(meta) { 5 | meta.context = meta.label 6 | meta.target_url = meta.url 7 | this.meta = meta 8 | } 9 | start (message, url) {return update(this.meta, message, url, 'pending')} 10 | pass (message, url) {return update(this.meta, message, url, 'success')} 11 | fail (message, url) {return update(this.meta, message, url, 'failure')} 12 | error (message, url) {return update(this.meta, message, url, 'error')} 13 | } 14 | 15 | const update = (build, message, url, status) => new Promise((resolve, reject) => { 16 | axios({ 17 | method: 'POST', 18 | url: `https://api.github.com/repos/${build.repo}/statuses/${build.sha}`, 19 | responseType: 'json', 20 | data: { 21 | state: status, 22 | target_url: url || build.url, 23 | description: message || build.description, 24 | context: build.context 25 | }, 26 | headers: {'Authorization': `token ${build.token}`} 27 | }) 28 | .then(({status, data}) => resolve({status, data})) 29 | .catch(({response = {status: 500}}) => reject({ 30 | status: response.status, 31 | error: response.data 32 | })) 33 | }) 34 | 35 | module.exports = Build; 36 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-build", 3 | "version": "1.2.3", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "github-build", 9 | "version": "1.2.3", 10 | "license": "MIT", 11 | "dependencies": { 12 | "axios": "1.6.0" 13 | } 14 | }, 15 | "node_modules/asynckit": { 16 | "version": "0.4.0", 17 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 18 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 19 | }, 20 | "node_modules/axios": { 21 | "version": "1.6.0", 22 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", 23 | "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", 24 | "dependencies": { 25 | "follow-redirects": "^1.15.0", 26 | "form-data": "^4.0.0", 27 | "proxy-from-env": "^1.1.0" 28 | } 29 | }, 30 | "node_modules/combined-stream": { 31 | "version": "1.0.8", 32 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 33 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 34 | "dependencies": { 35 | "delayed-stream": "~1.0.0" 36 | }, 37 | "engines": { 38 | "node": ">= 0.8" 39 | } 40 | }, 41 | "node_modules/delayed-stream": { 42 | "version": "1.0.0", 43 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 44 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 45 | "engines": { 46 | "node": ">=0.4.0" 47 | } 48 | }, 49 | "node_modules/follow-redirects": { 50 | "version": "1.15.3", 51 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", 52 | "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==", 53 | "funding": [ 54 | { 55 | "type": "individual", 56 | "url": "https://github.com/sponsors/RubenVerborgh" 57 | } 58 | ], 59 | "engines": { 60 | "node": ">=4.0" 61 | }, 62 | "peerDependenciesMeta": { 63 | "debug": { 64 | "optional": true 65 | } 66 | } 67 | }, 68 | "node_modules/form-data": { 69 | "version": "4.0.0", 70 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 71 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 72 | "dependencies": { 73 | "asynckit": "^0.4.0", 74 | "combined-stream": "^1.0.8", 75 | "mime-types": "^2.1.12" 76 | }, 77 | "engines": { 78 | "node": ">= 6" 79 | } 80 | }, 81 | "node_modules/mime-db": { 82 | "version": "1.52.0", 83 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 84 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 85 | "engines": { 86 | "node": ">= 0.6" 87 | } 88 | }, 89 | "node_modules/mime-types": { 90 | "version": "2.1.35", 91 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 92 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 93 | "dependencies": { 94 | "mime-db": "1.52.0" 95 | }, 96 | "engines": { 97 | "node": ">= 0.6" 98 | } 99 | }, 100 | "node_modules/proxy-from-env": { 101 | "version": "1.1.0", 102 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 103 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 104 | } 105 | }, 106 | "dependencies": { 107 | "asynckit": { 108 | "version": "0.4.0", 109 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 110 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" 111 | }, 112 | "axios": { 113 | "version": "1.6.0", 114 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.0.tgz", 115 | "integrity": "sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg==", 116 | "requires": { 117 | "follow-redirects": "^1.15.0", 118 | "form-data": "^4.0.0", 119 | "proxy-from-env": "^1.1.0" 120 | } 121 | }, 122 | "combined-stream": { 123 | "version": "1.0.8", 124 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 125 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 126 | "requires": { 127 | "delayed-stream": "~1.0.0" 128 | } 129 | }, 130 | "delayed-stream": { 131 | "version": "1.0.0", 132 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 133 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" 134 | }, 135 | "follow-redirects": { 136 | "version": "1.15.3", 137 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz", 138 | "integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==" 139 | }, 140 | "form-data": { 141 | "version": "4.0.0", 142 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", 143 | "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", 144 | "requires": { 145 | "asynckit": "^0.4.0", 146 | "combined-stream": "^1.0.8", 147 | "mime-types": "^2.1.12" 148 | } 149 | }, 150 | "mime-db": { 151 | "version": "1.52.0", 152 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 153 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" 154 | }, 155 | "mime-types": { 156 | "version": "2.1.35", 157 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 158 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 159 | "requires": { 160 | "mime-db": "1.52.0" 161 | } 162 | }, 163 | "proxy-from-env": { 164 | "version": "1.1.0", 165 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 166 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" 167 | } 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-build", 3 | "version": "1.2.4", 4 | "description": "Github builds/checks for CI", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "node test" 8 | }, 9 | "keywords": [ 10 | "github", 11 | "build", 12 | "checks", 13 | "ci" 14 | ], 15 | "homepage": "https://github.com/siddharthkp/github-build", 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/siddharthkp/github-build.git" 19 | }, 20 | "author": "siddharthkp", 21 | "license": "MIT", 22 | "dependencies": { 23 | "axios": "1.6.0" 24 | }, 25 | "files": [ 26 | "index.js" 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | const Build = require('./index') 2 | 3 | const data = { 4 | repo: 'siddharthkp/github-build', 5 | sha: process.env.SHA || process.env.TRAVIS_PULL_REQUEST_SHA || '4391039e9c506a1702ee7971cda4613ca5da2d69', 6 | token: process.env.GITHUB_TOKEN, 7 | label: 'github-build', 8 | description: 'Running some tests' 9 | } 10 | 11 | const build = new Build(data) 12 | build.start() 13 | setTimeout(() => build.pass('Tests passed!', 'https://example.com'), 5000) 14 | 15 | process.on('unhandledRejection', (reason, p) => { 16 | console.log('Unhandled Promise: ') 17 | console.log(reason, p) 18 | process.exit(1) 19 | }) 20 | --------------------------------------------------------------------------------