Verified commit gate#91
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a reusable GitHub Actions workflow intended to gate pull requests based on whether all commits have verified cryptographic signatures, and to manage a persistent PR comment indicating which commits are not verified.
Changes:
- Introduces
.github/workflows/check-signature.yamlas aworkflow_callworkflow taking apr_numberinput. - Uses
actions/github-scriptto query commit signature verification status and create/update/delete a bot PR comment. - Fails the workflow run when unverified commits are detected.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const result = await github.graphql(query, variables); | ||
| const commits = result.repository.pullRequest.commits.nodes; | ||
|
|
| const comments = await github.rest.issues.listComments({ | ||
| owner: context.repo.owner, | ||
| repo: context.repo.repo, | ||
| issue_number: prNumber, | ||
| }); |
| // 4. Handle logic based on validation state | ||
| if (unsignedCommits.length > 0) { | ||
| const commitList = unsignedCommits.map(c => `- \`${c.commit.oid.substring(0, 7)}\``).join('\n'); | ||
| const commentBody = `${commentIdentifier}\n.⚠️ **Unsigned Commits Detected**\n\nThe following commits in this Pull Request are missing a verified cryptographic signature:\n\n${commitList}\n\nPlease sign your commits to comply with <a href="https://metoffice.github.io/simulation-systems/WorkingPractices/gh_authorisation.html#verified-commits">project guidelines</a>.`; |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (5)
.github/workflows/check-signature.yaml:15
runs-on: ubuntu-slimis not used anywhere else in this repo’s workflows (others useubuntu-24.04/ubuntu-latest), so this job may never schedule on GitHub-hosted runners unless you have a self-hosted label namedubuntu-slim. Consider switching to a standard runner label to avoid the workflow failing immediately.
runs-on: ubuntu-slim
.github/workflows/check-signature.yaml:39
- This only checks the first 100 commits (
commits(first: 100)), so PRs with more than 100 commits could bypass the signature gate for later commits. Consider paginating (GraphQLpageInfo+after) or using a REST API that returns all commits.
commits(first: 100) {
.github/workflows/check-signature.yaml:71
issues.listCommentsis paginated (defaults to 30). If a PR has more comments, the workflow may not find the existing signature-gate comment and will post duplicates instead of updating/deleting it. At minimum, request a larger page size; ideally usegithub.paginate.
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
});
.github/workflows/check-signature.yaml:78
- The comment body starts with
\n.⚠️(leading.), which looks like an accidental character and renders oddly in the PR comment.
const commentBody = `${commentIdentifier}\n.⚠️ **Unsigned Commits Detected**\n\nThe following commits in this Pull Request are missing a verified cryptographic signature:\n\n${commitList}\n\nPlease sign your commits to comply with <a href="https://metoffice.github.io/simulation-systems/WorkingPractices/gh_authorisation.html#verified-commits">project guidelines</a>.`;
.github/workflows/check-signature.yaml:111
::success::is not a supported workflow command (supported ones include::notice::,::warning::,::error::). This will just print a confusing string in logs.
console.log("::success::All commits are properly signed.");
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 3 comments.
Comments suppressed due to low confidence (1)
.github/workflows/check-signature.yaml:1
- The PR description currently says "fail if any found", which reads as the opposite of the implemented behavior (this workflow fails when unverified/unsigned commits are found). Please update the PR description to match what this workflow actually enforces.
name: Check PR Commit Signatures
| name: Check PR Commit Signatures | ||
|
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
.github/workflows/check-signature.yaml:95
listCommentsonly fetches the first page (up to 100 comments). On PRs with more than 100 comments, the workflow can miss the existing bot comment and create duplicates. Use Octokit's pagination helper to search all comments for the identifier.
// 3. Scan for an existing bot comment to update or delete
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: prNumber,
per_page: 100
});
const existingComment = comments.data.find(c => c.body.includes(commentIdentifier));
| on: | ||
| workflow_call: | ||
| inputs: | ||
| pr_number: | ||
| description: 'The Pull Request number to inspect' | ||
| required: true | ||
| type: number | ||
|
|
||
| permissions: {} # Restrict token access to the minimum required for this workflow | ||
|
|
||
| jobs: | ||
| verify: | ||
| name: Verify Signatures | ||
| runs-on: ubuntu-slim | ||
| permissions: | ||
| contents: read # Restrict token access strictly to reading repository contents | ||
| pull-requests: write # Restrict token access strictly to writing PR comments | ||
|
|
||
| steps: | ||
| - name: Check signatures and manage PR comments | ||
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | ||
| env: | ||
| PR_NUMBER: ${{ inputs.pr_number }} | ||
| with: |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
.github/workflows/check-signature.yaml:16
- This workflow is only exposed via
workflow_calland there are no callers in.github/workflowsreferencing it, so it won't actually run on PRs (and therefore won't gate unverified commits) unless another workflow invokes it. Add a PR-triggered caller workflow (e.g.,on: pull_request+jobs.<name>.uses: ./.github/workflows/check-signature.yamlwithpr_number: ${{ github.event.pull_request.number }}), or update the PR description to reflect that this is only a reusable building block.
on:
workflow_call:
inputs:
pr_number:
description: 'The Pull Request number to inspect'
required: true
type: number
| // Since our filter/map only targets matched elements, grab the first element if it exists | ||
| const existingComment = matchingComments[0] || null; | ||
|
|
| permissions: | ||
| contents: read # Restrict token access strictly to reading repository contents | ||
| pull-requests: write # Restrict token access strictly to writing PR comments |
…ature verification workflow
| permissions: | ||
| contents: read # Restrict token access strictly to reading repository contents | ||
| pull-requests: write # Required to manage PR metadata |
| permissions: | ||
| contents: read # Necessary to fetch base repository environment details | ||
| pull-requests: write # Required to manage PR metadata |
| const matchingComments = await github.paginate( | ||
| github.rest.issues.listComments, | ||
| { owner, repo, issue_number: prNumber, per_page: 100 }, | ||
| (page) => page.data | ||
| .filter(c => c.body && c.body.includes(commentIdentifier)) | ||
| .map(c => ({ id: c.id, body: c.body })) // Save only ID & body properties | ||
| ); |
PR Summary
Check commit signatures in a PR and fail if any unverified commits found.
Code Reviewer:
✅ Code Quality Checklist
(Some checks are automatically carried out via the CI pipeline)
🤖 AI Assistance and Attribution
💻 Code Review