From 07c5332d1d5ad64a0388b98a31f44aa4befcceed Mon Sep 17 00:00:00 2001
From: Kilian Ciuffolo <385716+kilianc@users.noreply.github.com>
Date: Tue, 14 May 2024 16:15:55 -0700
Subject: [PATCH] feat: add ability to set a min threshold for coverage (#32)
---
.github/workflows/ci.yaml | 2 ++
README.md | 4 ++++
action.yaml | 16 ++++++++++++++-
src/check-threshold.js | 15 ++++++++++++++
src/update-comment.js | 41 +++++++++++++++++++++++++++------------
5 files changed, 65 insertions(+), 13 deletions(-)
create mode 100644 src/check-threshold.js
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 735ee33..acce089 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -27,9 +27,11 @@ jobs:
make test
- name: Go Beautiful HTML Coverage
+ if: always()
uses: './'
with:
path: go-test-app-01/
+ threshold: 66.7
- name: Go Beautiful HTML Coverage
uses: './'
diff --git a/README.md b/README.md
index 99b39dc..3e6620c 100644
--- a/README.md
+++ b/README.md
@@ -86,6 +86,10 @@ Once your test has ran and `cover.out` has been generated, the GHA does the foll
# The relative path of your go project. Useful for monorepos and custom folder structures.
# Default: ./
path: ''
+
+ # The minimum % of coverage required.
+ # Default: 0
+ threshold: ''
```
## Examples
diff --git a/action.yaml b/action.yaml
index 89e3cb8..d3c95d0 100644
--- a/action.yaml
+++ b/action.yaml
@@ -17,6 +17,9 @@ inputs:
path:
description: The relative path of your go project. Useful for monorepos and custom folder structures.
default: './'
+ threshold:
+ description: The minimum % of coverage required.
+ default: '0'
runs:
using: composite
steps:
@@ -69,4 +72,15 @@ runs:
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 }}'
- await script({ context, github }, path, revision)
+ const threshold = parseFloat('${{ inputs.threshold }}', 10)
+ await script({ context, github, path, revision, threshold })
+
+ - name: Check Coverage Threshold
+ uses: actions/github-script@v6
+ 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 })
diff --git a/src/check-threshold.js b/src/check-threshold.js
new file mode 100644
index 0000000..036165a
--- /dev/null
+++ b/src/check-threshold.js
@@ -0,0 +1,15 @@
+const fs = require('fs')
+
+const checkThreshold = module.exports = async ({ threshold, revision }) => {
+ const coverageText = fs.readFileSync(`go-cover/${revision}.txt`, 'utf8').split('\n').slice(0, -1)
+ const coverageTextSummary = coverageText[coverageText.length-1].split('\t').pop()
+
+ const coverage = parseFloat(coverageTextSummary.replace('%', ''), 10)
+
+ if (coverage < threshold) {
+ console.log(`\x1b[91m✘ coverage ${coverage}% < ${threshold}%`)
+ process.exit(1)
+ }
+
+ console.log(`\x1b[92m✔ coverage ${coverage}% >= ${threshold}%`)
+}
diff --git a/src/update-comment.js b/src/update-comment.js
index 85183ff..fd990ec 100644
--- a/src/update-comment.js
+++ b/src/update-comment.js
@@ -1,6 +1,6 @@
const fs = require('fs')
-const updateCodeCoverageComment = module.exports = async ({ context, github }, path, revision) => {
+const updateCodeCoverageComment = module.exports = async ({ context, github, path, revision, threshold }) => {
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
@@ -14,23 +14,40 @@ const updateCodeCoverageComment = module.exports = async ({ context, github }, p
const coverageText = fs.readFileSync(`go-cover/${revision}.txt`, 'utf8').split('\n').slice(0, -1)
const coverageTextSummary = coverageText[coverageText.length-1].split('\t').pop()
- const pathText = (path !== './' ? ` for \`${path}/\`` : '').replace('//', '/')
+ const coverage = parseFloat(coverageTextSummary.replace('%', ''), 10)
+ const coverageEmoji = coverage >= threshold ? '' : `🔻 ${(coverage - threshold).toFixed(1)}% `
+ const pathText = (path !== './' ? ` for ${path}/` : '').replace('//', '/')
const commentBody = [
``,
- `### [Code Coverage Report 🔗](https://${context.repo.owner}.github.io/${context.repo.repo}/?hash=${revision})${pathText} at ${revision}`,
+ `##### ${coverageEmoji}[🔗 Code Coverage Report](https://${context.repo.owner}.github.io/${context.repo.repo}/?hash=${revision})${pathText} at ${revision}`,
'```',
- `Total: ${coverageTextSummary}`,
- '```',
- '',
- 'Full coverage report
',
- '',
- '```',
- ...coverageText,
- '```',
- ' ',
+ `📔 Total: ${coverageTextSummary}`,
]
+ if (threshold > 0) {
+ commentBody.push(
+ `🎯 Threshold: ${threshold}%`,
+ )
+
+ if (coverage >= threshold) {
+ commentBody.push(`✅ ${coverageTextSummary} >= ${threshold}%`)
+ } else {
+ commentBody.push(`❌ ${coverageTextSummary} < ${threshold}%`)
+ }
+ }
+
+ commentBody.push(
+ '```',
+ '',
+ 'Full coverage report
',
+ '',
+ '```',
+ ...coverageText,
+ '```',
+ ' ',
+ )
+
const upsertCommentOptions = {
owner: context.repo.owner,
repo: context.repo.repo,