forked from ChelseaKR/tods-validate
-
Notifications
You must be signed in to change notification settings - Fork 0
109 lines (103 loc) · 4.98 KB
/
Copy pathverify.yml
File metadata and controls
109 lines (103 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
name: Verify (reusable)
# The full merge-blocking gate set (`make verify`), callable from CI and from
# the release workflows so a release can never publish without re-running it
# at the tagged commit (REL-14/15; CICD-27 make verify = CI gates, by
# construction rather than copy-paste).
#
# Pass `tag` when calling from a release workflow to additionally enforce:
# - version consistency: the tag, pyproject.toml, and CITATION.cff all agree,
# and CHANGELOG.md has a section for the released version (REL-03/REL-10).
# - the tag is an annotated, signed tag object, not a lightweight one
# (REL-08), and its SSH signature verifies against the committed
# .github/allowed_signers file. This is a forward-fix: existing tags
# (through v0.6.0) predate it and are not retroactively rewritten.
on:
workflow_call:
inputs:
tag:
description: Release tag being verified (e.g. v0.6.0). Empty outside a release.
required: false
type: string
default: ""
permissions:
contents: read
jobs:
verify:
runs-on: ubuntu-latest
env:
GITLEAKS_VERSION: "8.30.1"
GITLEAKS_SHA256: "551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb"
# Routed through env: rather than interpolated into the run: shell below
# (CICD-21): `tag` is a workflow_call input and, transitively, a
# release's tag name, which is not guaranteed to be shell-metacharacter-
# free or trusted.
TAG: ${{ inputs.tag }}
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
with:
persist-credentials: false
fetch-depth: 0 # full history + tags: needed for the tag/version checks below
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
with:
python-version: "3.13"
# CQ-09 drift half of the gate; see the note in the Makefile's `lockfile`
# target for why `uv sync --frozen` alone cannot fail on a stale lock.
- run: uv lock --check
- run: uv sync --frozen --extra dev
- run: echo "$PWD/.venv/bin" >> "$GITHUB_PATH"
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "24"
cache: npm
cache-dependency-path: package-lock.json
- run: npm ci --ignore-scripts
- name: Select the hosted Chrome binary
run: |
a11y_chrome="$(command -v google-chrome)"
test -x "$a11y_chrome"
echo "PUPPETEER_EXECUTABLE_PATH=$a11y_chrome" >> "$GITHUB_ENV"
- name: Install gitleaks (checksum-verified)
run: |
set -eu
curl -sSL -o gitleaks.tar.gz \
"https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}/gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz"
echo "${GITLEAKS_SHA256} gitleaks.tar.gz" | sha256sum -c -
tar -xzf gitleaks.tar.gz gitleaks
sudo install -m 0755 gitleaks /usr/local/bin/gitleaks
- run: make verify
- name: Version consistency (REL-03)
if: inputs.tag != ''
run: |
set -eu
TAG_VERSION="${TAG#v}"
PYPROJECT_VERSION="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml","rb"))["project"]["version"])')"
CFF_VERSION="$(grep -E '^version:' CITATION.cff | head -1 | sed -E 's/^version:[[:space:]]*//')"
echo "tag=$TAG_VERSION pyproject=$PYPROJECT_VERSION cff=$CFF_VERSION"
if [ "$TAG_VERSION" != "$PYPROJECT_VERSION" ] || [ "$TAG_VERSION" != "$CFF_VERSION" ]; then
echo "::error::Version mismatch: tag=$TAG_VERSION pyproject=$PYPROJECT_VERSION CITATION.cff=$CFF_VERSION"
exit 1
fi
if ! grep -qE "^## v?${TAG_VERSION//./\\.}( |$)" CHANGELOG.md; then
echo "::error::CHANGELOG.md has no section heading for version $TAG_VERSION (expected a line matching '## v$TAG_VERSION - YYYY-MM-DD')."
exit 1
fi
- name: Tag is annotated and signed (REL-08)
if: inputs.tag != ''
run: |
set -eu
git fetch origin --tags --force
TAG_TYPE="$(git cat-file -t "$TAG" 2>/dev/null || echo missing)"
if [ "$TAG_TYPE" != "tag" ]; then
echo "::error::$TAG is a $TAG_TYPE, not an annotated tag object. Create release tags with: git tag -s $TAG -m \"release: $TAG\""
exit 1
fi
# Release tags are SSH-signed; git verify-tag needs an
# allowed-signers list to map the signature to a trusted principal.
# The list is committed at the verified ref, so trusting it is the
# same trust decision as running this workflow's own code.
git config gpg.ssh.allowedSignersFile "$PWD/.github/allowed_signers"
if ! git verify-tag "$TAG" >/tmp/verify-tag.log 2>&1; then
echo "::error::$TAG is not a verifiable signed tag. Sign it: git tag -s $TAG -m \"release: $TAG\" (see the log below)."
cat /tmp/verify-tag.log
exit 1
fi