diff-coverage-comment #184
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: diff-coverage-comment | |
| on: | |
| workflow_run: # zizmor: ignore[dangerous-triggers] runs from the base repo on ci completion; checks out the trusted base branch, never the PR head, and never executes PR code | |
| workflows: ["ci"] | |
| types: [completed] | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| actions: read | |
| # one comment per PR head; a newer ci run supersedes an in-flight comment. | |
| concurrency: | |
| group: diff-coverage-comment-${{ github.event.workflow_run.head_sha }} | |
| cancel-in-progress: true | |
| jobs: | |
| comment: | |
| if: github.event.workflow_run.event == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| # workflow_run.pull_requests is empty for fork PRs -- resolve via the | |
| # commit->pulls endpoint, the same way ci-label does. | |
| - name: resolve the PR | |
| id: pr | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| REPO: ${{ github.repository }} | |
| HEAD_SHA: ${{ github.event.workflow_run.head_sha }} | |
| run: | | |
| pr=$(gh api "repos/$REPO/commits/$HEAD_SHA/pulls" --jq '.[0].number' 2>/dev/null || true) | |
| base=$(gh api "repos/$REPO/commits/$HEAD_SHA/pulls" --jq '.[0].base.ref' 2>/dev/null || true) | |
| if [ -z "$pr" ] || [ "$pr" = "null" ]; then | |
| echo "no open PR for $HEAD_SHA" | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| # the base ref feeds actions/checkout. it can only name a branch that | |
| # already exists here, but validate the shape anyway rather than | |
| # trusting an api string in a `ref:` -- fail closed to the integration | |
| # branch if it looks like anything other than a plain branch name. | |
| case "$base" in | |
| ''|*' '*|*'..'*|-*) base='test' ;; | |
| esac | |
| if ! printf '%s' "$base" | grep -qE '^[A-Za-z0-9._/-]{1,100}$'; then | |
| base='test' | |
| fi | |
| { | |
| echo "found=true" | |
| echo "number=$pr" | |
| echo "base=$base" | |
| } >> "$GITHUB_OUTPUT" | |
| # the diff-coverage job is `needs: test`, so a run that failed at lint or | |
| # type-check produces no artifact. that is not a coverage verdict, so stay | |
| # silent rather than posting a misleading comment. | |
| - name: fetch the diff-coverage report | |
| id: report | |
| if: steps.pr.outputs.found == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| REPO: ${{ github.repository }} | |
| RUN_ID: ${{ github.event.workflow_run.id }} | |
| run: | | |
| id=$(gh api "repos/$REPO/actions/runs/$RUN_ID/artifacts" \ | |
| --jq '.artifacts[] | select(.name=="diff-coverage") | .id' 2>/dev/null | head -1 || true) | |
| if [ -z "$id" ]; then | |
| echo "no diff-coverage artifact on run $RUN_ID" | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| gh api "repos/$REPO/actions/artifacts/$id/zip" > dc.zip | |
| unzip -o -q dc.zip | |
| if [ ! -f diff-coverage.json ]; then | |
| echo "artifact carried no json report" | |
| echo "found=false" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "found=true" >> "$GITHUB_OUTPUT" | |
| # the base branch is a branch in this repo, so its code is trusted; the PR | |
| # head is never checked out. this is what renders the comment body. | |
| - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| if: steps.report.outputs.found == 'true' | |
| with: | |
| ref: ${{ steps.pr.outputs.base }} | |
| persist-credentials: false | |
| path: base | |
| - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 | |
| if: steps.report.outputs.found == 'true' | |
| with: | |
| python-version: "3.12" | |
| # rendered by the tested renderer in vouch.pr_bot, not by yaml. file paths | |
| # in the report come from the PR's own diff, so the body is written to a | |
| # file and posted with --body-file: never interpolated into a shell word. | |
| - name: render the comment | |
| if: steps.report.outputs.found == 'true' | |
| run: | | |
| PYTHONPATH=base/src python -m vouch.pr_bot diff-coverage-comment \ | |
| --report-file diff-coverage.json > comment.md | |
| cat comment.md >> "$GITHUB_STEP_SUMMARY" | |
| - name: upsert the comment | |
| if: steps.report.outputs.found == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| REPO: ${{ github.repository }} | |
| PR: ${{ steps.pr.outputs.number }} | |
| run: | | |
| marker='<!-- vouch-bot: diff-coverage -->' | |
| existing=$(gh api "repos/$REPO/issues/$PR/comments" --paginate \ | |
| --jq "map(select(.body | startswith(\"$marker\"))) | .[0].id" 2>/dev/null || true) | |
| if [ -n "$existing" ] && [ "$existing" != "null" ]; then | |
| gh api --method PATCH "repos/$REPO/issues/comments/$existing" \ | |
| -F body=@comment.md >/dev/null | |
| echo "updated comment $existing on #$PR" | |
| else | |
| gh pr comment "$PR" --repo "$REPO" --body-file comment.md | |
| echo "created a comment on #$PR" | |
| fi |