Skip to content

Commit e5df517

Browse files
authored
ci: pin actions to commit SHAs and add shellcheck (#3126)
* ci: pin actions to commit SHAs and add shellcheck Pin actions/github-script in catalog-assign.yml to a full commit SHA; all other workflows were already pinned. Add a repo-wide regression test that every workflow `uses:` ref is pinned to a 40-char commit SHA. Add a shellcheck job to lint.yml (--severity=error over scripts/bash/*.sh) and document the local command in CONTRIBUTING.md. * ci: use repo-standard actions/checkout v7.0.0 in shellcheck job * ci: shellcheck all tracked shell scripts Assisted-by: Codex (model: GPT-5, autonomous) * ci: address workflow hygiene review feedback Assisted-by: Codex (model: GPT-5, autonomous)
1 parent b577e6c commit e5df517

4 files changed

Lines changed: 64 additions & 1 deletion

File tree

.github/workflows/catalog-assign.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
permissions:
2020
issues: write
2121
steps:
22-
- uses: actions/github-script@v9
22+
- uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
2323
with:
2424
script: |
2525
const issue = context.payload.issue;

.github/workflows/lint.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,15 @@ jobs:
4242
globs: |
4343
'**/*.md'
4444
!extensions/**/*.md
45+
46+
shellcheck:
47+
runs-on: ubuntu-latest
48+
steps:
49+
- name: Checkout
50+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
51+
52+
# shellcheck is preinstalled on ubuntu-latest runners.
53+
# Start at --severity=error to block real bugs without flagging style
54+
# (notably SC2155). Tighten in a follow-up after cleanup.
55+
- name: Run shellcheck on shell scripts
56+
run: git ls-files -z -- '*.sh' | xargs -0 shellcheck --severity=error

CONTRIBUTING.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ uv pip install -e ".[test]"
113113
> `specify_cli` to this checkout's `src/`. This matches the gotcha documented in
114114
> `AGENTS.md` (Common Pitfalls).
115115
116+
#### Shell scripts
117+
118+
```bash
119+
git ls-files -z -- '*.sh' | xargs -0 shellcheck --severity=error
120+
```
121+
122+
The CI `lint.yml` `shellcheck` job currently reports and blocks only
123+
error-severity findings. Warnings such as SC2155 are intentionally outside this
124+
job until a follow-up cleanup tightens the threshold.
125+
116126
### Manual testing
117127

118128
#### Testing setup

tests/test_github_workflows.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
"""Static checks for repository GitHub Actions workflows."""
2+
3+
from __future__ import annotations
4+
5+
import re
6+
from pathlib import Path
7+
8+
9+
REPO_ROOT = Path(__file__).resolve().parent.parent
10+
WORKFLOWS_DIR = REPO_ROOT / ".github" / "workflows"
11+
# Match both the dedicated-step form (` uses: x@sha`) and the
12+
# inline shorthand (` - uses: x@sha`) used in catalog-assign.yml.
13+
USES_RE = re.compile(r"^\s*(?:-\s*)?uses:\s*(?P<ref>\S+)", re.MULTILINE)
14+
PINNED_SHA_RE = re.compile(r"@[0-9a-f]{40}$", re.IGNORECASE)
15+
16+
17+
def test_github_actions_are_pinned_to_full_commit_shas():
18+
unpinned_refs = []
19+
20+
workflows = sorted(
21+
list(WORKFLOWS_DIR.glob("*.yml")) + list(WORKFLOWS_DIR.glob("*.yaml"))
22+
)
23+
assert workflows
24+
25+
for workflow in workflows:
26+
workflow_text = workflow.read_text(encoding="utf-8")
27+
for match in USES_RE.finditer(workflow_text):
28+
uses_ref = match.group("ref")
29+
if uses_ref.startswith(("./", "../")):
30+
continue
31+
if PINNED_SHA_RE.search(uses_ref):
32+
continue
33+
unpinned_refs.append(f"{workflow.relative_to(REPO_ROOT)}: {uses_ref}")
34+
35+
assert unpinned_refs == []
36+
37+
38+
def test_pinned_action_ref_accepts_uppercase_hex_sha():
39+
assert PINNED_SHA_RE.search(
40+
"actions/example@0123456789ABCDEF0123456789ABCDEF01234567"
41+
)

0 commit comments

Comments
 (0)