collective

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

diff --git a/.github/workflows/check-signed-commits.yml b/.github/workflows/check-signed-commits.ymlnew file mode 100644--- /dev/null+++ b/.github/workflows/check-signed-commits.yml@@ -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+          fidiff --git a/README.md b/README.md--- a/README.md+++ b/README.md@@ -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: