Added commit signature verification with verified commit#305
Added commit signature verification with verified commit#305SpaceFace02 wants to merge 1 commit into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: SpaceFace02 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Reviewer's GuideAdds a reusable commit verification workflow to enforce signed commits and matching authorship on PRs, and wires it into existing Rust, Go, integration-test, and lint GitHub Actions workflows as a prerequisite job. Sequence diagram for commit signature and authorship verificationsequenceDiagram
participant Workflow as Commit_Verification_Workflow
participant Job as verify-commits_job
participant GHCLI as gh_cli
participant GitHubAPI as GitHub_API
Workflow->>Job: start
Job->>GHCLI: gh api repos/{repository}/pulls/{number}/commits
GHCLI->>GitHubAPI: GET /repos/{repository}/pulls/{number}/commits
GitHubAPI-->>GHCLI: commits list (verification, author)
GHCLI-->>Job: commits JSON
loop for each commit
alt commit.verification.verified != true
Job->>Job: print ::error::Commit is not signed
else author.login != PR_AUTHOR
Job->>Job: print ::error::Commit author does not match PR owner
end
end
alt errors found
Job->>Workflow: exit 1
else no errors
Job->>Workflow: echo All commits are signed and authored by PR owner
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- The reusable
commit-verification.ymlworkflow relies ongithub.event.pull_requestbut is also invoked viaworkflow_call, which means it will break for non-PR triggers (e.g., push/schedule); consider passing PR metadata as inputs or guarding the job withif: github.event_name == 'pull_request'and avoiding directgithub.event.pull_requestaccess in the reusable workflow. - By making all jobs
needs: verify-commits, any non-PR runs of these workflows (e.g., direct pushes to main) will also depend on commit verification even though the PR context may not exist; if you want verification only for PRs, add anif: github.event_name == 'pull_request'on theverify-commitsjob in the caller workflows or split PR vs non-PR workflows.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The reusable `commit-verification.yml` workflow relies on `github.event.pull_request` but is also invoked via `workflow_call`, which means it will break for non-PR triggers (e.g., push/schedule); consider passing PR metadata as inputs or guarding the job with `if: github.event_name == 'pull_request'` and avoiding direct `github.event.pull_request` access in the reusable workflow.
- By making all jobs `needs: verify-commits`, any non-PR runs of these workflows (e.g., direct pushes to main) will also depend on commit verification even though the PR context may not exist; if you want verification only for PRs, add an `if: github.event_name == 'pull_request'` on the `verify-commits` job in the caller workflows or split PR vs non-PR workflows.
## Individual Comments
### Comment 1
<location path=".github/workflows/commit-verification.yml" line_range="11-12" />
<code_context>
+ branches:
+ - "main"
+ workflow_call:
+permissions:
+ contents: "read"
+
+jobs:
</code_context>
<issue_to_address>
**issue (bug_risk):** The workflow permissions likely need `pull-requests: read` for the `gh api` call to succeed on PR endpoints.
Because `permissions` is explicitly set, all unspecified scopes default to `none`, so the token used by `gh api` may lack access to the PR endpoint and start returning 403s. Please add:
```yaml
permissions:
contents: read
pull-requests: read
```
to ensure this workflow can read PR commits reliably.
</issue_to_address>
### Comment 2
<location path=".github/workflows/commit-verification.yml" line_range="25-34" />
<code_context>
+ PR_AUTHOR: ${{ github.event.pull_request.user.login }}
+ run: |
+ set -euo pipefail
+ errors=$(gh api "repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/commits" \
+ -q '
+ .[] | .sha[:12] as $s |
+ (if .commit.verification.verified != true
+ then "::error::Commit \($s) is not signed (\(.commit.verification.reason))"
+ else empty end),
+ (if (.author.login // "") != env.PR_AUTHOR
+ then "::error::Commit \($s) author (\(.author.login // "unknown")) does not match PR owner (\(env.PR_AUTHOR))"
+ else empty end)
+ ')
+ if [ -n "${errors}" ]; then
+ echo "${errors}"
</code_context>
<issue_to_address>
**suggestion (bug_risk):** Consider failing fast on the `gh api` call itself to distinguish API errors from actual verification failures.
If the `gh api` call fails (network/permissions/invalid PR, etc.), `errors` stays empty and the job incorrectly reports success.
Add an explicit check on the `gh` exit status, e.g.:
```bash
if [ ${PIPESTATUS[0]} -ne 0 ]; then
echo "::error::Failed to query PR commits via GitHub API"
exit 1
fi
```
(or run the API call separately) so API/infrastructure failures cause the job to fail instead of silently passing verification.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
I gather you want the verification check to run before other tests, but is there a more unified way to order tests? (e.g. can we design this in a way that we won't forget the same gate when we add another test, or that we don't again need to edit 4 files if we want another test that goes before unit tests)
Then again, as long as GHA remains free for public repos, there isn't even a real incentive to do this itfp
There was a problem hiding this comment.
Yeah, might not be needed because we aren't the ones paying for the GHA minutes anyways, but generally a good idea to try to preserve compute if we can as a community courtesy.
As these workflows are seperate files, GH doesn't yet have a way for like a global pre-check. There seems to be a way with Branch Protection Rules, although I can't comment on that
There was a problem hiding this comment.
I'm kind of against this, not just because it makes the files fatter, but also because I saw now it runs per flow, so you get
- Commit Verification / Verify commit signatures and authorship
- Go / Build (pull_request)
- Go / verify-commits / Verify commit signatures and authorship (pull_request)
- Lint / Lints, pinned toolchain (pull_request)
- Lint / verify-commits / Verify commit signatures and authorship (pull_request)
etc.
e: so the "less compute time" argument is negated a bit anyhow
There was a problem hiding this comment.
Yeah, it does run for each flow, although its relatively lightweight than running the jobs without gating, I think removing it is fine for now.
I am also open to closing this issue as the repo owner can configure both options(verify signatures and prevent merging until pipeline succeeds) from the Branch Protection Rules, although it will run on merge, not on a PR.
63d655c to
723ed5a
Compare
|
Implemented by branch protection rules |
Have tested with unverified commit
Summary by Sourcery
Enforce commit signature and authorship verification in all CI workflows before running tests, builds, and linting.
CI: