From 37f2ecaeba8d9cfd8c8b28fd01871508d4b54666 Mon Sep 17 00:00:00 2001 From: Daniel Strader Date: Mon, 3 Aug 2026 09:44:15 -0700 Subject: [PATCH 1/2] ci: pin Node 24 setup action --- .github/workflows/ci.yml | 2 +- tests/test_workflow_pins.py | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 tests/test_workflow_pins.py diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a14062e..124b16b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 with: node-version: "22" - name: Listener and engine parse diff --git a/tests/test_workflow_pins.py b/tests/test_workflow_pins.py new file mode 100644 index 0000000..6de4d59 --- /dev/null +++ b/tests/test_workflow_pins.py @@ -0,0 +1,20 @@ +from pathlib import Path +import re +import unittest + + +class WorkflowPinTests(unittest.TestCase): + def test_setup_node_is_immutable_and_node24_compatible(self): + workflow = (Path(__file__).parents[1] / ".github" / "workflows" / "ci.yml").read_text( + encoding="utf-8" + ) + matches = re.findall(r"actions/setup-node@([^\s#]+)", workflow) + self.assertEqual(matches, ["820762786026740c76f36085b0efc47a31fe5020"]) + self.assertIn( + "actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0", + workflow, + ) + + +if __name__ == "__main__": + unittest.main() From de72bea6000a716ebf5f15d181c3e37b900eb0f8 Mon Sep 17 00:00:00 2001 From: Daniel Strader Date: Mon, 3 Aug 2026 09:49:07 -0700 Subject: [PATCH 2/2] test: tolerate packaged workflow absence --- tests/test_workflow_pins.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_workflow_pins.py b/tests/test_workflow_pins.py index 6de4d59..55d3f9d 100644 --- a/tests/test_workflow_pins.py +++ b/tests/test_workflow_pins.py @@ -5,9 +5,10 @@ class WorkflowPinTests(unittest.TestCase): def test_setup_node_is_immutable_and_node24_compatible(self): - workflow = (Path(__file__).parents[1] / ".github" / "workflows" / "ci.yml").read_text( - encoding="utf-8" - ) + workflow_path = Path(__file__).parents[1] / ".github" / "workflows" / "ci.yml" + if not workflow_path.exists(): + self.skipTest("repository workflow is not part of the packaged artifact") + workflow = workflow_path.read_text(encoding="utf-8") matches = re.findall(r"actions/setup-node@([^\s#]+)", workflow) self.assertEqual(matches, ["820762786026740c76f36085b0efc47a31fe5020"]) self.assertIn(