Skip to content

Commit eecf098

Browse files
committed
ci: pin persistent runner actions
1 parent 8b6d74b commit eecf098

3 files changed

Lines changed: 35 additions & 16 deletions

File tree

.github/workflows/ci-self-hosted.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
runs-on: [self-hosted, macOS, ARM64, cppmega-mlx-macos]
1919
timeout-minutes: 30
2020
steps:
21-
- uses: actions/checkout@v4
21+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
2222
- name: Run focused MLX contract suite
2323
shell: bash
2424
run: |
@@ -47,8 +47,8 @@ jobs:
4747
runs-on: [self-hosted, Linux, X64, cppmega-mlx]
4848
timeout-minutes: 20
4949
steps:
50-
- uses: actions/checkout@v4
51-
- uses: actions/setup-python@v5
50+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
51+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
5252
with:
5353
python-version: "3.13"
5454
- name: Install portable test dependencies

.github/workflows/e2e-matrix.yml

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ jobs:
3939
matrix:
4040
shard: [1, 2, 3, 4]
4141
steps:
42-
- uses: actions/checkout@v4
43-
- uses: actions/setup-node@v4
42+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
43+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
4444
with:
4545
node-version: "22"
4646
cache: "npm"
@@ -81,7 +81,7 @@ jobs:
8181
--shard=${{ matrix.shard }}/4
8282
- name: Upload artefacts
8383
if: always()
84-
uses: actions/upload-artifact@v4
84+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
8585
with:
8686
name: preset-matrix-shard-${{ matrix.shard }}
8787
path: |
@@ -97,8 +97,8 @@ jobs:
9797
runs-on: [self-hosted, macOS, ARM64, cppmega-mlx-macos]
9898
timeout-minutes: 15
9999
steps:
100-
- uses: actions/checkout@v4
101-
- uses: actions/setup-node@v4
100+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
101+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
102102
with: { node-version: "22", cache: "npm",
103103
cache-dependency-path: vbgui/package-lock.json }
104104
- name: Create isolated MLX Python
@@ -131,7 +131,7 @@ jobs:
131131
e2e/scenarios/06_sharding_proposals.spec.ts \
132132
e2e/scenarios/07_gotchas.spec.ts
133133
- if: always()
134-
uses: actions/upload-artifact@v4
134+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
135135
with:
136136
name: specialised-results
137137
path: |
@@ -147,8 +147,8 @@ jobs:
147147
runs-on: [self-hosted, macOS, ARM64, cppmega-mlx-macos]
148148
timeout-minutes: 60
149149
steps:
150-
- uses: actions/checkout@v4
151-
- uses: actions/setup-node@v4
150+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
151+
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
152152
with: { node-version: "22", cache: "npm",
153153
cache-dependency-path: vbgui/package-lock.json }
154154
- name: Create isolated MLX Python
@@ -177,7 +177,7 @@ jobs:
177177
npx playwright test --config=e2e/playwright.config.ts \
178178
e2e/scenarios/03_train_matrix.spec.ts
179179
- if: always()
180-
uses: actions/upload-artifact@v4
180+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
181181
with:
182182
name: mini-train-results
183183
path: |
@@ -194,18 +194,18 @@ jobs:
194194
runs-on: [self-hosted, Linux, X64, cppmega-mlx]
195195
if: ${{ always() && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) }}
196196
steps:
197-
- uses: actions/checkout@v4
198-
- uses: actions/download-artifact@v4
197+
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
198+
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
199199
with: { path: artifacts }
200-
- uses: actions/setup-python@v5
200+
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
201201
with: { python-version: "3.13" }
202202
- name: Build matrix report
203203
run: |
204204
python tools/build_e2e_matrix_report.py \
205205
--artifacts artifacts \
206206
--output e2e_matrix_report.md
207207
cat e2e_matrix_report.md >> "$GITHUB_STEP_SUMMARY"
208-
- uses: actions/upload-artifact@v4
208+
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
209209
with:
210210
name: e2e_matrix_report
211211
path: e2e_matrix_report.md

tests/test_workflow_runner_policy.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
"github.event_name == 'schedule' || "
2222
"github.event_name == 'workflow_dispatch'"
2323
)
24+
ACTION_USE = re.compile(
25+
r"uses:\s*['\"]?(?P<action>actions/[A-Za-z0-9_.-]+)"
26+
r"@(?P<ref>[^\s'\"#]+)"
27+
)
2428

2529

2630
def test_workflows_do_not_use_github_hosted_runners() -> None:
@@ -56,6 +60,21 @@ def test_pull_requests_cannot_execute_on_persistent_self_hosted_runners() -> Non
5660
)
5761

5862

63+
def test_persistent_pr_ci_actions_are_pinned_to_commits() -> None:
64+
violations = []
65+
for name in ("ci-self-hosted.yml", "e2e-matrix.yml"):
66+
workflow = (
67+
REPO_ROOT / ".github" / "workflows" / name
68+
).read_text(encoding="utf-8")
69+
violations.extend(
70+
f"{name}:{match.group('action')}@{match.group('ref')}"
71+
for match in ACTION_USE.finditer(workflow)
72+
if re.fullmatch(r"[0-9a-f]{40}", match.group("ref")) is None
73+
)
74+
75+
assert not violations, f"mutable action references are forbidden: {violations}"
76+
77+
5978
def test_macos_e2e_uses_an_isolated_job_venv() -> None:
6079
workflow = (REPO_ROOT / ".github" / "workflows" / "e2e-matrix.yml").read_text(
6180
encoding="utf-8"

0 commit comments

Comments
 (0)