Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: output combined code coverage on github #30

Merged
merged 5 commits into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion bin/cc-merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ allFiles.forEach((filename, k) => {
})

const { getNycOptions } = require('../task-utils')
const { reportCodeCoverageGHA } = require('../src/utils')

const processWorkingDirectory = process.cwd()
const nycReportOptions = getNycOptions(processWorkingDirectory)
Expand All @@ -60,4 +61,9 @@ debug('current working directory is %s', processWorkingDirectory)
const NYC = require('nyc')
const nyc = new NYC(nycReportOptions)

nyc.report()
nyc.report().then(() => {
if (process.env.GITHUB_ACTIONS) {
debug('will report combined code coverage on GitHub Actions')
reportCodeCoverageGHA('Combined code coverage')
}
})
1 change: 1 addition & 0 deletions examples/merge-coverage/cypress/e2e/add.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
import { add } from '../../src/math'

it('adds two numbers', () => {
expect(add(1, 3)).to.equal(4)
expect(add(2, 3)).to.equal(5)
})
3 changes: 3 additions & 0 deletions examples/merge-coverage/src/math.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
*/
export const add = (a, b) => {
console.log('add %d to %d', a, b)
if (a === 2) {
console.log('a is 2')
}
return a + b
}

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"homepage": "https://github.com/bahmutov/cypress-code-coverage#readme",
"files": [
"*.js",
"src",
"middleware",
"bin"
],
Expand Down
80 changes: 3 additions & 77 deletions plugin.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,13 @@
// @ts-check
require('console.table')
const { getNycReportFilename } = require('./task-utils')
const { existsSync, readFileSync } = require('fs')
const { existsSync } = require('fs')
const NYC = require('nyc')
const debug = require('debug')('code-coverage')
const ghCore = require('@actions/core')
const path = require('path')
const { reportCodeCoverageGHACallback } = require('./src/utils')

const nycFilename = getNycReportFilename(process.cwd())

function pickCoverageEmoji(percentage) {
if (percentage >= 95) {
return '✅'
}
if (percentage >= 90) {
return '🏆'
}
if (percentage >= 80) {
return '🥇'
}
if (percentage >= 70) {
return '🥈'
}
if (percentage >= 60) {
return '🥉'
}
if (percentage >= 50) {
return '📈'
}
if (percentage >= 40) {
return '⚠️'
}
return '🪫'
}

function registerCodeCoveragePlugin(on, config) {
require('./task')(on, config)

Expand Down Expand Up @@ -76,55 +50,7 @@ function registerCodeCoveragePlugin(on, config) {

if (process.env.GITHUB_ACTIONS) {
debug('will report code coverage on GitHub Actions')
on('after:run', () => {
const summaryFilename = path.join('coverage', 'coverage-summary.json')
if (!existsSync(summaryFilename)) {
debug('cannot find summary file %s', summaryFilename)
} else {
const summary = JSON.parse(readFileSync(summaryFilename, 'utf8'))
if (summary.total) {
debug('code coverage summary totals %o', summary.total)
const s = summary.total.statements
const b = summary.total.branches
const f = summary.total.functions
const l = summary.total.lines
const row = [
String(s.pct),
`${s.covered}/${s.total}`,
String(b.pct),
`${b.covered}/${b.total}`,
String(f.pct),
`${f.covered}/${f.total}`,
String(l.pct),
`${l.covered}/${l.total}`,
]
debug(row)

ghCore.summary
.addHeading('Code coverage')
.addTable([
[
{ data: 'Statements %', header: true },
{ data: pickCoverageEmoji(s.pct), header: true },
{ data: 'Branches %', header: true },
{ data: pickCoverageEmoji(b.pct), header: true },
{ data: 'Functions %', header: true },
{ data: pickCoverageEmoji(f.pct), header: true },
{ data: 'Lines %', header: true },
{ data: pickCoverageEmoji(l.pct), header: true },
],
row,
])
.addLink(
'@bahmutov/cypress-code-coverage',
'https://github.com/bahmutov/cypress-code-coverage',
)
.write()
} else {
debug('could not find totals in %s', summaryFilename)
}
}
})
on('after:run', reportCodeCoverageGHACallback)
}
}

Expand Down
96 changes: 96 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// @ts-check

const debug = require('debug')('code-coverage')
const ghCore = require('@actions/core')
const path = require('path')
const { existsSync, readFileSync } = require('fs')

function pickCoverageEmoji(percentage) {
if (percentage >= 95) {
return '✅'
}
if (percentage >= 90) {
return '🏆'
}
if (percentage >= 80) {
return '🥇'
}
if (percentage >= 70) {
return '🥈'
}
if (percentage >= 60) {
return '🥉'
}
if (percentage >= 50) {
return '📈'
}
if (percentage >= 40) {
return '⚠️'
}
return '🪫'
}

function reportCodeCoverageGHA(heading = 'Code coverage') {
if (typeof heading !== 'string') {
debug(heading)
throw new Error('Expected a string heading when reporting CC on GHA')
}
const summaryFilename = path.join('coverage', 'coverage-summary.json')
if (!existsSync(summaryFilename)) {
debug('cannot find summary file %s', summaryFilename)
} else {
const summary = JSON.parse(readFileSync(summaryFilename, 'utf8'))
if (summary.total) {
debug('code coverage summary totals %o', summary.total)
const s = summary.total.statements
const b = summary.total.branches
const f = summary.total.functions
const l = summary.total.lines
const row = [
String(s.pct),
`${s.covered}/${s.total}`,
String(b.pct),
`${b.covered}/${b.total}`,
String(f.pct),
`${f.covered}/${f.total}`,
String(l.pct),
`${l.covered}/${l.total}`,
]
debug(row)

ghCore.summary
.addHeading(heading)
.addTable([
[
{ data: 'Statements %', header: true },
{ data: pickCoverageEmoji(s.pct), header: true },
{ data: 'Branches %', header: true },
{ data: pickCoverageEmoji(b.pct), header: true },
{ data: 'Functions %', header: true },
{ data: pickCoverageEmoji(f.pct), header: true },
{ data: 'Lines %', header: true },
{ data: pickCoverageEmoji(l.pct), header: true },
],
row,
])
.addLink(
'@bahmutov/cypress-code-coverage',
'https://github.com/bahmutov/cypress-code-coverage',
)
.write()
} else {
debug('could not find totals in %s', summaryFilename)
}
}
}

function reportCodeCoverageGHACallback() {
// we could use the test run summary passed in "after:run" event
return reportCodeCoverageGHA()
}

module.exports = {
pickCoverageEmoji,
reportCodeCoverageGHA,
reportCodeCoverageGHACallback,
}