-
Notifications
You must be signed in to change notification settings - Fork 0
204 lines (186 loc) · 9.39 KB
/
Copy pathpre-commit.yml
File metadata and controls
204 lines (186 loc) · 9.39 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
name: pre-commit
on:
pull_request:
branches: [main]
push:
branches: [main]
permissions:
contents: read
jobs:
pre-commit:
name: Run pre-commit hooks
runs-on: ubuntu-latest
# 35 minutes accommodates the 3-attempt retry wrapper on the
# `Run pre-commit` step below (3 attempts * 10 min per-attempt
# timeout + 2 * 90 s retry waits = 33 min worst case) plus a
# small margin for setup/install steps. Without the bump, the
# job-level cap killed any retry attempt before it could start,
# making the retry policy ineffective (CR finding on #697).
timeout-minutes: 35
steps:
- name: Checkout code
uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
persist-credentials: false
- name: Verify checkout SHA
env:
expectedSHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
set -euo pipefail
actualSHA="$(git rev-parse HEAD)"
echo "Expected SHA: ${expectedSHA}"
echo "Actual SHA: ${actualSHA}"
test "${actualSHA}" = "${expectedSHA}"
- name: Set up Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.13"
- name: Set up Go
uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with:
# Read from go.mod rather than a hardcoded string, matching
# aws_sanity / azure_sanity / database-migration. One fewer place the
# Go version has to be bumped by hand (issue #1833).
go-version-file: pkg/go.mod
cache-dependency-path: "**/go.sum"
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: "24"
# Cache the installed tool binaries (gosec, gocyclo). Keyed on the
# pinned version strings so a tool-version bump still triggers a
# fresh install. Both binaries land in ~/go/bin which setup-go@v6
# already adds to PATH. Restored BEFORE the install steps so the
# `if: cache-hit != 'true'` guards below can short-circuit them on
# cache-hit runs (the `go install` invocations cost ~3-5s each
# even when the module cache is warm; skipping them on cache-hit
# is worth the extra `if`).
- name: Cache Go-installed tools (gosec, gocyclo)
id: cache-go-tools
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/go/bin
key: go-tools-${{ runner.os }}-gosec-v2.28.0-gocyclo-v0.6.0
- name: Install gosec
if: steps.cache-go-tools.outputs.cache-hit != 'true'
# Pinned to the same version ci.yml's `securego/gosec` Action uses,
# so an upstream gosec release with rule changes can't silently
# downgrade the gate between the two workflows.
run: go install github.com/securego/gosec/v2/cmd/gosec@v2.28.0
- name: Install gocyclo
if: steps.cache-go-tools.outputs.cache-hit != 'true'
# Pinned to match ci.yml — security tool installs must not use
# @latest; that's exactly the supply-chain weakness this PR is
# closing for Dockerfile FROMs.
run: go install github.com/fzipp/gocyclo/cmd/gocyclo@v0.6.0
- name: Install Trivy
# Pinned to v0.69.3 (the latest release with published GitHub-release
# tarballs as of writing). Tags exist for v0.58 onwards but several
# mid-range releases skipped publishing assets to the Releases page;
# the install.sh script fetches via GitHub Releases, so picking one
# of those tags makes install bail silently after detecting the
# version. v0.69.3 ships the standard `trivy_<ver>_Linux-64bit.tar.gz`
# asset.
#
# The installer itself is fetched from the same pinned release tag
# (not the mutable `main` branch) and downloaded to a file before
# execution: a malicious or
# accidental change to install.sh on main can't silently execute
# on this CI runner, and `curl -fsSL` makes transport errors fail
# loudly instead of piping an HTML error page into sh.
env:
TRIVY_VERSION: v0.69.3
run: |
set -euo pipefail
curl -fsSL -o /tmp/trivy-install.sh \
"https://raw.githubusercontent.com/aquasecurity/trivy/${TRIVY_VERSION}/contrib/install.sh"
sh /tmp/trivy-install.sh -b /usr/local/bin "${TRIVY_VERSION}"
- name: Install git-secrets
# Pinned to a release tag rather than master HEAD. The tag is
# mutable in principle, so also assert HEAD resolves to the exact
# commit verified at the time this was written (`git ls-remote
# --tags` against the upstream repo) before trusting it enough to
# `sudo make install`. After install we register the AWS pattern
# set and ASSERT at least one pattern was registered — without the
# assert, a registration failure produces a patternless scanner
# that exits 0 unconditionally, leaving the gate silently
# downgraded.
env:
GIT_SECRETS_SHA: ad82d68ee924906a0401dfd48de5057731a9bc84
run: |
set -euo pipefail
git clone --depth 1 --branch 1.3.0 https://github.com/awslabs/git-secrets.git /tmp/git-secrets
resolved="$(git -C /tmp/git-secrets rev-parse HEAD)"
if [ "${resolved}" != "${GIT_SECRETS_SHA}" ]; then
echo "git-secrets 1.3.0 tag resolved to ${resolved}, expected ${GIT_SECRETS_SHA}" >&2
exit 1
fi
sudo make -C /tmp/git-secrets install
git secrets --register-aws --global
git secrets --list --global | grep -q '.' || {
echo "git-secrets registration produced no patterns — gate would be silently disabled"
exit 1
}
- name: Run git-secrets allowlist self-test
# Self-test for the git-secrets allowlist (#1972): asserts, through
# the real pre-commit hook scan path, that secret-shaped fixtures
# are still caught and that the documented false positives still
# scan clean.
run: bash scripts/test-git-secrets-allowlist.sh
# Note: the local `hadolint` hook in .pre-commit-config.yaml (search for
# `id: hadolint`; no line number, because this comment has already gone
# stale twice as that file shifted) runs ghcr.io/hadolint/hadolint pinned
# by digest. The version lives in that entry and is the single source of
# truth; do not restate it here, or this comment rots again. We do NOT
# install a host binary here — it would be dead code (never invoked by
# the hook) AND a supply-chain hole (latest tag, no checksum). Note:
# an earlier version of this comment claimed the hook already pinned
# the image to v2.14.0 via the hook repo's `rev:` -- it did not; that
# `rev:` only pins hadolint's *hook definition*, whose upstream entry
# (`ghcr.io/hadolint/hadolint hadolint`) has no image tag and floats to
# `:latest`. See the digest pin in .pre-commit-config.yaml for the fix.
# If a future change switches the hook to a host binary, install a
# pinned + sha256-verified binary here.
- name: Install pre-commit
run: pip install 'pre-commit==4.0.1'
# Cache pre-commit's per-hook environments (Go, Python, Node, etc.
# virtualenvs it builds on first run). Keyed on the hook config
# because pre-commit will rebuild any env whose pinned rev changes.
# Saves ~30-60s per cache-hit run; safe because pre-commit verifies
# env integrity on use.
- name: Cache pre-commit environments
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}
restore-keys: |
pre-commit-${{ runner.os }}-
# Cache the Go build cache so `go vet`, `gosec`, and any other
# Go-compiling hooks reuse compiled object files instead of
# rebuilding from source. setup-go@v6 caches ~/go/pkg/mod
# (modules) but NOT ~/.cache/go-build (compiled output) — this
# step covers the latter. Keyed on go.sum so a dep upgrade still
# invalidates the cache and gets clean builds.
- name: Cache Go build cache
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: ~/.cache/go-build
key: go-build-${{ runner.os }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-build-${{ runner.os }}-
- name: Run pre-commit
# SKIP the local per-changed-package gosec hook in CI: --all-files
# feeds every Go file at once, while the dedicated Security Scanning
# job remains the authoritative per-module gosec v2.28.0 gate.
# nick-fields/retry wraps the run with up to 3 attempts and a
# 90-second wait so transient flakes do not require a manual rerun.
uses: nick-fields/retry@ce71cc2ab81d554ebbe88c79ab5975992d79ba08 # v3.0.2
env:
SKIP: gosec
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
timeout_minutes: 10
max_attempts: 3
retry_wait_seconds: 90
command: pre-commit run --all-files