From c22dfcdef2c332985f179a11f582de3f40b2ed57 Mon Sep 17 00:00:00 2001 From: Pasquale Congiusti Date: Thu, 11 Jan 2024 12:54:00 +0100 Subject: [PATCH] feat(ci): new coverage flow As suggested in https://securitylab.github.com/research/github-actions-preventing-pwn-requests/ --- .github/actions/automatic-updates/action.yml | 3 +- .github/actions/e2e-build/action.yml | 16 ++++- .github/workflows/comment-pr.yaml | 67 ++++++++++++++++++++ .gitignore | 5 +- coverage | 1 + script/Makefile | 6 +- 6 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 .github/workflows/comment-pr.yaml create mode 100644 coverage diff --git a/.github/actions/automatic-updates/action.yml b/.github/actions/automatic-updates/action.yml index 21c8ea1d77..04da33940a 100644 --- a/.github/actions/automatic-updates/action.yml +++ b/.github/actions/automatic-updates/action.yml @@ -69,6 +69,7 @@ runs: run: | go test -v ./... -covermode=count -coverprofile=coverage.out go tool cover -func=coverage.out -o=coverage.out + grep -o -P '(?<=\(statements\))(.+)(?=%)' coverage.out | xargs > coverage touch badge.out - name: Go Coverage Badge uses: ./.github/actions/coverage-badge @@ -89,7 +90,7 @@ runs: run: | git config --local user.email "$CI_EMAIL" git config --local user.name "$CI_USER" - git add -A && git commit -m 'chore: nightly coverage badge update' && echo "badge=1" >> $GITHUB_ENV || echo "No changes to coverage badge" + git add -A -f && git commit -m 'chore: nightly coverage changed' && echo "badge=1" >> $GITHUB_ENV || echo "No changes to coverage" # Git push - name: Push changes diff --git a/.github/actions/e2e-build/action.yml b/.github/actions/e2e-build/action.yml index d3ac7dfeb1..a5a976ff56 100644 --- a/.github/actions/e2e-build/action.yml +++ b/.github/actions/e2e-build/action.yml @@ -29,4 +29,18 @@ runs: - name: Test shell: bash - run: make + run: | + COVERAGE_OPTS="-covermode=count -coverprofile=coverage.out" make build + + - name: Save coverage PR value + shell: bash + run: | + mkdir -p ./pr + go tool cover -func=coverage.out -o=coverage.out + grep -o -P '(?<=\(statements\))(.+)(?=%)' coverage.out | xargs > ./pr/coverage + echo ${{ github.event.number }} > ./pr/id + + - uses: actions/upload-artifact@v2 + with: + name: pr + path: pr/ \ No newline at end of file diff --git a/.github/workflows/comment-pr.yaml b/.github/workflows/comment-pr.yaml new file mode 100644 index 0000000000..22bc3f61b4 --- /dev/null +++ b/.github/workflows/comment-pr.yaml @@ -0,0 +1,67 @@ +name: Comment on the pull request + +env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + +on: + workflow_run: + workflows: ["build"] + types: + - completed + +jobs: + upload: + runs-on: ubuntu-latest + if: > + github.event.workflow_run.event == 'pull_request' && + github.event.workflow_run.conclusion == 'success' + steps: + - name: 'Download coverage artifact' + uses: actions/github-script@v3.1.0 + with: + script: | + var artifacts = await github.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: ${{github.event.workflow_run.id }}, + }); + var matchArtifact = artifacts.data.artifacts.filter((artifact) => { + return artifact.name == "pr" + })[0]; + var download = await github.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact.id, + archive_format: 'zip', + }); + var fs = require('fs'); + fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data)); + - run: unzip pr.zip + + - name: 'Comment on PR' + uses: actions/github-script@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + script: | + var fs = require('fs'); + const coverage = Number(fs.readFileSync('./coverage')); + const issue_number = Number(fs.readFileSync('./id')); + const main_coverage_result = await github.request('https://raw.githubusercontent.com/' + context.repo.owner + '/' + context.repo.repo + '/main/coverage') + const main_cov_num = Number(main_coverage_result.data) + diff = Math.round((coverage - main_cov_num + Number.EPSILON) * 100) / 100 + + if(diff > 0){ + await github.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue_number, + body: ':heavy_check_mark: Unit test coverage report - coverage increased from ' + main_cov_num + '% to ' + coverage + '% (**+' + diff + '%**)' + }) + }else if(diff < 0){ + await github.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue_number, + body: ':warning: Unit test coverage report - coverage decreased from ' + main_cov_num + '% to ' + coverage + '% (**' + diff + '%**)' + }) + } diff --git a/.gitignore b/.gitignore index 1e5a721683..6896b7685d 100644 --- a/.gitignore +++ b/.gitignore @@ -141,8 +141,9 @@ anaconda-mode/ # Test binary, build with 'go test -c' *.test -# Output of the go coverage tool, specifically when used with LiteIDE -*.out +# Output of the go coverage tool +coverage.out +coverage ### Vim ### # swap diff --git a/coverage b/coverage new file mode 100644 index 0000000000..d193c0ba80 --- /dev/null +++ b/coverage @@ -0,0 +1 @@ +34.2 diff --git a/script/Makefile b/script/Makefile index 24dff1e4fd..817a65d612 100644 --- a/script/Makefile +++ b/script/Makefile @@ -243,11 +243,7 @@ endif test: do-build @echo "####### Running unit test..." - go test ./... - -test-fmt: do-build - @echo "####### Running unit test..." - go test -v ./... -json 2>&1 | gotestfmt + go test ./... $(COVERAGE_OPTS) # # Common tests that do not require any customized operator setting. They can leverage a unique namespaced operator installation to reduce