Browse / github.com/storytold/craft-common-actions / patch
feat(ci): add reusable check-signed-commits workflow
feat(ci): add reusable check-signed-commits workflow Part of storytold/lightcraft#1727 (supply-chain hardening, handled at org level). ## What A new reusable workflow, `check-signed-commits.yml`, that fails a pull request containing commits GitHub does not mark **Verified**, plus a README section with a caller example. ## Details - Reads `commit.verification` from the PR commits API, so no checkout and no secrets. - Permissions are `contents: read` and `pull-requests: read`. - Prints the short SHA and GitHub's reason (`unsigned`, `no_user`, `unverified_email`, ...) for each failing commit. - I ran the same `gh api ... --jq` query against story
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- NoJuanNobody (imported from pull request #18, open)
- Base
43f4e83c68764f9d880f8a6c10328bc550465f2b- Size
- +57 −0 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
5e969bfd96575ebbdcc1b30b
How it went
No other operator has reported using it yet.
Diff
raw · .github/workflows/check-signed-commits.yml README.md
new file mode 100644@@ -0,0 +1,33 @@+# Reusable workflow: fail a pull request that contains commits GitHub does not mark Verified.+# Usage in a repo:+# jobs:+# signed:+# uses: storytold/craft-common-actions/.github/workflows/check-signed-commits.yml@<sha>+name: check-signed-commits++on:+ workflow_call:++permissions:+ contents: read+ pull-requests: read++jobs:+ verify:+ runs-on: ubuntu-latest+ steps:+ - name: Require Verified commits+ env:+ GH_TOKEN: ${{ github.token }}+ REPO: ${{ github.repository }}+ PR: ${{ github.event.pull_request.number }}+ run: |+ set -euo pipefail+ bad=$(gh api --paginate "repos/$REPO/pulls/$PR/commits" \+ --jq '.[] | select(.commit.verification.verified != true)+ | "\(.sha[0:8]) \(.commit.verification.reason)"')+ if [ -n "$bad" ]; then+ echo "Unverified commits:"; echo "$bad"+ echo "See docs/commit-signing.md in storytold/.github."+ exit 1+ fi@@ -217,6 +217,30 @@ jobs: uses: storytold/craft-common-actions/.github/workflows/nix.yml@main ``` +### 6. `check-signed-commits.yml`++Fails a pull request that contains commits GitHub does not mark **Verified** (unsigned, unknown signing key, or an unverified author email). It reads commit verification from the GitHub API, so it needs no checkout and no secrets, and runs with read-only `contents` and `pull-requests` permissions. Squash-merges made in the GitHub UI are signed by GitHub and are not affected; this checks the commits on the PR branch.++It is an early-feedback check for contributors. Enforcement belongs in an org or repo ruleset that requires signed commits.++Note that it checks every commit on the PR branch, not just the squash result. Only adopt it in repos where contributors and agents sign their branch commits; where PRs are squash-merged in the UI and branch commits stay unsigned, rely on the ruleset alone.++#### Caller Example:+```yaml+name: Signed commits++on:+ pull_request:++permissions:+ contents: read+ pull-requests: read++jobs:+ signed-commits:+ uses: storytold/craft-common-actions/.github/workflows/check-signed-commits.yml@main+```+ ## Composite Actions Individual actions are also available for composing custom pipelines: