├── .github ├── config.yml ├── CONTRIBUTING.md └── CODE_OF_CONDUCT.md ├── tests ├── setup.js ├── fixtures │ ├── circle │ │ ├── log.txt │ │ ├── commit.json │ │ ├── build.json │ │ └── output.json │ ├── issues.getComments.json │ ├── issues.getComments-two.json │ └── travis │ │ └── log.txt ├── providers │ ├── __snapshots__ │ │ ├── Travis.test.js.snap │ │ └── Circle.test.js.snap │ ├── Circle.test.js │ └── Travis.test.js ├── index.test.js └── __snapshots__ │ └── index.test.js.snap ├── .gitignore ├── .gcloudignore ├── src ├── default-config.json ├── new-comment.js ├── update-comment.js ├── template.js ├── providers │ ├── Travis.js │ └── Circle.js └── index.js ├── .travis.yml ├── .env.example ├── webpack.config.js ├── LICENSE ├── index.js ├── package.json └── README.md /.github/config.yml: -------------------------------------------------------------------------------- 1 | todo: 2 | keyword: "TODO: " -------------------------------------------------------------------------------- /tests/setup.js: -------------------------------------------------------------------------------- 1 | process.env.LOG_LEVEL = 'fatal' 2 | process.env.APP_NAME = 'pizza-bot' 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | *.pem 4 | .env 5 | package-lock.json 6 | coverage 7 | env.json 8 | dist 9 | .DS_Store 10 | *.zip -------------------------------------------------------------------------------- /.gcloudignore: -------------------------------------------------------------------------------- 1 | .gcloudignore 2 | .git 3 | .gitignore 4 | node_modules 5 | src 6 | coverage 7 | .github 8 | .env 9 | .env.example 10 | .travis.yml 11 | README.md 12 | webpack.config.js 13 | tests 14 | LICENSE 15 | .DS_Store -------------------------------------------------------------------------------- /tests/fixtures/circle/log.txt: -------------------------------------------------------------------------------- 1 | 2 | > failing-repo@1.0.0 test /home/circleci/repo 3 | > echo "Error: no test specified" && exit 1 4 | 5 | Error: no test specified 6 | npm ERR! Test failed. See above for more details. 7 |  -------------------------------------------------------------------------------- /src/default-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "updateComment": true, 3 | "before": "✨ Good work on this PR so far! ✨ Unfortunately, the [{{ provider }} build]({{ targetUrl }}) is failing as of {{ commit }}. Here's the output:", 4 | "after": "I'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project!" 5 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | language: node_js 4 | 5 | node_js: 6 | - "8" 7 | - "9" 8 | 9 | notifications: 10 | disabled: true 11 | 12 | install: 13 | - npm install -g codecov 14 | - npm install 15 | 16 | branches: 17 | except: 18 | - /^v\d+\.\d+\.\d+$/ 19 | 20 | script: 21 | - npm test 22 | - codecov 23 | -------------------------------------------------------------------------------- /src/new-comment.js: -------------------------------------------------------------------------------- 1 | async function newComment ({context, template, data, sha, number, after, before}) { 2 | // If there is not, create one 3 | const body = template({...data, commit: sha, after, before}) 4 | const issue = { number, body } 5 | return context.github.issues.createComment(context.repo(issue)) 6 | } 7 | 8 | module.exports = newComment 9 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # The ID of your GitHub App 2 | APP_ID= 3 | 4 | # The webhook secret set in the GitHub App UI 5 | WEBHOOK_SECRET= 6 | 7 | # Uncomment this to get verbose logging 8 | # LOG_LEVEL: trace # or `info` to show less 9 | 10 | # Subdomain to use for localtunnel server. Defaults to your local username. 11 | # SUBDOMAIN= 12 | 13 | # The kebab-case name of your GitHub App (used to self-identify) 14 | APP_NAME= -------------------------------------------------------------------------------- /tests/providers/__snapshots__/Travis.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Travis parseLog returns the correct string 1`] = ` 4 | Object { 5 | "command": "npm test", 6 | "content": "> public-test@1.0.0 test /home/travis/build/JasonEtco/public-test 7 | > echo \\"Error: no test specified\\" && exit 1 8 | 9 | Error: no test specified", 10 | } 11 | `; 12 | 13 | exports[`Travis serialize returns the correct body string 1`] = ` 14 | "> public-test@1.0.0 test /home/travis/build/JasonEtco/public-test 15 | > echo \\"Error: no test specified\\" && exit 1 16 | 17 | Error: no test specified" 18 | `; 19 | -------------------------------------------------------------------------------- /src/update-comment.js: -------------------------------------------------------------------------------- 1 | async function updateComment ({context, template, data, sha, number, comment, after, before}) { 2 | const lastCommit = //g.exec(comment.body)[1] 3 | const lastLog = /([\s\S]+)/g.exec(comment.body)[1] 4 | const oldLogs = /([\s\S]+)/g.exec(comment.body)[1] 5 | 6 | const body = template({ 7 | ...data, 8 | commit: sha, 9 | oldLogs, 10 | lastLog, 11 | lastCommit: lastCommit.substring(0, 7), 12 | before, 13 | after 14 | }) 15 | 16 | return context.github.issues.editComment(context.repo({ number, body, id: comment.id })) 17 | } 18 | 19 | module.exports = updateComment 20 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | module.exports = { 4 | entry: ['babel-polyfill', './src/index.js'], 5 | target: 'node', 6 | module: { 7 | rules: [{ 8 | test: /\.js$/, 9 | include: [ 10 | __dirname 11 | ], 12 | use: { 13 | loader: 'babel-loader', 14 | options: { 15 | presets: ['babel-preset-es2015'], 16 | plugins: [ 17 | 'transform-async-to-generator', 18 | [ 19 | 'transform-object-rest-spread', 20 | { useBuiltIns: true } 21 | ] 22 | ] 23 | } 24 | } 25 | }] 26 | }, 27 | output: { 28 | library: 'bot', 29 | libraryTarget: 'commonjs', 30 | path: path.join(__dirname, 'dist'), 31 | filename: 'index.js' 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/template.js: -------------------------------------------------------------------------------- 1 | module.exports = `### The build is failing 2 | {{#if before}} 3 | 4 | {{ before }} 5 | 6 | {{/if}} 7 | 8 | ##### \`{{ command }}\` 9 | 10 | \`\`\` 11 | {{{ content }}} 12 | \`\`\` 13 | 14 | {{#if after}} 15 | 16 | {{ after }} 17 | 18 | {{/if}} 19 | {{#if lastLog}} 20 | --- 21 | {{/if}} 22 | 23 | {{#if lastLog}} 24 |
25 | Failed build for {{ lastCommit }} 26 | 27 | {{{ lastLog }}} 28 | 29 |
30 | {{/if}} 31 | 32 | {{{ oldLogs }}} 33 | 34 | 35 | --- 36 | 37 | ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter). 38 | 39 | ` 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) , JasonEtco (https://github.com/jasonetco/ci-viewer) 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /tests/fixtures/issues.getComments.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [{ 3 | "id": 1, 4 | "user": { "login": "JasonEtco" } 5 | }, { 6 | "id": 2, 7 | "user": { "login": "pizza-bot[bot]" }, 8 | "body": "### The build is failing\n\n ✨ Good work on this PR so far! ✨ Unfortunately, the [Travis CI build](https://travis-ci.org/JasonEtco/failing-repo/builds/341165663?utm_source=github_status&utm_medium=notification) is failing as of 8a14336120c8f2fcd255fb1445a53f5c161b5217. Here's the output:\n \n \n ##### `npm test`\n \n ```\n > failing-repo@1.0.0 test /home/travis/build/JasonEtco/failing-repo\n > echo \"Error: no test specified\" && exit 1\n \n Error: no test specified\n ```\n \n \n I'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project!\n \n \n \n \n \n ---\n \n ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter).\n \n " 9 | }] 10 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const createProbot = require('probot-ts') 2 | const { bot } = require('./dist') 3 | 4 | const settings = require('./env.json') 5 | process.env.APP_NAME = 'ci-reporter' 6 | 7 | const probot = createProbot(settings) 8 | 9 | // Creates a Bunyan Stackdriver Logging client 10 | const LoggingBunyan = require('@google-cloud/logging-bunyan') 11 | const loggingBunyan = new LoggingBunyan() 12 | probot.logger.addStream(loggingBunyan.stream()) 13 | 14 | probot.load(bot) 15 | 16 | /** 17 | * Relay GitHub events to the bot 18 | */ 19 | exports.bot = (request, response) => { 20 | const event = request.get('x-github-event') || request.get('X-GitHub-Event') 21 | const id = request.get('x-github-delivery') || request.get('X-GitHub-Delivery') 22 | console.log(`Received event ${event}${request.body.action ? ('.' + request.body.action) : ''}`) 23 | if (event) { 24 | try { 25 | probot.receive({ 26 | event: event, 27 | id: id, 28 | payload: request.body 29 | }).then(() => { 30 | response.send({ 31 | statusCode: 200, 32 | body: JSON.stringify({ 33 | message: 'Executed' 34 | }) 35 | }) 36 | }) 37 | } catch (err) { 38 | console.error(err) 39 | response.sendStatus(500) 40 | } 41 | } else { 42 | console.error(request) 43 | response.sendStatus(400) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ci-viewer", 3 | "version": "1.0.0", 4 | "description": "", 5 | "author": "JasonEtco (https://github.com/jasonetco/ci-viewer)", 6 | "license": "ISC", 7 | "repository": "https://github.com/JasonEtco/ci-viewer.git", 8 | "scripts": { 9 | "start": "node ./node_modules/probot/bin/probot-run ./src/index.js", 10 | "start-dev": "nodemon ./node_modules/probot/bin/probot-run ./src/index.js", 11 | "test": "jest --coverage && standard", 12 | "test:update": "jest -u", 13 | "build": "webpack -p", 14 | "deploy": "npm run build && gcloud beta functions deploy ci-reporter --trigger-http --entry-point bot" 15 | }, 16 | "dependencies": { 17 | "@google-cloud/logging-bunyan": "^0.7.0", 18 | "delay": "^3.0.0", 19 | "probot": "^6.1.0", 20 | "probot-ts": "^4.0.1-typescript", 21 | "request": "^2.83.0", 22 | "request-promise-native": "^1.0.5", 23 | "strip-ansi": "^4.0.0", 24 | "webpack-cli": "^2.0.12" 25 | }, 26 | "devDependencies": { 27 | "babel-core": "^6.26.0", 28 | "babel-loader": "^7.1.2", 29 | "babel-plugin-transform-async-to-generator": "^6.24.1", 30 | "babel-plugin-transform-object-rest-spread": "^6.26.0", 31 | "babel-polyfill": "^6.26.0", 32 | "babel-preset-es2015": "^6.24.1", 33 | "jest": "^22.2.2", 34 | "localtunnel": "^1.8.2", 35 | "nock": "^9.1.4", 36 | "nodemon": "^1.14.12", 37 | "smee-client": "^1.0.1", 38 | "standard": "^11.0.0", 39 | "webpack": "^4.0.0" 40 | }, 41 | "engines": { 42 | "node": ">= 7.7.0", 43 | "npm": ">= 4.0.0" 44 | }, 45 | "standard": { 46 | "env": [ 47 | "jest" 48 | ] 49 | }, 50 | "jest": { 51 | "modulePathIgnorePatterns": [ 52 | "/tests/fixtures/", 53 | "/tests/setup.js" 54 | ], 55 | "setupFiles": [ 56 | "/tests/setup.js" 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | [fork]: /fork 4 | [pr]: /compare 5 | [style]: https://standardjs.com/ 6 | [code-of-conduct]: CODE_OF_CONDUCT.md 7 | 8 | Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great. 9 | 10 | Please note that this project is released with a [Contributor Code of Conduct][code-of-conduct]. By participating in this project you agree to abide by its terms. 11 | 12 | ## Submitting a pull request 13 | 14 | 1. [Fork][fork] and clone the repository 15 | 1. Configure and install the dependencies: `npm install` 16 | 1. Make sure the tests pass on your machine: `npm test`, note: these tests also apply the linter, so no need to lint seperately 17 | 1. Create a new branch: `git checkout -b my-branch-name` 18 | 1. Make your change, add tests, and make sure the tests still pass 19 | 1. Push to your fork and [submit a pull request][pr] 20 | 1. Pat your self on the back and wait for your pull request to be reviewed and merged. 21 | 22 | Here are a few things you can do that will increase the likelihood of your pull request being accepted: 23 | 24 | - Follow the [style guide][style] which is using standard. Any linting errors should be shown when running `npm test` 25 | - Write and update tests. 26 | - Keep your change as focused as possible. If there are multiple changes you would like to make that are not dependent upon each other, consider submitting them as separate pull requests. 27 | - Write a [good commit message](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). 28 | 29 | Work in Progress pull request are also welcome to get feedback early on, or if there is something blocked you. 30 | 31 | ## Resources 32 | 33 | - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) 34 | - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/) 35 | - [GitHub Help](https://help.github.com) 36 | -------------------------------------------------------------------------------- /src/providers/Travis.js: -------------------------------------------------------------------------------- 1 | const request = require('request-promise-native') 2 | const stripAnsi = require('strip-ansi') 3 | const delay = require('delay') 4 | 5 | class Travis { 6 | constructor (context) { 7 | this.context = context 8 | this.retries = 0 9 | this.headers = { 'Travis-API-Version': 3 } 10 | } 11 | 12 | static get ctx () { 13 | return 'continuous-integration/travis-ci/pr' 14 | } 15 | 16 | buildUri (build) { return `https://api.travis-ci.org/build/${build}` } 17 | logUri (job) { return `https://api.travis-ci.org/job/${job}/log.txt` } 18 | 19 | parseLog (log) { 20 | // sp00ky RegExp to start the extraction 21 | const reg = /\[0K\$\snpm\stest(?:\r\n|\n)*([\s\S]+)[\r\n]+.*Test failed\./g 22 | 23 | const result = reg.exec(log) 24 | 25 | if (!result) { 26 | return false 27 | } 28 | 29 | let content = result[1].trim() 30 | return { content, command: 'npm test' } 31 | } 32 | 33 | async getLog (job) { 34 | const res = await request({ 35 | uri: this.logUri(job.id), 36 | headers: this.headers 37 | }) 38 | 39 | const result = this.parseLog(res) 40 | 41 | // Travis sometimes sends back incomplete logs 42 | // if the request is made too quickly. 43 | if (!result && this.retries <= 3) { 44 | this.context.log('Log incomplete; Retrying...') 45 | this.retries = this.retries + 1 46 | 47 | await delay(500) 48 | return this.getLog(job) 49 | } 50 | 51 | return result 52 | } 53 | 54 | async serialize () { 55 | const { target_url: targetUrl } = this.context.payload 56 | const build = /\/builds\/(\d+)/g.exec(targetUrl)[1] 57 | const buildJson = await request({ 58 | json: true, 59 | uri: this.buildUri(build), 60 | headers: this.headers 61 | }) 62 | 63 | // TODO: Account for multiple jobs 64 | const result = await this.getLog(buildJson.jobs[0]) 65 | 66 | if (result) { 67 | const { content, command } = result 68 | return { 69 | number: buildJson.pull_request_number, 70 | data: { 71 | provider: 'Travis CI', 72 | content: stripAnsi(content), 73 | targetUrl, 74 | command 75 | } 76 | } 77 | } 78 | } 79 | } 80 | 81 | module.exports = Travis 82 | -------------------------------------------------------------------------------- /tests/providers/Circle.test.js: -------------------------------------------------------------------------------- 1 | const Circle = require('../../src/providers/Circle') 2 | const nock = require('nock') 3 | const fs = require('fs') 4 | const path = require('path') 5 | 6 | const readFile = file => fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'circle', file), 'utf8') 7 | 8 | describe('Circle', () => { 9 | describe('static get ctx()', () => { 10 | it('returns the correct status context string', () => { 11 | expect(Circle.ctx).toBe('ci/circleci') 12 | }) 13 | }) 14 | 15 | describe('buildUri', () => { 16 | it('creates the correct URI', () => { 17 | const circle = new Circle() 18 | const repo = { owner: 'JasonEtco', repo: 'ci-reporter' } 19 | expect(circle.buildUri(repo, 317090494)).toBe('https://circleci.com/api/v1.1/project/github/JasonEtco/ci-reporter/317090494') 20 | }) 21 | }) 22 | 23 | describe('parseLog', () => { 24 | const log = readFile('log.txt') 25 | it('returns the correct log string', () => { 26 | const circle = new Circle() 27 | const actual = circle.parseLog(log) 28 | expect(actual).toMatchSnapshot() 29 | }) 30 | }) 31 | 32 | describe('serialize', () => { 33 | let circle 34 | 35 | beforeEach(() => { 36 | const build = readFile('build.json') 37 | const output = readFile('output.json') 38 | 39 | nock('https://circleci.com') 40 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, build) 41 | .get('/fake-output-url').reply(200, output) 42 | 43 | circle = new Circle({ 44 | payload: { 45 | target_url: 'https://circleci.com/gh/JasonEtco/todo/5?utm_source=github_status&utm_medium=notification' 46 | }, 47 | repo: () => ({ owner: 'JasonEtco', repo: 'todo' }) 48 | }) 49 | }) 50 | 51 | it('returns the correct content string', async () => { 52 | const res = await circle.serialize() 53 | expect(res.number).toBe(1) 54 | expect(res.data.content).toMatchSnapshot() 55 | }) 56 | 57 | it('returns false if the status is not on a PR', async () => { 58 | nock.cleanAll() 59 | nock('https://circleci.com') 60 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, readFile('commit.json')) 61 | 62 | const res = await circle.serialize() 63 | expect(res).toBeFalsy() 64 | }) 65 | }) 66 | }) 67 | -------------------------------------------------------------------------------- /src/providers/Circle.js: -------------------------------------------------------------------------------- 1 | const request = require('request-promise-native') 2 | const stripAnsi = require('strip-ansi') 3 | 4 | class Circle { 5 | constructor (context) { 6 | this.context = context 7 | } 8 | 9 | static get ctx () { 10 | return 'ci/circleci' 11 | } 12 | 13 | buildUri ({ owner, repo }, build) { return `https://circleci.com/api/v1.1/project/github/${owner}/${repo}/${build}` } 14 | 15 | parseLog (log) { 16 | // sp00ky RegExp to start the extraction 17 | const start = new RegExp(/\r\n|\n/g) 18 | 19 | // The first line can be either \n or \r\n, so 20 | // we need to know how to offset it. 21 | const offset = start.exec(log)[0].length 22 | 23 | const end = 'Test failed. See above for more details.' 24 | 25 | // Get the content between the test and end strings 26 | let content = log.substring(log.search(start) + offset, log.indexOf(end)) 27 | 28 | // Remove the last line, it's usually extra 29 | content = content.substring(0, content.lastIndexOf('\n')) 30 | 31 | return content 32 | } 33 | 34 | async serialize () { 35 | // target_url looks like 36 | // https://circleci.com/gh/:owner/:repo/:number (see tests/fixtures/circle/build.json) 37 | const { target_url: targetUrl } = this.context.payload 38 | const build = /https:\/\/circleci\.com\/gh\/(?:.+?\/){2}(\d+)/g.exec(targetUrl)[1] 39 | 40 | const buildJson = await request({ 41 | json: true, 42 | uri: this.buildUri(this.context.repo(), build), 43 | headers: { Accept: 'application/json' } 44 | }) 45 | 46 | if (buildJson.pull_requests) { 47 | const prUrl = buildJson.pull_requests[0].url 48 | const number = prUrl.substr(prUrl.lastIndexOf('/')).substr(1) 49 | 50 | const failedStep = buildJson.steps.find(step => step.actions.some(action => action.exit_code === 1)) 51 | const failedAction = failedStep.actions[failedStep.actions.length - 1] 52 | 53 | const res = await request({ 54 | json: true, 55 | uri: failedAction.output_url, 56 | gzip: true, 57 | headers: { Accept: 'application/json' } 58 | }) 59 | 60 | const content = this.parseLog(res[0].message) 61 | 62 | return { 63 | number: parseInt(number, 10), 64 | data: { 65 | provider: 'Circle CI', 66 | command: failedStep.name, 67 | content: stripAnsi(content), 68 | targetUrl 69 | } 70 | } 71 | } else { 72 | return false 73 | } 74 | } 75 | } 76 | 77 | module.exports = Circle 78 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | const Travis = require('./providers/Travis') 2 | const Circle = require('./providers/Circle') 3 | const defaultConfig = require('./default-config.json') 4 | const newComment = require('./new-comment') 5 | const updateComment = require('./update-comment') 6 | 7 | // We already have an instance of handlebars from Probot's hbs dependency 8 | const { handlebars } = require('hbs') 9 | const template = handlebars.compile(require('./template')) 10 | 11 | module.exports = robot => { 12 | robot.on('status', async context => { 13 | const { owner, repo } = context.repo() 14 | 15 | // Only trigger on failed statuses 16 | if (context.payload.state === 'failure') { 17 | let serializer 18 | const config = await context.config('ci-reporter.yml', defaultConfig) 19 | 20 | const { context: statusContext, sha } = context.payload 21 | 22 | if (statusContext === Travis.ctx) { 23 | context.log(`Creating TravisCI instance for ${context.id}`) 24 | serializer = new Travis(context) 25 | } else if (statusContext === Circle.ctx) { 26 | context.log(`Creating CircleCI instance for ${context.id}`) 27 | serializer = new Circle(context) 28 | } else { 29 | context.log(`ctx does not exist: ${statusContext}`) 30 | return 31 | } 32 | 33 | // Will return false if something borks 34 | const serialized = await serializer.serialize() 35 | if (serialized) { 36 | const { number, data } = serialized 37 | 38 | const opts = { 39 | context, 40 | template, 41 | data, 42 | sha, 43 | number, 44 | after: config.after && handlebars.compile(config.after)({...data, commit: sha}), 45 | before: config.before && handlebars.compile(config.before)({...data, commit: sha}) 46 | } 47 | 48 | if (config.updateComment) { 49 | // Determine if there is already a comment on this PR from ci-reporter 50 | const comments = await context.github.issues.getComments(context.issue({ number })) 51 | const comment = comments.data.find(comment => comment.user.login === process.env.APP_NAME + '[bot]') 52 | 53 | // If there is, edit that one 54 | if (comment) { 55 | opts.comment = comment 56 | context.log(`Updating comment ${owner}/${repo} #${number}`) 57 | return updateComment(opts) 58 | } 59 | } 60 | 61 | context.log(`Creating comment ${owner}/${repo} #${number}`) 62 | return newComment(opts) 63 | } 64 | } 65 | }) 66 | } 67 | -------------------------------------------------------------------------------- /tests/providers/Travis.test.js: -------------------------------------------------------------------------------- 1 | const Travis = require('../../src/providers/Travis') 2 | const nock = require('nock') 3 | const fs = require('fs') 4 | const path = require('path') 5 | 6 | describe('Travis', () => { 7 | const log = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'travis', 'log.txt'), 'utf8') 8 | 9 | describe('static get ctx()', () => { 10 | it('returns the correct status context string', () => { 11 | expect(Travis.ctx).toBe('continuous-integration/travis-ci/pr') 12 | }) 13 | }) 14 | 15 | describe('buildUri', () => { 16 | it('creates the correct URI', () => { 17 | const travis = new Travis() 18 | expect(travis.buildUri(317090494)).toBe('https://api.travis-ci.org/build/317090494') 19 | }) 20 | }) 21 | 22 | describe('logUri', () => { 23 | it('creates the correct URI', () => { 24 | const travis = new Travis() 25 | expect(travis.logUri(123)).toBe('https://api.travis-ci.org/job/123/log.txt') 26 | }) 27 | }) 28 | 29 | describe('parseLog', () => { 30 | let travis 31 | 32 | beforeEach(() => { 33 | travis = new Travis() 34 | }) 35 | 36 | it('returns the correct string', () => { 37 | expect(travis.parseLog(log)).toMatchSnapshot() 38 | }) 39 | 40 | it('returns false if there are no matches', () => { 41 | expect(travis.parseLog('Hello!')).toBe(false) 42 | }) 43 | }) 44 | 45 | describe('serialize', () => { 46 | let travis 47 | 48 | beforeEach(() => { 49 | travis = new Travis({ 50 | payload: { 51 | target_url: 'https://travis-ci.org/JasonEtco/public-test/builds/123?utm_source=github_status&utm_medium=notification' 52 | }, 53 | log: jest.fn() 54 | }) 55 | }) 56 | 57 | it('returns the correct body string', async () => { 58 | nock('https://api.travis-ci.org') 59 | .get('/build/123').reply(200, { 60 | pull_request_number: 1, 61 | jobs: [{ id: 1234, number: 1, state: 'failed' }] 62 | }) 63 | .get('/job/1234/log.txt').reply(200, log) 64 | 65 | const res = await travis.serialize() 66 | expect(res.number).toBe(1) 67 | expect(res.data.content).toMatchSnapshot() 68 | }) 69 | 70 | it('returns false if there is no match in the log', async () => { 71 | nock('https://api.travis-ci.org').persist() 72 | .get('/build/123').reply(200, { 73 | pull_request_number: 1, 74 | jobs: [{ id: 1234, number: 1, state: 'failed' }] 75 | }) 76 | .get('/job/1234/log.txt').reply(200, 'Hello!') 77 | const res = await travis.serialize() 78 | expect(res).toBeFalsy() 79 | }) 80 | }) 81 | }) 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

