diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17928e3..fe81e5f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,8 +8,8 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-python@v5 + - uses: actions/checkout@v7 + - uses: actions/setup-python@v7 with: python-version: '3.11' - name: Install test tools diff --git a/CHANGELOG.md b/CHANGELOG.md index 823fd84..f94be8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ This project follows semantic-versioning guidance once recurring releases are ta ### Documentation-only updates +- Upgraded first-party GitHub Actions to node24-compatible majors: `actions/checkout@v7` and `actions/setup-python@v7` in the CI workflow and the `examples/ci/github-actions/` downstream examples, with regression coverage in `tests/test_ci_actions_versions.py` against stale node20-era majors. CI tooling only; no scanner behavior change. - Added `examples/ci/github-actions/agent-security-prompt-sarif.yml` for prompt-injection signal and exposure SARIF uploads. - Added `docs/report-comparison.md` and `examples/ci/github-actions/agent-security-compare-reports.yml` for stored config-risk report comparison. - Added `docs/schema-adapters.md` and Phase 12 regression coverage in `tests/test_phase12_schema_adapters.py` for adapter fixtures, explicit ignored fields, SARIF/Markdown adapter reporting, and cross-platform path serialization. diff --git a/docs/ci-integration.md b/docs/ci-integration.md index df485b8..27da5ab 100644 --- a/docs/ci-integration.md +++ b/docs/ci-integration.md @@ -102,3 +102,7 @@ High or critical findings should block merges for shared, production, or privile 4. If the risk is intentionally accepted, document the compensating controls outside this scanner before weakening CI. Warnings and info findings can be non-blocking in early adoption, but they should still be reviewed when they involve shared channels, persistence, browser access, shell access, or sandboxing. + +## Action runtime versions + +The workflows in this repo and the copyable examples under `examples/ci/github-actions/` use `actions/checkout@v7` and `actions/setup-python@v7`, which run on the node24 runtime. Older majors such as `actions/checkout@v4` and `actions/setup-python@v5` run on node20 and accrue GitHub Actions node-deprecation annotations over time. When copying these examples, prefer the node24-compatible majors (`actions/checkout@v7`, `actions/setup-python@v7`) or newer; `tests/test_ci_actions_versions.py` guards against stale node20-era majors reappearing in runnable workflows. diff --git a/examples/ci/github-actions/agent-security-compare-reports.yml b/examples/ci/github-actions/agent-security-compare-reports.yml index bd923ff..5f0fa94 100644 --- a/examples/ci/github-actions/agent-security-compare-reports.yml +++ b/examples/ci/github-actions/agent-security-compare-reports.yml @@ -15,10 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v7 with: python-version: "3.11" diff --git a/examples/ci/github-actions/agent-security-prompt-sarif.yml b/examples/ci/github-actions/agent-security-prompt-sarif.yml index a879551..76cbf9e 100644 --- a/examples/ci/github-actions/agent-security-prompt-sarif.yml +++ b/examples/ci/github-actions/agent-security-prompt-sarif.yml @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v7 with: python-version: "3.11" diff --git a/examples/ci/github-actions/agent-security-sarif.yml b/examples/ci/github-actions/agent-security-sarif.yml index 958fa19..4114d90 100644 --- a/examples/ci/github-actions/agent-security-sarif.yml +++ b/examples/ci/github-actions/agent-security-sarif.yml @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v7 with: python-version: "3.11" diff --git a/examples/ci/github-actions/agent-security-strict.yml b/examples/ci/github-actions/agent-security-strict.yml index 48c0f37..9eb5b63 100644 --- a/examples/ci/github-actions/agent-security-strict.yml +++ b/examples/ci/github-actions/agent-security-strict.yml @@ -15,10 +15,10 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out repository - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v7 with: python-version: "3.11" diff --git a/tests/test_ci_actions_versions.py b/tests/test_ci_actions_versions.py new file mode 100644 index 0000000..f247fde --- /dev/null +++ b/tests/test_ci_actions_versions.py @@ -0,0 +1,96 @@ +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[1] + +CI_WORKFLOW = ROOT / ".github" / "workflows" / "ci.yml" +WORKFLOW_DIR = ROOT / "examples" / "ci" / "github-actions" +WORKFLOW_EXAMPLES = sorted(WORKFLOW_DIR.glob("*.yml")) +CHANGELOG = ROOT / "CHANGELOG.md" +CI_DOC = ROOT / "docs" / "ci-integration.md" + +# First-party action major versions that run on the node24 runtime. +# actions/checkout v4 and actions/setup-python v5 run on node20, which +# GitHub Actions flags with node-deprecation annotations as node24 +# becomes the required runtime. Keep the repo workflow and the copyable +# downstream examples on node24-compatible majors. +NODE24_ACTIONS = { + "actions/checkout": "v7", + "actions/setup-python": "v7", +} + +# Third-party actions allowed in workflows; codeql-action's current major +# already targets modern node runtimes and is validated separately. +ALLOWED_ACTIONS = { + "actions/checkout", + "actions/setup-python", + "github/codeql-action/upload-sarif", +} + +# Stale node20-era majors that must not reappear in runnable workflows. +STALE_ACTION_REFS = [ + "actions/checkout@v1", + "actions/checkout@v2", + "actions/checkout@v3", + "actions/checkout@v4", + "actions/setup-python@v1", + "actions/setup-python@v2", + "actions/setup-python@v3", + "actions/setup-python@v4", + "actions/setup-python@v5", +] + + +def _read(path: Path) -> str: + assert path.exists(), f"missing expected CI artifact: {path.relative_to(ROOT)}" + text = path.read_text(encoding="utf-8") + assert text.endswith("\n"), f"{path.relative_to(ROOT)} should end with a newline" + return text + + +def _action_refs(text: str) -> list: + """Return every `uses:` reference in a workflow body.""" + refs = [] + for line in text.splitlines(): + stripped = line.strip() + if stripped.startswith("- uses:") or stripped.startswith("uses:"): + ref = stripped.split("uses:", 1)[1].strip().strip("'\"") + refs.append(ref) + return refs + + +def test_ci_workflow_and_examples_use_node24_first_party_actions() -> None: + paths = [CI_WORKFLOW, *WORKFLOW_EXAMPLES] + assert WORKFLOW_EXAMPLES, "expected workflow examples under examples/ci/github-actions" + for path in paths: + text = _read(path) + refs = _action_refs(text) + assert refs, f"{path.relative_to(ROOT)} uses no actions" + for ref in refs: + owner_repo, _, version = ref.partition("@") + assert owner_repo in ALLOWED_ACTIONS, ( + f"{path.relative_to(ROOT)} references unexpected action {owner_repo}" + ) + if owner_repo in NODE24_ACTIONS: + assert version == NODE24_ACTIONS[owner_repo], ( + f"{path.relative_to(ROOT)} should use {owner_repo}@{NODE24_ACTIONS[owner_repo]} " + f"(node24 runtime), found {ref}" + ) + + +def test_no_stale_node20_action_majors_in_runnable_workflows() -> None: + """Guard against stale node20-era majors creeping back into runnable workflows.""" + scan_targets = [CI_WORKFLOW, *WORKFLOW_EXAMPLES] + for path in scan_targets: + text = _read(path) + for stale in STALE_ACTION_REFS: + assert stale not in text, f"{path.relative_to(ROOT)} still references {stale}" + + +def test_changelog_and_ci_docs_note_the_node24_actions_upgrade() -> None: + changelog = _read(CHANGELOG) + doc = _read(CI_DOC) + assert "actions/checkout@v7" in changelog + assert "actions/setup-python@v7" in changelog + assert "node24" in doc + assert "actions/checkout@v7" in doc + assert "actions/setup-python@v7" in doc