docs(cicd): pin reusable-workflow refs to commit SHAs instead of @main

The org standard for reusable-workflow references changes from the mutable
@main branch ref to full commit SHA pins advanced by Dependabot. Adds a
Workflow Ref Pinning section covering the rationale and the two
prerequisites that keep pins current (github-actions ecosystem in
dependabot.yml, org-level Dependabot access to the internal .github repo).
This commit is contained in:
Adam Moussa 2026-07-27 15:28:31 -04:00
parent 0e83835b4a
commit 5f1818cd6b
No known key found for this signature in database

29
cicd.md
View file

@ -27,7 +27,7 @@ on:
branches: [main] branches: [main]
jobs: jobs:
ci: ci:
uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@main uses: Sea-Haven-Industries/.github/.github/workflows/ci-typescript-cdk.yaml@<full-commit-sha> # main
with: with:
node-version: "24" node-version: "24"
@ -38,7 +38,7 @@ on:
branches: [main] branches: [main]
jobs: jobs:
deploy: deploy:
uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@main uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@<full-commit-sha> # main
with: with:
node-version: "24" node-version: "24"
secrets: secrets:
@ -55,7 +55,7 @@ on:
branches: [main] branches: [main]
jobs: jobs:
ci: ci:
uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@main uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@<full-commit-sha> # main
# .github/workflows/deploy.yaml # .github/workflows/deploy.yaml
name: Deploy name: Deploy
@ -64,7 +64,7 @@ on:
branches: [main] branches: [main]
jobs: jobs:
deploy: deploy:
uses: Sea-Haven-Industries/.github/.github/workflows/cd-sam.yaml@main uses: Sea-Haven-Industries/.github/.github/workflows/cd-sam.yaml@<full-commit-sha> # main
with: with:
stack-name: "your-stack-name" stack-name: "your-stack-name"
secrets: secrets:
@ -88,7 +88,24 @@ Always pass `node-version: "24"` to reusable workflows. Local dev uses Node 24 /
## Naming ## Naming
- All workflow files: kebab-case - All workflow files: kebab-case
- Reusable workflow references: `@main` branch - Reusable workflow references: pinned to a full 40-character commit SHA with a `# main` comment — never a branch or tag ref
## Workflow Ref Pinning
Reusable workflow references are pinned to a full commit SHA of the central `.github` repo, with a trailing `# main` comment:
```yaml
uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@<full-commit-sha> # main
```
Branch refs are mutable: a compromised or bad commit on the central repo would flow instantly into every consumer's CI and deploy path. A SHA pin turns that same change into a reviewable Dependabot PR instead. The comment tells Dependabot (and readers) which ref the pin tracks.
Per the pinning principle, pins are for reproducibility, not for freezing time. Two prerequisites keep them moving:
1. Every repo's `dependabot.yml` must include the `github-actions` ecosystem (weekly), so pin-advance PRs are opened automatically.
2. Dependabot must be granted access to the internal `.github` repo at the org level (Org Settings → Advanced Security → Global settings → "Grant Dependabot access to repositories"). Without the grant, update jobs fail with `git_dependencies_not_reachable` and pins freeze silently — consumers stop receiving central workflow fixes with no visible signal beyond the failed Dependabot run.
When adding a caller workflow by hand, pin to the current tip of the central repo's `main` (`gh api /repos/Sea-Haven-Industries/.github/commits/main --jq .sha`) and let Dependabot advance it from there.
## When to Add a Pipeline ## When to Add a Pipeline
@ -113,7 +130,7 @@ permissions:
issues: write issues: write
jobs: jobs:
label: label:
uses: Sea-Haven-Industries/.github/.github/workflows/callable-labeler.yaml@main uses: Sea-Haven-Industries/.github/.github/workflows/callable-labeler.yaml@<full-commit-sha> # main
``` ```
- The trigger is plain `pull_request`, not `pull_request_target`: private repos take no fork PRs, so the lower-privilege event is sufficient and avoids the pwn-request surface. Because `pull_request` runs the workflow from the merge commit, the Labeler check appears on the PR that first adds the caller — an absent or failed check means a missing permission, not expected behaviour. - The trigger is plain `pull_request`, not `pull_request_target`: private repos take no fork PRs, so the lower-privilege event is sufficient and avoids the pwn-request surface. Because `pull_request` runs the workflow from the merge commit, the Labeler check appears on the PR that first adds the caller — an absent or failed check means a missing permission, not expected behaviour.