Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions .github/workflows/hygiene.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,46 @@ jobs:
- name: actionlint
uses: raven-actions/actionlint@3d39aea434753780c3b3d4a1a31c854b4dbf49d7 # v2.2.0

# The org's two pinning rules are the kind that decay silently: nothing
# fails when a `uses:` line drifts, it just quietly widens the blast
# radius of someone else's repository. This is the only thing enforcing
# them, so it runs everywhere hygiene runs.
- name: action pins (ADR-0012, ADR-0021)
run: |
fail=0
while IFS= read -r line; do
file=${line%%:*}
rest=${line#*:}
lineno=${rest%%:*}
ref=$(printf '%s' "$line" | sed -E 's/.*uses:[[:space:]]*//; s/[[:space:]]*(#.*)?$//' | tr -d "\"'")

# A local composite action carries no supply-chain risk of its own.
case $ref in
./*|'') continue ;;
esac

if [ "${ref%%/*}" = "beatrax-app" ]; then
# First-party: the moving major-version tag is the contract.
if ! printf '%s' "$ref" | grep -qE '@v[0-9]+$'; then
echo "$file:$lineno: first-party reusable workflow must ride a major-version tag (@v1), got: $ref"
fail=1
fi
continue
fi

if ! printf '%s' "$ref" | grep -qE '@[0-9a-f]{40}$'; then
echo "$file:$lineno: third-party action must be pinned to a full 40-character commit SHA, got: $ref"
fail=1
fi
done < <(grep -rnE '^[[:space:]]*(-[[:space:]]*)?uses:' .github/workflows/ 2>/dev/null)

if [ "$fail" -ne 0 ]; then
echo
echo "See ADR-0012 (third-party SHA pinning) and ADR-0021 (first-party @vN tags)."
exit 1
fi
echo "action pins OK"

typos:
runs-on: ubuntu-latest
steps:
Expand Down
12 changes: 12 additions & 0 deletions 00-overview/decisions/0012-action-pinning.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ Two rules, deliberately different:
Dependency automation watches the actions ecosystem weekly so the inline version
comments do not rot.

## Enforcement

The `action pins` step in the shared `hygiene` workflow fails the build on any
`uses:` line that breaks either rule — a third-party action without a full
40-character SHA, or a first-party reusable workflow off its major-version tag.
It runs in every repository that calls `hygiene`.

This is deliberate rather than incidental. The second rule of this ADR went
unfollowed from the day it was written until [ADR-0021](0021-reusable-workflow-version-tags.md)
found three repositories doing two different things, because nothing checked.
An unenforced pinning rule is a comment.

## Alternatives considered

| Option | Why it lost |
Expand Down
Loading