From d06edee72fecf181fc0191c8ff5740d42b8feba7 Mon Sep 17 00:00:00 2001 From: Shamim Rehman Date: Thu, 7 May 2026 13:34:35 -0400 Subject: [PATCH] Pin CI actions to commit SHAs --- .github/workflows/ci.yml | 8 ++++---- tests/test_ci_workflow.py | 12 ++++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0261a2e..3c2bbec 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,10 +17,10 @@ jobs: python-version: ["3.11", "3.12", "3.13"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: ${{ matrix.python-version }} @@ -36,10 +36,10 @@ jobs: dependency-security: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5 with: python-version: "3.11" diff --git a/tests/test_ci_workflow.py b/tests/test_ci_workflow.py index 6faa938..613f32d 100644 --- a/tests/test_ci_workflow.py +++ b/tests/test_ci_workflow.py @@ -1,10 +1,12 @@ from __future__ import annotations +import re from pathlib import Path ROOT = Path(__file__).resolve().parents[1] CI_WORKFLOW = ROOT / ".github" / "workflows" / "ci.yml" +TAGGED_ACTION_REF = re.compile(r"uses:\s+[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+@v\d+") def test_ci_workflow_has_dependency_security_gate() -> None: @@ -16,3 +18,13 @@ def test_ci_workflow_has_dependency_security_gate() -> None: assert 'python -m pip install --upgrade "pip>=26.1"' in workflow assert "python -m pip install pip-audit" in workflow assert "python -m pip_audit --progress-spinner off" in workflow + + +def test_github_actions_are_pinned_to_commit_shas() -> None: + offenders = [ + line.strip() + for line in CI_WORKFLOW.read_text().splitlines() + if TAGGED_ACTION_REF.search(line) + ] + + assert offenders == []