Skip to content

Commit

Permalink
chore: add incremental coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
kilianc committed May 15, 2024
1 parent 1c8a384 commit fec52f4
Show file tree
Hide file tree
Showing 12 changed files with 138 additions and 28 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
with:
path: go-test-app-01/
threshold: 66.7
branch: cover-branch

- name: Go Beautiful HTML Coverage
uses: './'
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.vscode
cover.out
*.out
cover.txt
cover.html
10 changes: 6 additions & 4 deletions action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ runs:
shell: bash
run: |
export INPUTS_BRANCH="${{ inputs.branch }}"
export INPUTS_PATH="${{ inputs.path }}"
${GITHUB_ACTION_PATH}/scripts/pull.sh
- name: Push Coverage
Expand All @@ -47,23 +48,24 @@ runs:
- name: Post Code Coverage Comment
if: ${{ github.event_name == 'pull_request' }}
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
github-token: ${{ inputs.token }}
script: |
const script = require(`${process.env.GITHUB_ACTION_PATH}/src/update-comment.js`)
const revision = '${{ github.event.pull_request.head.sha || github.sha }}'
const path = '${{ inputs.path }}'
const threshold = parseFloat('${{ inputs.threshold }}', 10)
const path = '${{ inputs.path }}'
await script({ context, github, path, revision, threshold })
- name: Check Coverage Threshold
if: ${{ github.event_name == 'pull_request' }}
uses: actions/github-script@v6
uses: actions/github-script@v7
with:
github-token: ${{ inputs.token }}
script: |
const script = require(`${process.env.GITHUB_ACTION_PATH}/src/check-threshold.js`)
const revision = '${{ github.event.pull_request.head.sha || github.sha }}'
const threshold = parseFloat('${{ inputs.threshold }}', 10)
await script({ threshold, revision })
const path = '${{ inputs.path }}'
await script({ threshold, path, revision })
2 changes: 1 addition & 1 deletion assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
async function loadContent() {
const spinner = document.getElementById("spinner");
const hash = getHashFromQueryString();
const fileUrl = `${hash}.html`;
const fileUrl = `revisions/${hash}.html`;

spinner.style.display = "block";

Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion assets/nord.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

body {
background: var(--nord0) !important;
color: var(--nord4) !important;
color: var(--nord3) !important;
}

#topbar {
Expand Down
12 changes: 12 additions & 0 deletions go-test-app-01/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ import (
"math/rand"
)

const side = "right"

func main() {
if tossCoin() == "heads" {
fmt.Println("Heads")
} else {
fmt.Println("Tails")
}

fmt.Println("Maybe:", maybe())
}

func tossCoin() string {
Expand All @@ -20,3 +24,11 @@ func tossCoin() string {
return "tails"
}
}

func maybe() bool {
if side == "right" {
return true
} else {
return false
}
}
5 changes: 4 additions & 1 deletion scripts/pull.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

set -eo pipefail
set -xeo pipefail

cd go-cover
git fetch origin
Expand All @@ -13,4 +13,7 @@ else
git checkout --orphan "${INPUTS_BRANCH}"
rm .git/index
git clean -fdx
touch "${INPUTS_PATH}/head/head.html"
touch "${INPUTS_PATH}/head/head.txt"
touch "${INPUTS_PATH}/head/head.out"
fi
53 changes: 38 additions & 15 deletions scripts/push.sh
Original file line number Diff line number Diff line change
@@ -1,30 +1,53 @@
#!/bin/bash

set -eo pipefail
set -xeo pipefail

# create cover directory

cover_dir="${GITHUB_WORKSPACE}/go-cover/${INPUTS_PATH}"
mkdir -p "${cover_dir}/revisions"
mkdir -p "${cover_dir}/head"

# generate coverage files
cd "${INPUTS_PATH}"
go tool cover -html=cover.out -o "${GITHUB_WORKSPACE}/go-cover/${REVISION}.html"
go tool cover -func=cover.out -o "${GITHUB_WORKSPACE}/go-cover/${REVISION}.txt"
cp cover.out "${GITHUB_WORKSPACE}/go-cover/${REVISION}.out"

# if we are on the main branch, copy files to main.*
if [ "${REF_NAME}" = "main" ]; then
cp "${GITHUB_WORKSPACE}/go-cover/${REVISION}.html" "${GITHUB_WORKSPACE}/go-cover/main.html"
cp "${GITHUB_WORKSPACE}/go-cover/${REVISION}.txt" "${GITHUB_WORKSPACE}/go-cover/main.txt"
cp "${GITHUB_WORKSPACE}/go-cover/${REVISION}.out" "${GITHUB_WORKSPACE}/go-cover/main.out"
fi
# generate coverage files

go tool cover -html=cover.out -o "${cover_dir}/revisions/${REVISION}.html"
go tool cover -func=cover.out -o "${cover_dir}/revisions/${REVISION}.txt"
cp cover.out "${cover_dir}/revisions/${REVISION}.out"

# generate incremental coverage files

cd "${GITHUB_WORKSPACE}/go-cover"
echo "mode: set" > incremental.out
# grep exits with 1 if no lines are found, so we need to ignore that
grep -F -v -x -f "${GITHUB_WORKSPACE}/go-cover/head/head.out" cover.out >> incremental.out || true
go tool cover -html=incremental.out -o "${cover_dir}/revisions/${REVISION}-inc.html"
go tool cover -func=incremental.out -o "${cover_dir}/revisions/${REVISION}-inc.txt"
cp incremental.out "${cover_dir}/revisions/${REVISION}-inc.out"

cd "${cover_dir}"

# beautify html
ex -sc '%s/<style>/<style>@import url("nord.css");/' -c 'x' "${REVISION}.html"
ex -sc '%s/<\/script>/<\/script><script src="ln.js"><\/script>/' -c 'x' "${REVISION}.html"

for file in "revisions/${REVISION}.html" "revisions/${REVISION}-inc.html"; do
ex -sc '%s/<style>/<style>@import url("..\/nord.css");/' -c 'x' "${file}"
ex -sc '%s/<\/script>/<\/script><script src="..\/index.js"><\/script>/' -c 'x' "${file}"
done

# if we are on the main branch, copy files to main.*

if [ "${REF_NAME}" = "main" ]; then
cp "revisions/${REVISION}.html" "${cover_dir}/head/head.html"
cp "revisions/${REVISION}.txt" "${cover_dir}/head/head.txt"
cp "revisions/${REVISION}.out" "${cover_dir}/head/head.out"
fi

# copy assets
cp "${GITHUB_ACTION_PATH}"/assets/* .

cp "${GITHUB_ACTION_PATH}"/assets/* "${cover_dir}"

# push to branch

git add .
git config user.email "[email protected]"
git config user.name "go-coverage-action"
Expand Down
7 changes: 5 additions & 2 deletions src/check-threshold.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const fs = require('fs')
const normalizePath = require('./normalize-path')

const checkThreshold = module.exports = async ({ threshold, revision }) => {
const coverageText = fs.readFileSync(`go-cover/${revision}.txt`, 'utf8').split('\n').slice(0, -1)
const checkThreshold = module.exports = async ({ threshold, path, revision }) => {
path = normalizePath(path)

const coverageText = fs.readFileSync(`go-cover/${path}/revisions/${revision}.txt`, 'utf8').split('\n').slice(0, -1)
const coverageTextSummary = coverageText[coverageText.length-1].split('\t').pop()

const coverage = parseFloat(coverageTextSummary.replace('%', ''), 10)
Expand Down
62 changes: 62 additions & 0 deletions src/normalize-path.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const path = require('path')

const normalizePath = module.exports = (dir) => {
dir = path.normalize(dir)

if (dir === '/' || dir === './' || dir === '.') {
return ''
}

if (dir.startsWith('./')) {
dir = dir.substring(2)
}

if (dir.startsWith('/')) {
dir = dir.substring(1)
}

if (dir.endsWith('/')) {
dir = dir.substring(0, dir.length - 1)
}

return dir
}

const test = async () => {
let pass = true

const tests = [
{ input: '/', expected: '' },
{ input: '/foo', expected: 'foo' },

{ input: './', expected: '' },
{ input: './foo', expected: 'foo' },
{ input: './foo/', expected: 'foo' },
{ input: './foo/bar', expected: 'foo/bar' },
{ input: './foo/bar/', expected: 'foo/bar' },

{ input: '', expected: '' },
{ input: 'foo', expected: 'foo' },
{ input: 'foo/', expected: 'foo' },
{ input: 'foo/bar', expected: 'foo/bar' },
{ input: 'foo/bar/', expected: 'foo/bar' },
]

for (const { input, expected } of tests) {
const result = normalizePath(input)
if (result !== expected) {
console.error(`error("${input}"): expected "${expected}" but got "${result}"`)
pass = false
}
}

if (!pass) {
process.exit(1)
} else {
console.log('All tests passed')
}
}

if (require.main === module) {
test()
}
10 changes: 7 additions & 3 deletions src/update-comment.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const fs = require('fs')
const normalizePath = require('./normalize-path')

const updateCodeCoverageComment = module.exports = async ({ context, github, path, revision, threshold }) => {
const comments = await github.rest.issues.listComments({
Expand All @@ -12,15 +13,18 @@ const updateCodeCoverageComment = module.exports = async ({ context, github, pat
return comment.body.startsWith(`<!-- coverage (${path})-->`)
}) || {}

const coverageText = fs.readFileSync(`go-cover/${revision}.txt`, 'utf8').split('\n').slice(0, -1)
path = normalizePath(path)

const coverageText = fs.readFileSync(`go-cover/${path}/revisions/${revision}.txt`, 'utf8').split('\n').slice(0, -1)
const coverageTextSummary = coverageText[coverageText.length-1].split('\t').pop()
const coverage = parseFloat(coverageTextSummary.replace('%', ''), 10)
const coverageEmoji = coverage >= threshold ? '' : `<kbd>🔻 ${(coverage - threshold).toFixed(1)}%</kbd> `
const pathText = (path !== './' ? ` for <kbd>${path}/</kbd>` : '').replace('//', '/')
const pathText = (path !== '/' ? ` for <kbd>${path}/</kbd>` : '')
const url = `https://${context.repo.owner}.github.io/${context.repo.repo}/${path}/?hash=${revision}`

const commentBody = [
`<!-- coverage (${path})-->`,
`##### ${coverageEmoji}<kbd>[🔗 Code Coverage Report](https://${context.repo.owner}.github.io/${context.repo.repo}/?hash=${revision})</kbd>${pathText} at <kbd>${revision}</kbd>`,
`##### ${coverageEmoji}<kbd>[🔗 Code Coverage Report](${url})</kbd>${pathText} at <kbd>${revision}</kbd>`,
'```',
`📔 Total: ${coverageTextSummary}`,
]
Expand Down

0 comments on commit fec52f4

Please sign in to comment.