ci-reporter

4 |

A GitHub App built with Probot that pastes the error output of a failing commit into the relevant PR

5 |

Build Status Codecov Greenkeeper enabled

6 |

7 | 8 | ## Usage 9 | 10 | Simply [install the app](https://github.com/apps/ci-reporter) and watch the magic happen as your Pull Requests trigger failure statuses. 11 | 12 |

13 | ci-reporter commenting on a PR with failed build log 14 |

15 | 16 | ## How it works 17 | 18 | When a build fails, the CI provider will tell GitHub (via a status). GitHub then tells **ci-reporter** about a failed status, and it'll find the part of the build that failed, then comment back on the PR. 19 | 20 | 21 | 22 | ## Configuration 23 | 24 | You don't need any configuration for this to work in your project but you can customize a few things to fit your needs. You can create a `.github/ci-reporter.yml` file: 25 | 26 | ```yml 27 | # Set to false to create a new comment instead of updating the app's first one 28 | updateComment: true 29 | 30 | # Use a custom string, or set to false to disable 31 | before: "✨ Good work on this PR so far! ✨ Unfortunately, the [{{ provider }} build]({{ targetUrl }}) is failing as of {{ commit }}. Here's the output:" 32 | 33 | # Use a custom string, or set to false to disable 34 | after: "I'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project!" 35 | ``` 36 | 37 | If you need more configuration, please [let me know in a new issue](https://github.com/JasonEtco/ci-reporter/issues/new?title=[Config]&body=Can%20you%20please%20add%20the%20___%20config%20option). 38 | 39 | 40 | 41 | ## Does it work with _____? 42 | 43 | **ci-reporter** currently supports TravisCI and CircleCI. If you're interested in seeing support for another CI tool, please [open an issue](https://github.com/JasonEtco/ci-reporter/issues/new)! 44 | 45 | 46 | 47 | ## Contributing 48 | 49 | So glad you want to contribute! If you're looking to help with a new feature, please open an issue to discuss it first. If you're helping fix a bug, let me know! Check out [the contributing docs](.github/CONTRIBUTING.md) for more details. 50 | -------------------------------------------------------------------------------- /.github/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at jasonetco@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /tests/providers/__snapshots__/Circle.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Circle parseLog returns the correct log string 1`] = ` 4 | "> failing-repo@1.0.0 test /home/circleci/repo 5 | > echo \\"Error: no test specified\\" && exit 1 6 | 7 | Error: no test specified" 8 | `; 9 | 10 | exports[`Circle serialize returns the correct content string 1`] = ` 11 | "> todo@1.0.0 test /home/circleci/repo 12 | > jest && codecov && standard 13 | 14 | PASS __tests__/lib/metadata.js 15 | PASS __tests__/lib/generate-blob-link.js 16 | PASS __tests__/lib/reopen-closed.js 17 | PASS __tests__/lib/commit-is-in-pr.js 18 | PASS __tests__/lib/generate-label.js 19 | PASS __tests__/lib/generate-body.js 20 | PASS __tests__/languages.js 21 | PASS __tests__/installation.js 22 | PASS __tests__/pr-comments.js 23 | PASS __tests__/merge-handler.js 24 | PASS __tests__/open-issues.js 25 | 26 | Test Suites: 11 passed, 11 total 27 | Tests: 70 passed, 70 total 28 | Snapshots: 0 total 29 | Time: 4.335s 30 | Ran all test suites. 31 | --------------------------------|----------|----------|----------|----------|----------------| 32 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 33 | --------------------------------|----------|----------|----------|----------|----------------| 34 | All files | 100 | 100 | 100 | 100 | | 35 | repo | 100 | 100 | 100 | 100 | | 36 | index.js | 100 | 100 | 100 | 100 | | 37 | repo/lib | 100 | 100 | 100 | 100 | | 38 | check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | | 39 | commit-is-in-pr.js | 100 | 100 | 100 | 100 | | 40 | default-config.js | 100 | 100 | 100 | 100 | | 41 | generate-blob-link.js | 100 | 100 | 100 | 100 | | 42 | generate-body.js | 100 | 100 | 100 | 100 | | 43 | generate-label.js | 100 | 100 | 100 | 100 | | 44 | get-file-contents.js | 100 | 100 | 100 | 100 | | 45 | helpers.js | 100 | 100 | 100 | 100 | | 46 | merge-handler.js | 100 | 100 | 100 | 100 | | 47 | metadata.js | 100 | 100 | 100 | 100 | | 48 | open-issues.js | 100 | 100 | 100 | 100 | | 49 | organize-commits.js | 100 | 100 | 100 | 100 | | 50 | reopen-closed.js | 100 | 100 | 100 | 100 | | 51 | search-contents-for-titles.js | 100 | 100 | 100 | 100 | | 52 | --------------------------------|----------|----------|----------|----------|----------------| 53 | _____ _ 54 | / ____| | | 55 | | | ___ __| | ___ ___ _____ __ 56 | | | / _ \\\\ / _\` |/ _ \\\\/ __/ _ \\\\ \\\\ / / 57 | | |___| (_) | (_| | __/ (_| (_) \\\\ V / 58 | \\\\_____\\\\___/ \\\\__,_|\\\\___|\\\\___\\\\___/ \\\\_/ 59 | v2.3.0 60 | ==> Detecting CI Provider 61 | Circle CI Detected 62 | ==> Configuration: 63 | Endpoint: https://codecov.io 64 | { service: 'circleci', 65 | build: '4.0', 66 | job: '4.0', 67 | commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa', 68 | branch: 'cleanup', 69 | pr: undefined, 70 | slug: 'JasonEtco/todo', 71 | package: 'node-v2.3.0' } 72 | ==> Building file structure 73 | ==> Generating gcov reports (skip via --disable=gcov) 74 | $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} + 75 | ==> Scanning for reports 76 | + /home/circleci/repo/coverage/clover.xml 77 | + /home/circleci/repo/coverage/lcov.info 78 | ==> Uploading reports 79 | Success! 80 | View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa 81 | standard: Use JavaScript Standard Style (https://standardjs.com) 82 | standard: Run \`standard --fix\` to automatically fix some problems. 83 | /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found. 84 | " 85 | `; 86 | -------------------------------------------------------------------------------- /tests/fixtures/circle/commit.json: -------------------------------------------------------------------------------- 1 | { 2 | "compare" : "https://github.com/JasonEtco/todo/compare/36eeffbb45a7...f485a7dcc619", 3 | "previous_successful_build" : { 4 | "build_num" : 3, 5 | "status" : "success", 6 | "build_time_millis" : 25854 7 | }, 8 | "build_parameters" : null, 9 | "oss" : true, 10 | "all_commit_details_truncated" : false, 11 | "committer_date" : "2017-12-25T11:09:32-05:00", 12 | "steps" : [ { 13 | "name" : "npm test", 14 | "actions" : [ { 15 | "truncated" : false, 16 | "index" : 0, 17 | "parallel" : true, 18 | "failed" : null, 19 | "infrastructure_fail" : null, 20 | "name" : "npm test", 21 | "bash_command" : "#!/bin/bash -eo pipefail\nnpm test", 22 | "status" : "success", 23 | "timedout" : null, 24 | "continue" : null, 25 | "end_time" : "2017-12-25T16:10:07.280Z", 26 | "type" : "test", 27 | "allocation_id" : "5a4122a4c9e77c0001868fc8-0-build/76A07AA6", 28 | "output_url" : "https://circleci.com/fake-output-url", 29 | "start_time" : "2017-12-25T16:09:56.282Z", 30 | "background" : false, 31 | "exit_code" : 1, 32 | "insignificant" : false, 33 | "canceled" : null, 34 | "step" : 105, 35 | "run_time_millis" : 10998, 36 | "has_output" : true 37 | } ] 38 | } ], 39 | "body" : "", 40 | "usage_queued_at" : "2017-12-25T16:09:08.975Z", 41 | "fail_reason" : null, 42 | "retry_of" : null, 43 | "reponame" : "todo", 44 | "ssh_users" : [ ], 45 | "build_url" : "https://circleci.com/gh/JasonEtco/todo/5", 46 | "parallel" : 1, 47 | "failed" : false, 48 | "branch" : "cleanup", 49 | "username" : "JasonEtco", 50 | "author_date" : "2017-12-25T11:09:32-05:00", 51 | "why" : "github", 52 | "user" : { 53 | "is_user" : true, 54 | "login" : "JasonEtco", 55 | "avatar_url" : "https://avatars1.githubusercontent.com/u/10660468?v=4", 56 | "name" : "Jason Etcovitch", 57 | "vcs_type" : "github", 58 | "id" : 10660468 59 | }, 60 | "vcs_revision" : "f485a7dcc6193a33ef1090ef6b6bc5cc8dde75d2", 61 | "owners" : [ "JasonEtco" ], 62 | "vcs_tag" : null, 63 | "build_num" : 5, 64 | "infrastructure_fail" : false, 65 | "committer_email" : "jasonetco@gmail.com", 66 | "has_artifacts" : true, 67 | "previous" : { 68 | "build_num" : 4, 69 | "status" : "failed", 70 | "build_time_millis" : 23348 71 | }, 72 | "status" : "fixed", 73 | "committer_name" : "Jason Etcovitch", 74 | "retries" : null, 75 | "subject" : "Fix linter", 76 | "vcs_type" : "github", 77 | "timedout" : false, 78 | "dont_build" : null, 79 | "lifecycle" : "finished", 80 | "no_dependency_cache" : false, 81 | "stop_time" : "2017-12-25T16:10:07.286Z", 82 | "ssh_disabled" : true, 83 | "build_time_millis" : 25884, 84 | "picard" : { 85 | "build_agent" : { 86 | "image" : null, 87 | "properties" : { 88 | "executor" : "docker", 89 | "build_agent" : "0.0.4606-189b121" 90 | } 91 | }, 92 | "resource_class" : { 93 | "cpu" : 2.0, 94 | "ram" : 4096, 95 | "class" : "medium" 96 | }, 97 | "executor" : "docker" 98 | }, 99 | "circle_yml" : { 100 | "string" : "version: 2\njobs:\n build:\n docker:\n - image: circleci/node:8.9.1\n\n working_directory: ~/repo\n\n steps:\n - checkout\n\n # Download and cache dependencies\n - restore_cache:\n keys:\n - v1-dependencies-{{ checksum \"package.json\" }}\n - v1-dependencies-\n\n - run: npm install\n\n - save_cache:\n paths:\n - node_modules\n key: v1-dependencies-{{ checksum \"package.json\" }}\n\n - run: npm test\n" 101 | }, 102 | "messages" : [ ], 103 | "is_first_green_build" : false, 104 | "job_name" : null, 105 | "start_time" : "2017-12-25T16:09:41.402Z", 106 | "canceler" : null, 107 | "all_commit_details" : [ { 108 | "committer_date" : "2017-12-25T11:09:32-05:00", 109 | "body" : "", 110 | "branch" : "cleanup", 111 | "author_date" : "2017-12-25T11:09:32-05:00", 112 | "committer_email" : "jasonetco@gmail.com", 113 | "commit" : "f485a7dcc6193a33ef1090ef6b6bc5cc8dde75d2", 114 | "committer_login" : "JasonEtco", 115 | "committer_name" : "Jason Etcovitch", 116 | "subject" : "Fix linter", 117 | "commit_url" : "https://github.com/JasonEtco/todo/commit/f485a7dcc6193a33ef1090ef6b6bc5cc8dde75d2", 118 | "author_login" : "JasonEtco", 119 | "author_name" : "Jason Etcovitch", 120 | "author_email" : "jasonetco@gmail.com" 121 | } ], 122 | "platform" : "2.0", 123 | "outcome" : "success", 124 | "vcs_url" : "https://github.com/JasonEtco/todo", 125 | "author_name" : "Jason Etcovitch", 126 | "node" : null, 127 | "queued_at" : "2017-12-25T16:09:37.419Z", 128 | "canceled" : false, 129 | "author_email" : "jasonetco@gmail.com" 130 | } -------------------------------------------------------------------------------- /tests/fixtures/circle/build.json: -------------------------------------------------------------------------------- 1 | { 2 | "compare" : "https://github.com/JasonEtco/todo/compare/36eeffbb45a7...f485a7dcc619", 3 | "previous_successful_build" : { 4 | "build_num" : 3, 5 | "status" : "success", 6 | "build_time_millis" : 25854 7 | }, 8 | "build_parameters" : null, 9 | "oss" : true, 10 | "all_commit_details_truncated" : false, 11 | "committer_date" : "2017-12-25T11:09:32-05:00", 12 | "steps" : [ { 13 | "name" : "npm test", 14 | "actions" : [ { 15 | "truncated" : false, 16 | "index" : 0, 17 | "parallel" : true, 18 | "failed" : null, 19 | "infrastructure_fail" : null, 20 | "name" : "npm test", 21 | "bash_command" : "#!/bin/bash -eo pipefail\nnpm test", 22 | "status" : "success", 23 | "timedout" : null, 24 | "continue" : null, 25 | "end_time" : "2017-12-25T16:10:07.280Z", 26 | "type" : "test", 27 | "allocation_id" : "5a4122a4c9e77c0001868fc8-0-build/76A07AA6", 28 | "output_url" : "https://circleci.com/fake-output-url", 29 | "start_time" : "2017-12-25T16:09:56.282Z", 30 | "background" : false, 31 | "exit_code" : 1, 32 | "insignificant" : false, 33 | "canceled" : null, 34 | "step" : 105, 35 | "run_time_millis" : 10998, 36 | "has_output" : true 37 | } ] 38 | } ], 39 | "body" : "", 40 | "usage_queued_at" : "2017-12-25T16:09:08.975Z", 41 | "fail_reason" : null, 42 | "retry_of" : null, 43 | "reponame" : "todo", 44 | "ssh_users" : [ ], 45 | "build_url" : "https://circleci.com/gh/JasonEtco/todo/5", 46 | "parallel" : 1, 47 | "failed" : false, 48 | "branch" : "cleanup", 49 | "username" : "JasonEtco", 50 | "author_date" : "2017-12-25T11:09:32-05:00", 51 | "why" : "github", 52 | "user" : { 53 | "is_user" : true, 54 | "login" : "JasonEtco", 55 | "avatar_url" : "https://avatars1.githubusercontent.com/u/10660468?v=4", 56 | "name" : "Jason Etcovitch", 57 | "vcs_type" : "github", 58 | "id" : 10660468 59 | }, 60 | "vcs_revision" : "f485a7dcc6193a33ef1090ef6b6bc5cc8dde75d2", 61 | "owners" : [ "JasonEtco" ], 62 | "vcs_tag" : null, 63 | "pull_requests" : [ { 64 | "head_sha" : "f485a7dcc6193a33ef1090ef6b6bc5cc8dde75d2", 65 | "url" : "https://github.com/JasonEtco/todo/pull/1" 66 | } ], 67 | "build_num" : 5, 68 | "infrastructure_fail" : false, 69 | "committer_email" : "jasonetco@gmail.com", 70 | "has_artifacts" : true, 71 | "previous" : { 72 | "build_num" : 4, 73 | "status" : "failed", 74 | "build_time_millis" : 23348 75 | }, 76 | "status" : "fixed", 77 | "committer_name" : "Jason Etcovitch", 78 | "retries" : null, 79 | "subject" : "Fix linter", 80 | "vcs_type" : "github", 81 | "timedout" : false, 82 | "dont_build" : null, 83 | "lifecycle" : "finished", 84 | "no_dependency_cache" : false, 85 | "stop_time" : "2017-12-25T16:10:07.286Z", 86 | "ssh_disabled" : true, 87 | "build_time_millis" : 25884, 88 | "picard" : { 89 | "build_agent" : { 90 | "image" : null, 91 | "properties" : { 92 | "executor" : "docker", 93 | "build_agent" : "0.0.4606-189b121" 94 | } 95 | }, 96 | "resource_class" : { 97 | "cpu" : 2.0, 98 | "ram" : 4096, 99 | "class" : "medium" 100 | }, 101 | "executor" : "docker" 102 | }, 103 | "circle_yml" : { 104 | "string" : "version: 2\njobs:\n build:\n docker:\n - image: circleci/node:8.9.1\n\n working_directory: ~/repo\n\n steps:\n - checkout\n\n # Download and cache dependencies\n - restore_cache:\n keys:\n - v1-dependencies-{{ checksum \"package.json\" }}\n - v1-dependencies-\n\n - run: npm install\n\n - save_cache:\n paths:\n - node_modules\n key: v1-dependencies-{{ checksum \"package.json\" }}\n\n - run: npm test\n" 105 | }, 106 | "messages" : [ ], 107 | "is_first_green_build" : false, 108 | "job_name" : null, 109 | "start_time" : "2017-12-25T16:09:41.402Z", 110 | "canceler" : null, 111 | "all_commit_details" : [ { 112 | "committer_date" : "2017-12-25T11:09:32-05:00", 113 | "body" : "", 114 | "branch" : "cleanup", 115 | "author_date" : "2017-12-25T11:09:32-05:00", 116 | "committer_email" : "jasonetco@gmail.com", 117 | "commit" : "f485a7dcc6193a33ef1090ef6b6bc5cc8dde75d2", 118 | "committer_login" : "JasonEtco", 119 | "committer_name" : "Jason Etcovitch", 120 | "subject" : "Fix linter", 121 | "commit_url" : "https://github.com/JasonEtco/todo/commit/f485a7dcc6193a33ef1090ef6b6bc5cc8dde75d2", 122 | "author_login" : "JasonEtco", 123 | "author_name" : "Jason Etcovitch", 124 | "author_email" : "jasonetco@gmail.com" 125 | } ], 126 | "platform" : "2.0", 127 | "outcome" : "success", 128 | "vcs_url" : "https://github.com/JasonEtco/todo", 129 | "author_name" : "Jason Etcovitch", 130 | "node" : null, 131 | "queued_at" : "2017-12-25T16:09:37.419Z", 132 | "canceled" : false, 133 | "author_email" : "jasonetco@gmail.com" 134 | } -------------------------------------------------------------------------------- /tests/fixtures/circle/output.json: -------------------------------------------------------------------------------- 1 | [{"type":"out","message":"\r\n> todo@1.0.0 test /home/circleci/repo\r\n> jest && codecov && standard\r\n\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/lib/\u001B[22m\u001B[1mmetadata.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/lib/\u001B[22m\u001B[1mgenerate-blob-link.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/lib/\u001B[22m\u001B[1mreopen-closed.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/lib/\u001B[22m\u001B[1mcommit-is-in-pr.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/lib/\u001B[22m\u001B[1mgenerate-label.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/lib/\u001B[22m\u001B[1mgenerate-body.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/\u001B[22m\u001B[1mlanguages.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/\u001B[22m\u001B[1minstallation.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/\u001B[22m\u001B[1mpr-comments.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/\u001B[22m\u001B[1mmerge-handler.js\u001B[22m\r\n\u001B[0m\u001B[7m\u001B[1m\u001B[32m PASS \u001B[39m\u001B[22m\u001B[27m\u001B[0m \u001B[2m__tests__/\u001B[22m\u001B[1mopen-issues.js\u001B[22m\r\n\u001B[999D\u001B[K\r\n\u001B[1mTest Suites: \u001B[22m\u001B[1m\u001B[32m11 passed\u001B[39m\u001B[22m, 11 total\r\n\u001B[1mTests: \u001B[22m\u001B[1m\u001B[32m70 passed\u001B[39m\u001B[22m, 70 total\r\n\u001B[1mSnapshots: \u001B[22m0 total\r\n\u001B[1mTime:\u001B[22m 4.335s\r\n\u001B[2mRan all test suites\u001B[22m\u001B[2m.\u001B[22m\r\n--------------------------------|----------|----------|----------|----------|----------------|\r\nFile | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |\r\n--------------------------------|----------|----------|----------|----------|----------------|\r\nAll files | 100 | 100 | 100 | 100 | |\r\n repo | 100 | 100 | 100 | 100 | |\r\n index.js | 100 | 100 | 100 | 100 | |\r\n repo/lib | 100 | 100 | 100 | 100 | |\r\n check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | |\r\n commit-is-in-pr.js | 100 | 100 | 100 | 100 | |\r\n default-config.js | 100 | 100 | 100 | 100 | |\r\n generate-blob-link.js | 100 | 100 | 100 | 100 | |\r\n generate-body.js | 100 | 100 | 100 | 100 | |\r\n generate-label.js | 100 | 100 | 100 | 100 | |\r\n get-file-contents.js | 100 | 100 | 100 | 100 | |\r\n helpers.js | 100 | 100 | 100 | 100 | |\r\n merge-handler.js | 100 | 100 | 100 | 100 | |\r\n metadata.js | 100 | 100 | 100 | 100 | |\r\n open-issues.js | 100 | 100 | 100 | 100 | |\r\n organize-commits.js | 100 | 100 | 100 | 100 | |\r\n reopen-closed.js | 100 | 100 | 100 | 100 | |\r\n search-contents-for-titles.js | 100 | 100 | 100 | 100 | |\r\n--------------------------------|----------|----------|----------|----------|----------------|\r\n _____ _ \r\n / ____| | | \r\n| | ___ __| | ___ ___ _____ __ \r\n| | / _ \\ / _` |/ _ \\/ __/ _ \\ \\ / / \r\n| |___| (_) | (_| | __/ (_| (_) \\ V / \r\n \\_____\\___/ \\__,_|\\___|\\___\\___/ \\_/ \r\n v2.3.0\r\n==> Detecting CI Provider\r\n Circle CI Detected\r\n==> Configuration: \r\n Endpoint: https://codecov.io\r\n{ service: 'circleci',\r\n build: '4.0',\r\n job: '4.0',\r\n commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa',\r\n branch: 'cleanup',\r\n pr: undefined,\r\n slug: 'JasonEtco/todo',\r\n package: 'node-v2.3.0' }\r\n==> Building file structure\r\n==> Generating gcov reports (skip via --disable=gcov)\r\n $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} +\r\n==> Scanning for reports\r\n + /home/circleci/repo/coverage/clover.xml\r\n + /home/circleci/repo/coverage/lcov.info\r\n==> Uploading reports\r\n Success!\r\n View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa\r\nstandard: Use JavaScript Standard Style (https://standardjs.com)\r\nstandard: Run `standard --fix` to automatically fix some problems.\r\n /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found.\r\n\u001B[37;40mnpm\u001B[0m \u001B[0m\u001B[31;40mERR!\u001B[0m\u001B[35m\u001B[0m Test failed. See above for more details.\r\n\u001B[0m","time":"2017-12-25T16:08:48.235Z"},{"type":"err","message":"Exited with code 1","time":"2017-12-25T16:08:48.239Z"}] -------------------------------------------------------------------------------- /tests/fixtures/issues.getComments-two.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": [{ 3 | "id": 1, 4 | "user": { "login": "JasonEtco" } 5 | }, { 6 | "id": 2, 7 | "user": { "login": "pizza-bot[bot]" }, 8 | "body":"### The build is failing\n\n✨ Good work on this PR so far! ✨ Unfortunately, the [Circle CI build](https://circleci.com/gh/JasonEtco/todo/5?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link) is failing as of b04b9ce383a933ed1a0a7b3de9e1cd31770b380e. Here's the output:\n\n\n##### `npm test`\n\n```\n> todo@1.0.0 test /home/circleci/repo\r\n> jest && codecov && standard\r\n\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/lib/\u001b[22m\u001b[1mmetadata.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/lib/\u001b[22m\u001b[1mgenerate-blob-link.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/lib/\u001b[22m\u001b[1mreopen-closed.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/lib/\u001b[22m\u001b[1mcommit-is-in-pr.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/lib/\u001b[22m\u001b[1mgenerate-label.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/lib/\u001b[22m\u001b[1mgenerate-body.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/\u001b[22m\u001b[1mlanguages.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/\u001b[22m\u001b[1minstallation.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/\u001b[22m\u001b[1mpr-comments.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/\u001b[22m\u001b[1mmerge-handler.js\u001b[22m\r\n\u001b[0m\u001b[7m\u001b[1m\u001b[32m PASS \u001b[39m\u001b[22m\u001b[27m\u001b[0m \u001b[2m__tests__/\u001b[22m\u001b[1mopen-issues.js\u001b[22m\r\n\u001b[999D\u001b[K\r\n\u001b[1mTest Suites: \u001b[22m\u001b[1m\u001b[32m11 passed\u001b[39m\u001b[22m, 11 total\r\n\u001b[1mTests: \u001b[22m\u001b[1m\u001b[32m70 passed\u001b[39m\u001b[22m, 70 total\r\n\u001b[1mSnapshots: \u001b[22m0 total\r\n\u001b[1mTime:\u001b[22m 4.335s\r\n\u001b[2mRan all test suites\u001b[22m\u001b[2m.\u001b[22m\r\n--------------------------------|----------|----------|----------|----------|----------------|\r\nFile | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |\r\n--------------------------------|----------|----------|----------|----------|----------------|\r\nAll files | 100 | 100 | 100 | 100 | |\r\n repo | 100 | 100 | 100 | 100 | |\r\n index.js | 100 | 100 | 100 | 100 | |\r\n repo/lib | 100 | 100 | 100 | 100 | |\r\n check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | |\r\n commit-is-in-pr.js | 100 | 100 | 100 | 100 | |\r\n default-config.js | 100 | 100 | 100 | 100 | |\r\n generate-blob-link.js | 100 | 100 | 100 | 100 | |\r\n generate-body.js | 100 | 100 | 100 | 100 | |\r\n generate-label.js | 100 | 100 | 100 | 100 | |\r\n get-file-contents.js | 100 | 100 | 100 | 100 | |\r\n helpers.js | 100 | 100 | 100 | 100 | |\r\n merge-handler.js | 100 | 100 | 100 | 100 | |\r\n metadata.js | 100 | 100 | 100 | 100 | |\r\n open-issues.js | 100 | 100 | 100 | 100 | |\r\n organize-commits.js | 100 | 100 | 100 | 100 | |\r\n reopen-closed.js | 100 | 100 | 100 | 100 | |\r\n search-contents-for-titles.js | 100 | 100 | 100 | 100 | |\r\n--------------------------------|----------|----------|----------|----------|----------------|\r\n _____ _ \r\n / ____| | | \r\n| | ___ __| | ___ ___ _____ __ \r\n| | / _ \\ / _` |/ _ \\/ __/ _ \\ \\ / / \r\n| |___| (_) | (_| | __/ (_| (_) \\ V / \r\n \\_____\\___/ \\__,_|\\___|\\___\\___/ \\_/ \r\n v2.3.0\r\n==> Detecting CI Provider\r\n Circle CI Detected\r\n==> Configuration: \r\n Endpoint: https://codecov.io\r\n{ service: 'circleci',\r\n build: '4.0',\r\n job: '4.0',\r\n commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa',\r\n branch: 'cleanup',\r\n pr: undefined,\r\n slug: 'JasonEtco/todo',\r\n package: 'node-v2.3.0' }\r\n==> Building file structure\r\n==> Generating gcov reports (skip via --disable=gcov)\r\n $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} +\r\n==> Scanning for reports\r\n + /home/circleci/repo/coverage/clover.xml\r\n + /home/circleci/repo/coverage/lcov.info\r\n==> Uploading reports\r\n Success!\r\n View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa\r\nstandard: Use JavaScript Standard Style (https://standardjs.com)\r\nstandard: Run `standard --fix` to automatically fix some problems.\r\n /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found.\r\n```\n\n\nI'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project!\n\n---\n\n
\n Failed build for 8a14336\n\n \n ##### `npm test`\n \n ```\n > failing-repo@1.0.0 test /home/travis/build/JasonEtco/failing-repo\n > echo \"Error: no test specified\" && exit 1\n \n Error: no test specified\n ```\n \n\n
\n\n\n \n \n\n\n---\n\n###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter).\n\n" 9 | }] 10 | } -------------------------------------------------------------------------------- /tests/index.test.js: -------------------------------------------------------------------------------- 1 | const {createRobot} = require('probot') 2 | const nock = require('nock') 3 | const path = require('path') 4 | const fs = require('fs') 5 | const ciReporter = require('../src') 6 | 7 | const readFile = file => fs.readFileSync(path.join(__dirname, 'fixtures', file), 'utf8') 8 | const commentsGet = require('./fixtures/issues.getComments.json') 9 | const commentsGetTwo = require('./fixtures/issues.getComments-two.json') 10 | 11 | describe('ci-reporter', () => { 12 | let robot, github 13 | 14 | beforeEach(() => { 15 | robot = createRobot() 16 | github = { 17 | issues: { 18 | getComments: jest.fn(() => Promise.resolve({data: []})), 19 | createComment: jest.fn(), 20 | editComment: jest.fn() 21 | }, 22 | repos: { 23 | getContent: jest.fn(() => Promise.resolve({data: { content: '' }})) 24 | } 25 | } 26 | 27 | robot.auth = jest.fn(() => Promise.resolve(github)) 28 | ciReporter(robot) 29 | }) 30 | 31 | describe('Travis CI', () => { 32 | it('creates the correct comment', async () => { 33 | const log = readFile(path.join('travis', 'log.txt')) 34 | 35 | nock('https://api.travis-ci.org') 36 | .get('/build/123').reply(200, { 37 | pull_request_number: 1, 38 | jobs: [{ id: 1234, number: 1, state: 'failed' }] 39 | }) 40 | .get('/job/1234/log.txt').reply(200, log) 41 | 42 | const event = { 43 | event: 'status', 44 | payload: { 45 | sha: 'b04b9ce383a933ed1a0a7b3de9e1cd31770b380e', 46 | target_url: 'https://travis-ci.org/JasonEtco/public-test/builds/123?utm_source=github_status&utm_medium=notification', 47 | context: 'continuous-integration/travis-ci/pr', 48 | state: 'failure', 49 | repository: { 50 | name: 'public-test', 51 | owner: { login: 'JasonEtco' } 52 | }, 53 | installation: { id: 123 } 54 | } 55 | } 56 | 57 | await robot.receive(event) 58 | expect(github.issues.createComment).toHaveBeenCalledTimes(1) 59 | 60 | const args = github.issues.createComment.mock.calls[0] 61 | 62 | expect(args[0].body).toMatchSnapshot() 63 | expect(args[0].number).toBe(1) 64 | expect(args[0].owner).toBe('JasonEtco') 65 | expect(args[0].repo).toBe('public-test') 66 | }) 67 | }) 68 | 69 | describe('Circle CI', () => { 70 | let event, build, output, commit 71 | 72 | beforeEach(() => { 73 | event = { 74 | event: 'status', 75 | payload: { 76 | sha: 'b04b9ce383a933ed1a0a7b3de9e1cd31770b380e', 77 | target_url: 'https://circleci.com/gh/JasonEtco/todo/5?utm_campaign=vcs-integration-link&utm_medium=referral&utm_source=github-build-link', 78 | context: 'ci/circleci', 79 | state: 'failure', 80 | repository: { 81 | name: 'todo', 82 | owner: { login: 'JasonEtco' } 83 | }, 84 | installation: { id: 123 } 85 | } 86 | } 87 | 88 | build = readFile(path.join('circle', 'build.json')) 89 | output = readFile(path.join('circle', 'output.json')) 90 | commit = readFile(path.join('circle', 'commit.json')) 91 | }) 92 | 93 | it('creates the correct comment', async () => { 94 | nock('https://circleci.com') 95 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, build) 96 | .get('/fake-output-url').reply(200, output) 97 | 98 | await robot.receive(event) 99 | expect(github.issues.createComment).toHaveBeenCalledTimes(1) 100 | 101 | const args = github.issues.createComment.mock.calls[0] 102 | 103 | expect(args[0].body).toMatchSnapshot() 104 | expect(args[0].number).toBe(1) 105 | expect(args[0].owner).toBe('JasonEtco') 106 | expect(args[0].repo).toBe('todo') 107 | }) 108 | 109 | it('creates the correct comment with before/after disabled', async () => { 110 | nock('https://circleci.com') 111 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, build) 112 | .get('/fake-output-url').reply(200, output) 113 | 114 | github.repos.getContent.mockReturnValueOnce(Promise.resolve({ data: {content: Buffer.from('after: false\nbefore: false')} })) 115 | await robot.receive(event) 116 | expect(github.issues.createComment.mock.calls[0][0].body).toMatchSnapshot() 117 | }) 118 | 119 | it('creates the correct comment with custom before/after', async () => { 120 | nock('https://circleci.com') 121 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, build) 122 | .get('/fake-output-url').reply(200, output) 123 | 124 | github.repos.getContent.mockReturnValueOnce(Promise.resolve({ data: {content: Buffer.from('before: I come before!\nafter: And I come after!')} })) 125 | await robot.receive(event) 126 | expect(github.issues.createComment.mock.calls[0][0].body).toMatchSnapshot() 127 | }) 128 | 129 | it('does not create a comment if the status is not in a PR', async () => { 130 | nock('https://circleci.com') 131 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, commit) 132 | .get('/fake-output-url').reply(200, output) 133 | 134 | await robot.receive(event) 135 | expect(github.issues.createComment).not.toHaveBeenCalled() 136 | }) 137 | 138 | it('updates an existing comment', async () => { 139 | nock('https://circleci.com') 140 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, build) 141 | .get('/fake-output-url').reply(200, output) 142 | 143 | github.issues.getComments.mockReturnValueOnce(Promise.resolve(commentsGet)) 144 | await robot.receive(event) 145 | expect(github.issues.editComment.mock.calls[0][0]).toMatchSnapshot() 146 | }) 147 | 148 | it('updates an existing comment twice', async () => { 149 | nock('https://circleci.com') 150 | .get('/api/v1.1/project/github/JasonEtco/todo/5').times(2).reply(200, build) 151 | .get('/fake-output-url').times(2).reply(200, output) 152 | 153 | github.issues.getComments.mockReturnValueOnce(Promise.resolve(commentsGet)) 154 | await robot.receive(event) 155 | github.issues.getComments.mockReturnValueOnce(Promise.resolve(commentsGetTwo)) 156 | await robot.receive(event) 157 | expect(github.issues.editComment.mock.calls[1][0]).toMatchSnapshot() 158 | }) 159 | 160 | it('respect the updateComment config', async () => { 161 | nock('https://circleci.com') 162 | .get('/api/v1.1/project/github/JasonEtco/todo/5').reply(200, build) 163 | .get('/fake-output-url').reply(200, output) 164 | 165 | github.repos.getContent.mockReturnValueOnce(Promise.resolve({data: {content: Buffer.from('updateComment: false')}})) 166 | github.issues.getComments.mockReturnValueOnce(Promise.resolve(commentsGet)) 167 | await robot.receive(event) 168 | expect(github.issues.createComment).toHaveBeenCalled() 169 | expect(github.issues.editComment).not.toHaveBeenCalled() 170 | }) 171 | }) 172 | 173 | it('does nothing if the status context is not accounted for', async () => { 174 | const event = { 175 | event: 'status', 176 | payload: { 177 | context: 'i/do/not/exist', 178 | state: 'failure', 179 | installation: { id: 123 }, 180 | repository: { 181 | name: 'public-test', 182 | owner: { login: 'JasonEtco' } 183 | } 184 | } 185 | } 186 | 187 | await robot.receive(event) 188 | expect(github.issues.createComment).not.toHaveBeenCalled() 189 | }) 190 | 191 | it('does nothing on non-failed status', async () => { 192 | const event = { 193 | event: 'status', 194 | payload: { 195 | state: 'passed', 196 | installation: { id: 123 }, 197 | repository: { 198 | name: 'public-test', 199 | owner: { login: 'JasonEtco' } 200 | } 201 | } 202 | } 203 | 204 | await robot.receive(event) 205 | expect(github.issues.createComment).not.toHaveBeenCalled() 206 | }) 207 | }) 208 | -------------------------------------------------------------------------------- /tests/fixtures/travis/log.txt: -------------------------------------------------------------------------------- 1 | travis_fold:start:worker_info 2 | Worker information 3 | hostname: 826d7660-6f4f-4268-8124-404c90929cbe@1.i-00e3218-production-2-worker-org-ec2.travisci.net 4 | version: v3.4.0 https://github.com/travis-ci/worker/tree/ce0440bc30c289a49a9b0c21e4e1e6f7d7825101 5 | instance: 6dbdb2d travisci/ci-garnet:packer-1512502276-986baf0 (via amqp) 6 | startup: 565.115238ms 7 | travis_fold:end:worker_info 8 | mode of ‘/usr/local/clang-5.0.0/bin’ changed from 0777 (rwxrwxrwx) to 0775 (rwxrwxr-x) 9 | travis_fold:start:system_info 10 | Build system information 11 | Build language: node_js 12 | Build group: stable 13 | Build dist: trusty 14 | Build id: 340790660 15 | Job id: 340790661 16 | Runtime kernel version: 4.14.12-041412-generic 17 | travis-build version: 8d2b1ed85 18 | Build image provisioning date and time 19 | Tue Dec 5 20:11:19 UTC 2017 20 | Operating System Details 21 | Distributor ID: Ubuntu 22 | Description: Ubuntu 14.04.5 LTS 23 | Release: 14.04 24 | Codename: trusty 25 | Cookbooks Version 26 | 7c2c6a6 https://github.com/travis-ci/travis-cookbooks/tree/7c2c6a6 27 | git version 28 | git version 2.15.1 29 | bash version 30 | GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu) 31 | gcc version 32 | gcc (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4 33 | Copyright (C) 2013 Free Software Foundation, Inc. 34 | This is free software; see the source for copying conditions. There is NO 35 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 36 | 37 | docker version 38 | Client: 39 | Version: 17.09.0-ce 40 | API version: 1.32 41 | Go version: go1.8.3 42 | Git commit: afdb6d4 43 | Built: Tue Sep 26 22:39:28 2017 44 | OS/Arch: linux/amd64 45 | clang version 46 | clang version 5.0.0 (tags/RELEASE_500/final) 47 | Target: x86_64-unknown-linux-gnu 48 | Thread model: posix 49 | InstalledDir: /usr/local/clang-5.0.0/bin 50 | jq version 51 | jq-1.5 52 | bats version 53 | Bats 0.4.0 54 | shellcheck version 55 | 0.4.6 56 | shfmt version 57 | v2.0.0 58 | ccache version 59 | ccache version 3.1.9 60 | 61 | Copyright (C) 2002-2007 Andrew Tridgell 62 | Copyright (C) 2009-2011 Joel Rosdahl 63 | 64 | This program is free software; you can redistribute it and/or modify it under 65 | the terms of the GNU General Public License as published by the Free Software 66 | Foundation; either version 3 of the License, or (at your option) any later 67 | version. 68 | cmake version 69 | cmake version 3.9.2 70 | 71 | CMake suite maintained and supported by Kitware (kitware.com/cmake). 72 | heroku version 73 | heroku-cli/6.14.39-addc925 (linux-x64) node-v9.2.0 74 | imagemagick version 75 | Version: ImageMagick 6.7.7-10 2017-07-31 Q16 http://www.imagemagick.org 76 | md5deep version 77 | 4.2 78 | mercurial version 79 | Mercurial Distributed SCM (version 4.2.2) 80 | (see https://mercurial-scm.org for more information) 81 | 82 | Copyright (C) 2005-2017 Matt Mackall and others 83 | This is free software; see the source for copying conditions. There is NO 84 | warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 85 | mysql version 86 | mysql Ver 14.14 Distrib 5.6.33, for debian-linux-gnu (x86_64) using EditLine wrapper 87 | openssl version 88 | OpenSSL 1.0.1f 6 Jan 2014 89 | packer version 90 | Packer v1.0.2 91 | 92 | Your version of Packer is out of date! The latest version 93 | is 1.1.2. You can update by downloading from www.packer.io 94 | postgresql client version 95 | psql (PostgreSQL) 9.6.6 96 | ragel version 97 | Ragel State Machine Compiler version 6.8 Feb 2013 98 | Copyright (c) 2001-2009 by Adrian Thurston 99 | subversion version 100 | svn, version 1.8.8 (r1568071) 101 | compiled Aug 10 2017, 17:20:39 on x86_64-pc-linux-gnu 102 | 103 | Copyright (C) 2013 The Apache Software Foundation. 104 | This software consists of contributions made by many people; 105 | see the NOTICE file for more information. 106 | Subversion is open source software, see http://subversion.apache.org/ 107 | 108 | The following repository access (RA) modules are available: 109 | 110 | * ra_svn : Module for accessing a repository using the svn network protocol. 111 | - with Cyrus SASL authentication 112 | - handles 'svn' scheme 113 | * ra_local : Module for accessing a repository on local disk. 114 | - handles 'file' scheme 115 | * ra_serf : Module for accessing a repository via WebDAV protocol using serf. 116 | - using serf 1.3.3 117 | - handles 'http' scheme 118 | - handles 'https' scheme 119 | 120 | sudo version 121 | Sudo version 1.8.9p5 122 | Configure options: --prefix=/usr -v --with-all-insults --with-pam --with-fqdn --with-logging=syslog --with-logfac=authpriv --with-env-editor --with-editor=/usr/bin/editor --with-timeout=15 --with-password-timeout=0 --with-passprompt=[sudo] password for %p: --without-lecture --with-tty-tickets --disable-root-mailer --enable-admin-flag --with-sendmail=/usr/sbin/sendmail --with-timedir=/var/lib/sudo --mandir=/usr/share/man --libexecdir=/usr/lib/sudo --with-sssd --with-sssd-lib=/usr/lib/x86_64-linux-gnu --with-selinux 123 | Sudoers policy plugin version 1.8.9p5 124 | Sudoers file grammar version 43 125 | 126 | Sudoers path: /etc/sudoers 127 | Authentication methods: 'pam' 128 | Syslog facility if syslog is being used for logging: authpriv 129 | Syslog priority to use when user authenticates successfully: notice 130 | Syslog priority to use when user authenticates unsuccessfully: alert 131 | Send mail if the user is not in sudoers 132 | Use a separate timestamp for each user/tty combo 133 | Lecture user the first time they run sudo 134 | Root may run sudo 135 | Allow some information gathering to give useful error messages 136 | Require fully-qualified hostnames in the sudoers file 137 | Visudo will honor the EDITOR environment variable 138 | Set the LOGNAME and USER environment variables 139 | Length at which to wrap log file lines (0 for no wrap): 80 140 | Authentication timestamp timeout: 15.0 minutes 141 | Password prompt timeout: 0.0 minutes 142 | Number of tries to enter a password: 3 143 | Umask to use or 0777 to use user's: 022 144 | Path to mail program: /usr/sbin/sendmail 145 | Flags for mail program: -t 146 | Address to send mail to: root 147 | Subject line for mail messages: *** SECURITY information for %h *** 148 | Incorrect password message: Sorry, try again. 149 | Path to authentication timestamp dir: /var/lib/sudo 150 | Default password prompt: [sudo] password for %p: 151 | Default user to run commands as: root 152 | Value to override user's $PATH with: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin 153 | Path to the editor for use by visudo: /usr/bin/editor 154 | When to require a password for 'list' pseudocommand: any 155 | When to require a password for 'verify' pseudocommand: all 156 | File descriptors >= 3 will be closed before executing a command 157 | Environment variables to check for sanity: 158 | TZ 159 | TERM 160 | LINGUAS 161 | LC_* 162 | LANGUAGE 163 | LANG 164 | COLORTERM 165 | Environment variables to remove: 166 | RUBYOPT 167 | RUBYLIB 168 | PYTHONUSERBASE 169 | PYTHONINSPECT 170 | PYTHONPATH 171 | PYTHONHOME 172 | TMPPREFIX 173 | ZDOTDIR 174 | READNULLCMD 175 | NULLCMD 176 | FPATH 177 | PERL5DB 178 | PERL5OPT 179 | PERL5LIB 180 | PERLLIB 181 | PERLIO_DEBUG 182 | JAVA_TOOL_OPTIONS 183 | SHELLOPTS 184 | GLOBIGNORE 185 | PS4 186 | BASH_ENV 187 | ENV 188 | TERMCAP 189 | TERMPATH 190 | TERMINFO_DIRS 191 | TERMINFO 192 | _RLD* 193 | LD_* 194 | PATH_LOCALE 195 | NLSPATH 196 | HOSTALIASES 197 | RES_OPTIONS 198 | LOCALDOMAIN 199 | CDPATH 200 | IFS 201 | Environment variables to preserve: 202 | JAVA_HOME 203 | TRAVIS 204 | CI 205 | DEBIAN_FRONTEND 206 | XAUTHORIZATION 207 | XAUTHORITY 208 | PS2 209 | PS1 210 | PATH 211 | LS_COLORS 212 | KRB5CCNAME 213 | HOSTNAME 214 | HOME 215 | DISPLAY 216 | COLORS 217 | Locale to use while parsing sudoers: C 218 | Directory in which to store input/output logs: /var/log/sudo-io 219 | File in which to store the input/output log: %{seq} 220 | Add an entry to the utmp/utmpx file when allocating a pty 221 | PAM service name to use 222 | PAM service name to use for login shells 223 | Create a new PAM session for the command to run in 224 | Maximum I/O log sequence number: 0 225 | 226 | Local IP address and netmask pairs: 227 | 172.17.0.2/255.255.0.0 228 | 229 | Sudoers I/O plugin version 1.8.9p5 230 | gzip version 231 | gzip 1.6 232 | Copyright (C) 2007, 2010, 2011 Free Software Foundation, Inc. 233 | Copyright (C) 1993 Jean-loup Gailly. 234 | This is free software. You may redistribute copies of it under the terms of 235 | the GNU General Public License . 236 | There is NO WARRANTY, to the extent permitted by law. 237 | 238 | Written by Jean-loup Gailly. 239 | zip version 240 | Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license. 241 | This is Zip 3.0 (July 5th 2008), by Info-ZIP. 242 | Currently maintained by E. Gordon. Please send bug reports to 243 | the authors using the web page at www.info-zip.org; see README for details. 244 | 245 | Latest sources and executables are at ftp://ftp.info-zip.org/pub/infozip, 246 | as of above date; see http://www.info-zip.org/ for other sites. 247 | 248 | Compiled with gcc 4.8.2 for Unix (Linux ELF) on Oct 21 2013. 249 | 250 | Zip special compilation options: 251 | USE_EF_UT_TIME (store Universal Time) 252 | BZIP2_SUPPORT (bzip2 library version 1.0.6, 6-Sept-2010) 253 | bzip2 code and library copyright (c) Julian R Seward 254 | (See the bzip2 license for terms of use) 255 | SYMLINK_SUPPORT (symbolic links supported) 256 | LARGE_FILE_SUPPORT (can read and write large files on file system) 257 | ZIP64_SUPPORT (use Zip64 to store large files in archives) 258 | UNICODE_SUPPORT (store and read UTF-8 Unicode paths) 259 | STORE_UNIX_UIDs_GIDs (store UID/GID sizes/values using new extra field) 260 | UIDGID_NOT_16BIT (old Unix 16-bit UID/GID extra field not used) 261 | [encryption, version 2.91 of 05 Jan 2007] (modified for Zip 3) 262 | 263 | Encryption notice: 264 | The encryption code of this program is not copyrighted and is 265 | put in the public domain. It was originally written in Europe 266 | and, to the best of our knowledge, can be freely distributed 267 | in both source and object forms from any country, including 268 | the USA under License Exception TSU of the U.S. Export 269 | Administration Regulations (section 740.13(e)) of 6 June 2002. 270 | 271 | Zip environment options: 272 | ZIP: [none] 273 | ZIPOPT: [none] 274 | vim version 275 | VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Nov 24 2016 16:43:18) 276 | Included patches: 1-52 277 | Extra patches: 8.0.0056 278 | Modified by pkg-vim-maintainers@lists.alioth.debian.org 279 | Compiled by buildd@ 280 | Huge version without GUI. Features included (+) or not (-): 281 | +acl +farsi +mouse_netterm +syntax 282 | +arabic +file_in_path +mouse_sgr +tag_binary 283 | +autocmd +find_in_path -mouse_sysmouse +tag_old_static 284 | -balloon_eval +float +mouse_urxvt -tag_any_white 285 | -browse +folding +mouse_xterm -tcl 286 | ++builtin_terms -footer +multi_byte +terminfo 287 | +byte_offset +fork() +multi_lang +termresponse 288 | +cindent +gettext -mzscheme +textobjects 289 | -clientserver -hangul_input +netbeans_intg +title 290 | -clipboard +iconv +path_extra -toolbar 291 | +cmdline_compl +insert_expand -perl +user_commands 292 | +cmdline_hist +jumplist +persistent_undo +vertsplit 293 | +cmdline_info +keymap +postscript +virtualedit 294 | +comments +langmap +printer +visual 295 | +conceal +libcall +profile +visualextra 296 | +cryptv +linebreak +python +viminfo 297 | +cscope +lispindent -python3 +vreplace 298 | +cursorbind +listcmds +quickfix +wildignore 299 | +cursorshape +localmap +reltime +wildmenu 300 | +dialog_con -lua +rightleft +windows 301 | +diff +menu -ruby +writebackup 302 | +digraphs +mksession +scrollbind -X11 303 | -dnd +modify_fname +signs -xfontset 304 | -ebcdic +mouse +smartindent -xim 305 | +emacs_tags -mouseshape -sniff -xsmp 306 | +eval +mouse_dec +startuptime -xterm_clipboard 307 | +ex_extra +mouse_gpm +statusline -xterm_save 308 | +extra_search -mouse_jsbterm -sun_workshop -xpm 309 | system vimrc file: "$VIM/vimrc" 310 | user vimrc file: "$HOME/.vimrc" 311 | 2nd user vimrc file: "~/.vim/vimrc" 312 | user exrc file: "$HOME/.exrc" 313 | fall-back for $VIM: "/usr/share/vim" 314 | Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 315 | Linking: gcc -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,--as-needed -o vim -lm -ltinfo -lnsl -lselinux -lacl -lattr -lgpm -ldl -L/usr/lib/python2.7/config-x86_64-linux-gnu -lpython2.7 -lpthread -ldl -lutil -lm -Xlinker -export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions 316 | iptables version 317 | iptables v1.4.21 318 | curl version 319 | curl 7.35.0 (x86_64-pc-linux-gnu) libcurl/7.35.0 OpenSSL/1.0.1f zlib/1.2.8 libidn/1.28 librtmp/2.3 320 | wget version 321 | GNU Wget 1.15 built on linux-gnu. 322 | rsync version 323 | rsync version 3.1.0 protocol version 31 324 | gimme version 325 | v1.2.0 326 | nvm version 327 | 0.33.6 328 | perlbrew version 329 | /home/travis/perl5/perlbrew/bin/perlbrew - App::perlbrew/0.80 330 | phpenv version 331 | rbenv 1.1.1-25-g6aa70b6 332 | rvm version 333 | rvm 1.29.3 (latest) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io] 334 | default ruby version 335 | ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux] 336 | CouchDB version 337 | couchdb 1.6.1 338 | ElasticSearch version 339 | 5.5.0 340 | Installed Firefox version 341 | firefox 56.0.2 342 | MongoDB version 343 | MongoDB 3.4.10 344 | PhantomJS version 345 | 2.1.1 346 | Pre-installed PostgreSQL versions 347 | 9.2.24 348 | 9.3.20 349 | 9.4.15 350 | 9.5.10 351 | 9.6.6 352 | RabbitMQ Version 353 | 3.6.14 354 | Redis version 355 | redis-server 4.0.6 356 | riak version 357 | 2.2.3 358 | Pre-installed Go versions 359 | 1.7.4 360 | ant version 361 | Apache Ant(TM) version 1.9.3 compiled on April 8 2014 362 | mvn version 363 | Apache Maven 3.5.2 (138edd61fd100ec658bfa2d307c43b76940a5d7d; 2017-10-18T07:58:13Z) 364 | Maven home: /usr/local/maven-3.5.2 365 | Java version: 1.8.0_151, vendor: Oracle Corporation 366 | Java home: /usr/lib/jvm/java-8-oracle/jre 367 | Default locale: en_US, platform encoding: UTF-8 368 | OS name: "linux", version: "4.4.0-101-generic", arch: "amd64", family: "unix" 369 | gradle version 370 | 371 | ------------------------------------------------------------ 372 | Gradle 4.0.1 373 | ------------------------------------------------------------ 374 | 375 | Build time: 2017-07-07 14:02:41 UTC 376 | Revision: 38e5dc0f772daecca1d2681885d3d85414eb6826 377 | 378 | Groovy: 2.4.11 379 | Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015 380 | JVM: 1.8.0_151 (Oracle Corporation 25.151-b12) 381 | OS: Linux 4.4.0-101-generic amd64 382 | 383 | lein version 384 | Leiningen 2.8.1 on Java 1.8.0_151 Java HotSpot(TM) 64-Bit Server VM 385 | Pre-installed Node.js versions 386 | v4.8.6 387 | v6.12.0 388 | v6.12.1 389 | v8.9 390 | v8.9.1 391 | phpenv versions 392 | system 393 | 5.6 394 | * 5.6.32 (set by /home/travis/.phpenv/version) 395 | 7.0 396 | 7.0.25 397 | 7.1 398 | 7.1.11 399 | hhvm 400 | hhvm-stable 401 | composer --version 402 | Composer version 1.5.2 2017-09-11 16:59:25 403 | Pre-installed Ruby versions 404 | ruby-2.2.7 405 | ruby-2.3.4 406 | ruby-2.4.1 407 | travis_fold:end:system_info 408 |  409 | removed ‘/etc/apt/sources.list.d/basho_riak.list’ 410 | W: http://ppa.launchpad.net/couchdb/stable/ubuntu/dists/trusty/Release.gpg: Signature by key 15866BAFD9BCC4F3C1E0DFC7D69548E1C17EAB57 uses weak digest algorithm (SHA1) 411 | 127.0.0.1 localhost 412 | ::1 ip6-localhost ip6-loopback 413 | fe00::0 ip6-localnet 414 | ff00::0 ip6-mcastprefix 415 | ff02::1 ip6-allnodes 416 | ff02::2 ip6-allrouters 417 | 172.17.0.5 travis-job-jasonetco-public-test-340790661.travisci.net travis-job-jasonetco-public-test-340790661 418 | travis_fold:start:git.checkout 419 | travis_time:start:0c82a414 420 | $ git clone --depth=50 https://github.com/JasonEtco/public-test.git JasonEtco/public-test 421 | Cloning into 'JasonEtco/public-test'... 422 | remote: Counting objects: 13, done. 423 | remote: Total 13 (delta 1), reused 1 (delta 1), pack-reused 11 424 | Unpacking objects: 7% (1/13) 425 | Unpacking objects: 15% (2/13) 426 | Unpacking objects: 23% (3/13) 427 | Unpacking objects: 30% (4/13) 428 | Unpacking objects: 38% (5/13) 429 | Unpacking objects: 46% (6/13) 430 | Unpacking objects: 53% (7/13) 431 | Unpacking objects: 61% (8/13) 432 | Unpacking objects: 69% (9/13) 433 | Unpacking objects: 76% (10/13) 434 | Unpacking objects: 84% (11/13) 435 | Unpacking objects: 92% (12/13) 436 | Unpacking objects: 100% (13/13) 437 | Unpacking objects: 100% (13/13), done. 438 | 439 | travis_time:end:0c82a414:start=1518492704430562118,finish=1518492704756699178,duration=326137060 440 | $ cd JasonEtco/public-test 441 | travis_time:start:01a95b60 442 | $ git fetch origin +refs/pull/9/merge: 443 | remote: Counting objects: 4, done. 444 | remote: Compressing objects: 33% (1/3)  445 | remote: Compressing objects: 66% (2/3)  446 | remote: Compressing objects: 100% (3/3)  447 | remote: Compressing objects: 100% (3/3), done. 448 | remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 449 | Unpacking objects: 25% (1/4) 450 | Unpacking objects: 50% (2/4) 451 | Unpacking objects: 75% (3/4) 452 | Unpacking objects: 100% (4/4) 453 | Unpacking objects: 100% (4/4), done. 454 | From https://github.com/JasonEtco/public-test 455 | * branch refs/pull/9/merge -> FETCH_HEAD 456 | 457 | travis_time:end:01a95b60:start=1518492704765754291,finish=1518492705039204309,duration=273450018 458 | $ git checkout -qf FETCH_HEAD 459 | travis_fold:end:git.checkout 460 | $ export PATH=./node_modules/.bin:$PATH 461 | Updating nvm 462 | travis_fold:start:nvm.install 463 | travis_time:start:061447ba 464 | $ nvm install 8 465 | Downloading and installing node v8.9.4... 466 | Downloading https://nodejs.org/dist/v8.9.4/node-v8.9.4-linux-x64.tar.xz... 467 | Computing checksum with sha256sum 468 | Checksums matched! 469 | Now using node v8.9.4 (npm v5.6.0) 470 | 471 | travis_time:end:061447ba:start=1518492711772072918,finish=1518492715579782709,duration=3807709791 472 | travis_fold:end:nvm.install 473 | $ node --version 474 | v8.9.4 475 | $ npm --version 476 | 5.6.0 477 | $ nvm --version 478 | 0.33.8 479 | travis_fold:start:install.npm 480 | travis_time:start:07c54a8e 481 | $ npm install 482 | npm notice created a lockfile as package-lock.json. You should commit this file. 483 | npm WARN public-test@1.0.0 No description 484 |  485 | up to date in 0.578s 486 | 487 | travis_time:end:07c54a8e:start=1518492717292602576,finish=1518492718642818149,duration=1350215573 488 | travis_time:start:1b890d7a 489 | $ npm ls 490 | public-test@1.0.0 /home/travis/build/JasonEtco/public-test 491 | └── (empty) 492 | 493 | 494 | travis_time:end:1b890d7a:start=1518492719011894785,finish=1518492719881022876,duration=869128091 495 | travis_fold:end:install.npm 496 | travis_time:start:01da490e 497 | $ npm test 498 | 499 | > public-test@1.0.0 test /home/travis/build/JasonEtco/public-test 500 | > echo "Error: no test specified" && exit 1 501 | 502 | Error: no test specified 503 | npm ERR! Test failed. See above for more details. 504 |  505 | travis_time:end:01da490e:start=1518492719888410081,finish=1518492720356721160,duration=468311079 506 |  507 | The command "npm test" exited with 1. 508 | 509 | Done. Your build exited with 1. 510 | -------------------------------------------------------------------------------- /tests/__snapshots__/index.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`ci-reporter Circle CI creates the correct comment 1`] = ` 4 | "### The build is failing 5 | 6 | ✨ Good work on this PR so far! ✨ Unfortunately, the [Circle CI build](https://circleci.com/gh/JasonEtco/todo/5?utm_campaign&#x3D;vcs-integration-link&amp;utm_medium&#x3D;referral&amp;utm_source&#x3D;github-build-link) is failing as of b04b9ce383a933ed1a0a7b3de9e1cd31770b380e. Here's the output: 7 | 8 | 9 | ##### \`npm test\` 10 | 11 | \`\`\` 12 | > todo@1.0.0 test /home/circleci/repo 13 | > jest && codecov && standard 14 | 15 | PASS __tests__/lib/metadata.js 16 | PASS __tests__/lib/generate-blob-link.js 17 | PASS __tests__/lib/reopen-closed.js 18 | PASS __tests__/lib/commit-is-in-pr.js 19 | PASS __tests__/lib/generate-label.js 20 | PASS __tests__/lib/generate-body.js 21 | PASS __tests__/languages.js 22 | PASS __tests__/installation.js 23 | PASS __tests__/pr-comments.js 24 | PASS __tests__/merge-handler.js 25 | PASS __tests__/open-issues.js 26 | 27 | Test Suites: 11 passed, 11 total 28 | Tests: 70 passed, 70 total 29 | Snapshots: 0 total 30 | Time: 4.335s 31 | Ran all test suites. 32 | --------------------------------|----------|----------|----------|----------|----------------| 33 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 34 | --------------------------------|----------|----------|----------|----------|----------------| 35 | All files | 100 | 100 | 100 | 100 | | 36 | repo | 100 | 100 | 100 | 100 | | 37 | index.js | 100 | 100 | 100 | 100 | | 38 | repo/lib | 100 | 100 | 100 | 100 | | 39 | check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | | 40 | commit-is-in-pr.js | 100 | 100 | 100 | 100 | | 41 | default-config.js | 100 | 100 | 100 | 100 | | 42 | generate-blob-link.js | 100 | 100 | 100 | 100 | | 43 | generate-body.js | 100 | 100 | 100 | 100 | | 44 | generate-label.js | 100 | 100 | 100 | 100 | | 45 | get-file-contents.js | 100 | 100 | 100 | 100 | | 46 | helpers.js | 100 | 100 | 100 | 100 | | 47 | merge-handler.js | 100 | 100 | 100 | 100 | | 48 | metadata.js | 100 | 100 | 100 | 100 | | 49 | open-issues.js | 100 | 100 | 100 | 100 | | 50 | organize-commits.js | 100 | 100 | 100 | 100 | | 51 | reopen-closed.js | 100 | 100 | 100 | 100 | | 52 | search-contents-for-titles.js | 100 | 100 | 100 | 100 | | 53 | --------------------------------|----------|----------|----------|----------|----------------| 54 | _____ _ 55 | / ____| | | 56 | | | ___ __| | ___ ___ _____ __ 57 | | | / _ \\\\ / _\` |/ _ \\\\/ __/ _ \\\\ \\\\ / / 58 | | |___| (_) | (_| | __/ (_| (_) \\\\ V / 59 | \\\\_____\\\\___/ \\\\__,_|\\\\___|\\\\___\\\\___/ \\\\_/ 60 | v2.3.0 61 | ==> Detecting CI Provider 62 | Circle CI Detected 63 | ==> Configuration: 64 | Endpoint: https://codecov.io 65 | { service: 'circleci', 66 | build: '4.0', 67 | job: '4.0', 68 | commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa', 69 | branch: 'cleanup', 70 | pr: undefined, 71 | slug: 'JasonEtco/todo', 72 | package: 'node-v2.3.0' } 73 | ==> Building file structure 74 | ==> Generating gcov reports (skip via --disable=gcov) 75 | $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} + 76 | ==> Scanning for reports 77 | + /home/circleci/repo/coverage/clover.xml 78 | + /home/circleci/repo/coverage/lcov.info 79 | ==> Uploading reports 80 | Success! 81 | View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa 82 | standard: Use JavaScript Standard Style (https://standardjs.com) 83 | standard: Run \`standard --fix\` to automatically fix some problems. 84 | /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found. 85 | \`\`\` 86 | 87 | 88 | I'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project! 89 | 90 | 91 | 92 | 93 | 94 | 95 | --- 96 | 97 | ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter). 98 | 99 | " 100 | `; 101 | 102 | exports[`ci-reporter Circle CI creates the correct comment with before/after disabled 1`] = ` 103 | "### The build is failing 104 | 105 | ##### \`npm test\` 106 | 107 | \`\`\` 108 | > todo@1.0.0 test /home/circleci/repo 109 | > jest && codecov && standard 110 | 111 | PASS __tests__/lib/metadata.js 112 | PASS __tests__/lib/generate-blob-link.js 113 | PASS __tests__/lib/reopen-closed.js 114 | PASS __tests__/lib/commit-is-in-pr.js 115 | PASS __tests__/lib/generate-label.js 116 | PASS __tests__/lib/generate-body.js 117 | PASS __tests__/languages.js 118 | PASS __tests__/installation.js 119 | PASS __tests__/pr-comments.js 120 | PASS __tests__/merge-handler.js 121 | PASS __tests__/open-issues.js 122 | 123 | Test Suites: 11 passed, 11 total 124 | Tests: 70 passed, 70 total 125 | Snapshots: 0 total 126 | Time: 4.335s 127 | Ran all test suites. 128 | --------------------------------|----------|----------|----------|----------|----------------| 129 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 130 | --------------------------------|----------|----------|----------|----------|----------------| 131 | All files | 100 | 100 | 100 | 100 | | 132 | repo | 100 | 100 | 100 | 100 | | 133 | index.js | 100 | 100 | 100 | 100 | | 134 | repo/lib | 100 | 100 | 100 | 100 | | 135 | check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | | 136 | commit-is-in-pr.js | 100 | 100 | 100 | 100 | | 137 | default-config.js | 100 | 100 | 100 | 100 | | 138 | generate-blob-link.js | 100 | 100 | 100 | 100 | | 139 | generate-body.js | 100 | 100 | 100 | 100 | | 140 | generate-label.js | 100 | 100 | 100 | 100 | | 141 | get-file-contents.js | 100 | 100 | 100 | 100 | | 142 | helpers.js | 100 | 100 | 100 | 100 | | 143 | merge-handler.js | 100 | 100 | 100 | 100 | | 144 | metadata.js | 100 | 100 | 100 | 100 | | 145 | open-issues.js | 100 | 100 | 100 | 100 | | 146 | organize-commits.js | 100 | 100 | 100 | 100 | | 147 | reopen-closed.js | 100 | 100 | 100 | 100 | | 148 | search-contents-for-titles.js | 100 | 100 | 100 | 100 | | 149 | --------------------------------|----------|----------|----------|----------|----------------| 150 | _____ _ 151 | / ____| | | 152 | | | ___ __| | ___ ___ _____ __ 153 | | | / _ \\\\ / _\` |/ _ \\\\/ __/ _ \\\\ \\\\ / / 154 | | |___| (_) | (_| | __/ (_| (_) \\\\ V / 155 | \\\\_____\\\\___/ \\\\__,_|\\\\___|\\\\___\\\\___/ \\\\_/ 156 | v2.3.0 157 | ==> Detecting CI Provider 158 | Circle CI Detected 159 | ==> Configuration: 160 | Endpoint: https://codecov.io 161 | { service: 'circleci', 162 | build: '4.0', 163 | job: '4.0', 164 | commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa', 165 | branch: 'cleanup', 166 | pr: undefined, 167 | slug: 'JasonEtco/todo', 168 | package: 'node-v2.3.0' } 169 | ==> Building file structure 170 | ==> Generating gcov reports (skip via --disable=gcov) 171 | $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} + 172 | ==> Scanning for reports 173 | + /home/circleci/repo/coverage/clover.xml 174 | + /home/circleci/repo/coverage/lcov.info 175 | ==> Uploading reports 176 | Success! 177 | View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa 178 | standard: Use JavaScript Standard Style (https://standardjs.com) 179 | standard: Run \`standard --fix\` to automatically fix some problems. 180 | /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found. 181 | \`\`\` 182 | 183 | 184 | 185 | 186 | 187 | 188 | --- 189 | 190 | ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter). 191 | 192 | " 193 | `; 194 | 195 | exports[`ci-reporter Circle CI creates the correct comment with custom before/after 1`] = ` 196 | "### The build is failing 197 | 198 | I come before! 199 | 200 | 201 | ##### \`npm test\` 202 | 203 | \`\`\` 204 | > todo@1.0.0 test /home/circleci/repo 205 | > jest && codecov && standard 206 | 207 | PASS __tests__/lib/metadata.js 208 | PASS __tests__/lib/generate-blob-link.js 209 | PASS __tests__/lib/reopen-closed.js 210 | PASS __tests__/lib/commit-is-in-pr.js 211 | PASS __tests__/lib/generate-label.js 212 | PASS __tests__/lib/generate-body.js 213 | PASS __tests__/languages.js 214 | PASS __tests__/installation.js 215 | PASS __tests__/pr-comments.js 216 | PASS __tests__/merge-handler.js 217 | PASS __tests__/open-issues.js 218 | 219 | Test Suites: 11 passed, 11 total 220 | Tests: 70 passed, 70 total 221 | Snapshots: 0 total 222 | Time: 4.335s 223 | Ran all test suites. 224 | --------------------------------|----------|----------|----------|----------|----------------| 225 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 226 | --------------------------------|----------|----------|----------|----------|----------------| 227 | All files | 100 | 100 | 100 | 100 | | 228 | repo | 100 | 100 | 100 | 100 | | 229 | index.js | 100 | 100 | 100 | 100 | | 230 | repo/lib | 100 | 100 | 100 | 100 | | 231 | check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | | 232 | commit-is-in-pr.js | 100 | 100 | 100 | 100 | | 233 | default-config.js | 100 | 100 | 100 | 100 | | 234 | generate-blob-link.js | 100 | 100 | 100 | 100 | | 235 | generate-body.js | 100 | 100 | 100 | 100 | | 236 | generate-label.js | 100 | 100 | 100 | 100 | | 237 | get-file-contents.js | 100 | 100 | 100 | 100 | | 238 | helpers.js | 100 | 100 | 100 | 100 | | 239 | merge-handler.js | 100 | 100 | 100 | 100 | | 240 | metadata.js | 100 | 100 | 100 | 100 | | 241 | open-issues.js | 100 | 100 | 100 | 100 | | 242 | organize-commits.js | 100 | 100 | 100 | 100 | | 243 | reopen-closed.js | 100 | 100 | 100 | 100 | | 244 | search-contents-for-titles.js | 100 | 100 | 100 | 100 | | 245 | --------------------------------|----------|----------|----------|----------|----------------| 246 | _____ _ 247 | / ____| | | 248 | | | ___ __| | ___ ___ _____ __ 249 | | | / _ \\\\ / _\` |/ _ \\\\/ __/ _ \\\\ \\\\ / / 250 | | |___| (_) | (_| | __/ (_| (_) \\\\ V / 251 | \\\\_____\\\\___/ \\\\__,_|\\\\___|\\\\___\\\\___/ \\\\_/ 252 | v2.3.0 253 | ==> Detecting CI Provider 254 | Circle CI Detected 255 | ==> Configuration: 256 | Endpoint: https://codecov.io 257 | { service: 'circleci', 258 | build: '4.0', 259 | job: '4.0', 260 | commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa', 261 | branch: 'cleanup', 262 | pr: undefined, 263 | slug: 'JasonEtco/todo', 264 | package: 'node-v2.3.0' } 265 | ==> Building file structure 266 | ==> Generating gcov reports (skip via --disable=gcov) 267 | $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} + 268 | ==> Scanning for reports 269 | + /home/circleci/repo/coverage/clover.xml 270 | + /home/circleci/repo/coverage/lcov.info 271 | ==> Uploading reports 272 | Success! 273 | View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa 274 | standard: Use JavaScript Standard Style (https://standardjs.com) 275 | standard: Run \`standard --fix\` to automatically fix some problems. 276 | /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found. 277 | \`\`\` 278 | 279 | 280 | And I come after! 281 | 282 | 283 | 284 | 285 | 286 | 287 | --- 288 | 289 | ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter). 290 | 291 | " 292 | `; 293 | 294 | exports[`ci-reporter Circle CI updates an existing comment 1`] = ` 295 | Object { 296 | "body": "### The build is failing 297 | 298 | ✨ Good work on this PR so far! ✨ Unfortunately, the [Circle CI build](https://circleci.com/gh/JasonEtco/todo/5?utm_campaign&#x3D;vcs-integration-link&amp;utm_medium&#x3D;referral&amp;utm_source&#x3D;github-build-link) is failing as of b04b9ce383a933ed1a0a7b3de9e1cd31770b380e. Here's the output: 299 | 300 | 301 | ##### \`npm test\` 302 | 303 | \`\`\` 304 | > todo@1.0.0 test /home/circleci/repo 305 | > jest && codecov && standard 306 | 307 | PASS __tests__/lib/metadata.js 308 | PASS __tests__/lib/generate-blob-link.js 309 | PASS __tests__/lib/reopen-closed.js 310 | PASS __tests__/lib/commit-is-in-pr.js 311 | PASS __tests__/lib/generate-label.js 312 | PASS __tests__/lib/generate-body.js 313 | PASS __tests__/languages.js 314 | PASS __tests__/installation.js 315 | PASS __tests__/pr-comments.js 316 | PASS __tests__/merge-handler.js 317 | PASS __tests__/open-issues.js 318 | 319 | Test Suites: 11 passed, 11 total 320 | Tests: 70 passed, 70 total 321 | Snapshots: 0 total 322 | Time: 4.335s 323 | Ran all test suites. 324 | --------------------------------|----------|----------|----------|----------|----------------| 325 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 326 | --------------------------------|----------|----------|----------|----------|----------------| 327 | All files | 100 | 100 | 100 | 100 | | 328 | repo | 100 | 100 | 100 | 100 | | 329 | index.js | 100 | 100 | 100 | 100 | | 330 | repo/lib | 100 | 100 | 100 | 100 | | 331 | check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | | 332 | commit-is-in-pr.js | 100 | 100 | 100 | 100 | | 333 | default-config.js | 100 | 100 | 100 | 100 | | 334 | generate-blob-link.js | 100 | 100 | 100 | 100 | | 335 | generate-body.js | 100 | 100 | 100 | 100 | | 336 | generate-label.js | 100 | 100 | 100 | 100 | | 337 | get-file-contents.js | 100 | 100 | 100 | 100 | | 338 | helpers.js | 100 | 100 | 100 | 100 | | 339 | merge-handler.js | 100 | 100 | 100 | 100 | | 340 | metadata.js | 100 | 100 | 100 | 100 | | 341 | open-issues.js | 100 | 100 | 100 | 100 | | 342 | organize-commits.js | 100 | 100 | 100 | 100 | | 343 | reopen-closed.js | 100 | 100 | 100 | 100 | | 344 | search-contents-for-titles.js | 100 | 100 | 100 | 100 | | 345 | --------------------------------|----------|----------|----------|----------|----------------| 346 | _____ _ 347 | / ____| | | 348 | | | ___ __| | ___ ___ _____ __ 349 | | | / _ \\\\ / _\` |/ _ \\\\/ __/ _ \\\\ \\\\ / / 350 | | |___| (_) | (_| | __/ (_| (_) \\\\ V / 351 | \\\\_____\\\\___/ \\\\__,_|\\\\___|\\\\___\\\\___/ \\\\_/ 352 | v2.3.0 353 | ==> Detecting CI Provider 354 | Circle CI Detected 355 | ==> Configuration: 356 | Endpoint: https://codecov.io 357 | { service: 'circleci', 358 | build: '4.0', 359 | job: '4.0', 360 | commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa', 361 | branch: 'cleanup', 362 | pr: undefined, 363 | slug: 'JasonEtco/todo', 364 | package: 'node-v2.3.0' } 365 | ==> Building file structure 366 | ==> Generating gcov reports (skip via --disable=gcov) 367 | $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} + 368 | ==> Scanning for reports 369 | + /home/circleci/repo/coverage/clover.xml 370 | + /home/circleci/repo/coverage/lcov.info 371 | ==> Uploading reports 372 | Success! 373 | View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa 374 | standard: Use JavaScript Standard Style (https://standardjs.com) 375 | standard: Run \`standard --fix\` to automatically fix some problems. 376 | /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found. 377 | \`\`\` 378 | 379 | 380 | I'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project! 381 | 382 | --- 383 | 384 |
385 | Failed build for 8a14336 386 | 387 | 388 | ##### \`npm test\` 389 | 390 | \`\`\` 391 | > failing-repo@1.0.0 test /home/travis/build/JasonEtco/failing-repo 392 | > echo \\"Error: no test specified\\" && exit 1 393 | 394 | Error: no test specified 395 | \`\`\` 396 | 397 | 398 |
399 | 400 | 401 | 402 | 403 | 404 | 405 | --- 406 | 407 | ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter). 408 | 409 | ", 410 | "id": 2, 411 | "number": 1, 412 | "owner": "JasonEtco", 413 | "repo": "todo", 414 | } 415 | `; 416 | 417 | exports[`ci-reporter Circle CI updates an existing comment twice 1`] = ` 418 | Object { 419 | "body": "### The build is failing 420 | 421 | ✨ Good work on this PR so far! ✨ Unfortunately, the [Circle CI build](https://circleci.com/gh/JasonEtco/todo/5?utm_campaign&#x3D;vcs-integration-link&amp;utm_medium&#x3D;referral&amp;utm_source&#x3D;github-build-link) is failing as of b04b9ce383a933ed1a0a7b3de9e1cd31770b380e. Here's the output: 422 | 423 | 424 | ##### \`npm test\` 425 | 426 | \`\`\` 427 | > todo@1.0.0 test /home/circleci/repo 428 | > jest && codecov && standard 429 | 430 | PASS __tests__/lib/metadata.js 431 | PASS __tests__/lib/generate-blob-link.js 432 | PASS __tests__/lib/reopen-closed.js 433 | PASS __tests__/lib/commit-is-in-pr.js 434 | PASS __tests__/lib/generate-label.js 435 | PASS __tests__/lib/generate-body.js 436 | PASS __tests__/languages.js 437 | PASS __tests__/installation.js 438 | PASS __tests__/pr-comments.js 439 | PASS __tests__/merge-handler.js 440 | PASS __tests__/open-issues.js 441 | 442 | Test Suites: 11 passed, 11 total 443 | Tests: 70 passed, 70 total 444 | Snapshots: 0 total 445 | Time: 4.335s 446 | Ran all test suites. 447 | --------------------------------|----------|----------|----------|----------|----------------| 448 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 449 | --------------------------------|----------|----------|----------|----------|----------------| 450 | All files | 100 | 100 | 100 | 100 | | 451 | repo | 100 | 100 | 100 | 100 | | 452 | index.js | 100 | 100 | 100 | 100 | | 453 | repo/lib | 100 | 100 | 100 | 100 | | 454 | check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | | 455 | commit-is-in-pr.js | 100 | 100 | 100 | 100 | | 456 | default-config.js | 100 | 100 | 100 | 100 | | 457 | generate-blob-link.js | 100 | 100 | 100 | 100 | | 458 | generate-body.js | 100 | 100 | 100 | 100 | | 459 | generate-label.js | 100 | 100 | 100 | 100 | | 460 | get-file-contents.js | 100 | 100 | 100 | 100 | | 461 | helpers.js | 100 | 100 | 100 | 100 | | 462 | merge-handler.js | 100 | 100 | 100 | 100 | | 463 | metadata.js | 100 | 100 | 100 | 100 | | 464 | open-issues.js | 100 | 100 | 100 | 100 | | 465 | organize-commits.js | 100 | 100 | 100 | 100 | | 466 | reopen-closed.js | 100 | 100 | 100 | 100 | | 467 | search-contents-for-titles.js | 100 | 100 | 100 | 100 | | 468 | --------------------------------|----------|----------|----------|----------|----------------| 469 | _____ _ 470 | / ____| | | 471 | | | ___ __| | ___ ___ _____ __ 472 | | | / _ \\\\ / _\` |/ _ \\\\/ __/ _ \\\\ \\\\ / / 473 | | |___| (_) | (_| | __/ (_| (_) \\\\ V / 474 | \\\\_____\\\\___/ \\\\__,_|\\\\___|\\\\___\\\\___/ \\\\_/ 475 | v2.3.0 476 | ==> Detecting CI Provider 477 | Circle CI Detected 478 | ==> Configuration: 479 | Endpoint: https://codecov.io 480 | { service: 'circleci', 481 | build: '4.0', 482 | job: '4.0', 483 | commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa', 484 | branch: 'cleanup', 485 | pr: undefined, 486 | slug: 'JasonEtco/todo', 487 | package: 'node-v2.3.0' } 488 | ==> Building file structure 489 | ==> Generating gcov reports (skip via --disable=gcov) 490 | $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} + 491 | ==> Scanning for reports 492 | + /home/circleci/repo/coverage/clover.xml 493 | + /home/circleci/repo/coverage/lcov.info 494 | ==> Uploading reports 495 | Success! 496 | View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa 497 | standard: Use JavaScript Standard Style (https://standardjs.com) 498 | standard: Run \`standard --fix\` to automatically fix some problems. 499 | /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found. 500 | \`\`\` 501 | 502 | 503 | I'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project! 504 | 505 | --- 506 | 507 |
508 | Failed build for b04b9ce 509 | 510 | 511 | ##### \`npm test\` 512 | 513 | \`\`\` 514 | > todo@1.0.0 test /home/circleci/repo 515 | > jest && codecov && standard 516 | 517 |  PASS  __tests__/lib/metadata.js 518 |  PASS  __tests__/lib/generate-blob-link.js 519 |  PASS  __tests__/lib/reopen-closed.js 520 |  PASS  __tests__/lib/commit-is-in-pr.js 521 |  PASS  __tests__/lib/generate-label.js 522 |  PASS  __tests__/lib/generate-body.js 523 |  PASS  __tests__/languages.js 524 |  PASS  __tests__/installation.js 525 |  PASS  __tests__/pr-comments.js 526 |  PASS  __tests__/merge-handler.js 527 |  PASS  __tests__/open-issues.js 528 |  529 | Test Suites: 11 passed, 11 total 530 | Tests: 70 passed, 70 total 531 | Snapshots: 0 total 532 | Time: 4.335s 533 | Ran all test suites. 534 | --------------------------------|----------|----------|----------|----------|----------------| 535 | File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | 536 | --------------------------------|----------|----------|----------|----------|----------------| 537 | All files | 100 | 100 | 100 | 100 | | 538 | repo | 100 | 100 | 100 | 100 | | 539 | index.js | 100 | 100 | 100 | 100 | | 540 | repo/lib | 100 | 100 | 100 | 100 | | 541 | check-for-duplicate-issue.js | 100 | 100 | 100 | 100 | | 542 | commit-is-in-pr.js | 100 | 100 | 100 | 100 | | 543 | default-config.js | 100 | 100 | 100 | 100 | | 544 | generate-blob-link.js | 100 | 100 | 100 | 100 | | 545 | generate-body.js | 100 | 100 | 100 | 100 | | 546 | generate-label.js | 100 | 100 | 100 | 100 | | 547 | get-file-contents.js | 100 | 100 | 100 | 100 | | 548 | helpers.js | 100 | 100 | 100 | 100 | | 549 | merge-handler.js | 100 | 100 | 100 | 100 | | 550 | metadata.js | 100 | 100 | 100 | 100 | | 551 | open-issues.js | 100 | 100 | 100 | 100 | | 552 | organize-commits.js | 100 | 100 | 100 | 100 | | 553 | reopen-closed.js | 100 | 100 | 100 | 100 | | 554 | search-contents-for-titles.js | 100 | 100 | 100 | 100 | | 555 | --------------------------------|----------|----------|----------|----------|----------------| 556 | _____ _ 557 | / ____| | | 558 | | | ___ __| | ___ ___ _____ __ 559 | | | / _ \\\\ / _\` |/ _ \\\\/ __/ _ \\\\ \\\\ / / 560 | | |___| (_) | (_| | __/ (_| (_) \\\\ V / 561 | \\\\_____\\\\___/ \\\\__,_|\\\\___|\\\\___\\\\___/ \\\\_/ 562 | v2.3.0 563 | ==> Detecting CI Provider 564 | Circle CI Detected 565 | ==> Configuration: 566 | Endpoint: https://codecov.io 567 | { service: 'circleci', 568 | build: '4.0', 569 | job: '4.0', 570 | commit: '36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa', 571 | branch: 'cleanup', 572 | pr: undefined, 573 | slug: 'JasonEtco/todo', 574 | package: 'node-v2.3.0' } 575 | ==> Building file structure 576 | ==> Generating gcov reports (skip via --disable=gcov) 577 | $ find /home/circleci/repo -type f -name '*.gcno' -exec gcov {} + 578 | ==> Scanning for reports 579 | + /home/circleci/repo/coverage/clover.xml 580 | + /home/circleci/repo/coverage/lcov.info 581 | ==> Uploading reports 582 | Success! 583 | View report at: https://codecov.io/github/JasonEtco/todo/commit/36eeffbb45a75f1ac2ef3c8b491b5a1d9b4afefa 584 | standard: Use JavaScript Standard Style (https://standardjs.com) 585 | standard: Run \`standard --fix\` to automatically fix some problems. 586 | /home/circleci/repo/lib/search-contents-for-titles.js:15:2: Newline required at end of file but not found. 587 | \`\`\` 588 | 589 | 590 |
591 | 592 | 593 |
594 | Failed build for 8a14336 595 | 596 | 597 | ##### \`npm test\` 598 | 599 | \`\`\` 600 | > failing-repo@1.0.0 test /home/travis/build/JasonEtco/failing-repo 601 | > echo \\"Error: no test specified\\" && exit 1 602 | 603 | Error: no test specified 604 | \`\`\` 605 | 606 | 607 |
608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | --- 616 | 617 | ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter). 618 | 619 | ", 620 | "id": 2, 621 | "number": 1, 622 | "owner": "JasonEtco", 623 | "repo": "todo", 624 | } 625 | `; 626 | 627 | exports[`ci-reporter Travis CI creates the correct comment 1`] = ` 628 | "### The build is failing 629 | 630 | ✨ Good work on this PR so far! ✨ Unfortunately, the [Travis CI build](https://travis-ci.org/JasonEtco/public-test/builds/123?utm_source&#x3D;github_status&amp;utm_medium&#x3D;notification) is failing as of b04b9ce383a933ed1a0a7b3de9e1cd31770b380e. Here's the output: 631 | 632 | 633 | ##### \`npm test\` 634 | 635 | \`\`\` 636 | > public-test@1.0.0 test /home/travis/build/JasonEtco/public-test 637 | > echo \\"Error: no test specified\\" && exit 1 638 | 639 | Error: no test specified 640 | \`\`\` 641 | 642 | 643 | I'm sure you can fix it! If you need help, don't hesitate to ask a maintainer of the project! 644 | 645 | 646 | 647 | 648 | 649 | 650 | --- 651 | 652 | ###### This comment was automagically generated by [ci-reporter](https://github.com/apps/ci-reporter). If you see a problem, open [an issue here](https://github.com/jasonetco/ci-reporter). 653 | 654 | " 655 | `; 656 | --------------------------------------------------------------------------------