From 150c59daa8581b40fd926e48533bb5a8d762ecd2 Mon Sep 17 00:00:00 2001 From: Durable Workflow Date: Tue, 1 Sep 2026 05:43:11 +0000 Subject: [PATCH] Allow always-running action policy preflights --- scripts/qualification_policy.py | 7 +++---- tests/test_qualification_policy.py | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/scripts/qualification_policy.py b/scripts/qualification_policy.py index abe70ef..a277b7a 100644 --- a/scripts/qualification_policy.py +++ b/scripts/qualification_policy.py @@ -695,10 +695,10 @@ def _verify_action_policy_preflight( preflight = jobs.get("action-policy") if not isinstance(preflight, dict): raise PolicyError(f"{label} has no central action policy preflight job") + accepted_conditions = {"", "github.server_url == 'https://github.com'"} if ( preflight.get("name") != "Central action policy preflight" - or _condition_without_expression_wrapper(preflight.get("if", "")) - != "github.server_url == 'https://github.com'" + or _condition_without_expression_wrapper(preflight.get("if", "")) not in accepted_conditions or preflight.get("runs-on") != "ubuntu-latest" or preflight.get("timeout-minutes") != "5" or preflight.get("needs") is not None @@ -751,13 +751,12 @@ def _verify_action_policy_preflight( if not isinstance(condition, str) or "always()" not in _condition_without_expression_wrapper(condition): raise PolicyError(f"{label} required check must run after a failed central action policy preflight") reviewed_gate = { - "if": "${{ github.server_url == 'https://github.com' }}", "env": {"ACTION_POLICY_RESULT": "${{ needs.action-policy.result }}"}, "run": 'test "$ACTION_POLICY_RESULT" = success', } if not any( isinstance(step, dict) - and step.get("if") == reviewed_gate["if"] + and _condition_without_expression_wrapper(step.get("if", "")) in accepted_conditions and step.get("env") == reviewed_gate["env"] and _normalized_shell(step.get("run")) == reviewed_gate["run"] for step in gate.get("steps") or [] diff --git a/tests/test_qualification_policy.py b/tests/test_qualification_policy.py index 07f806f..15d8999 100644 --- a/tests/test_qualification_policy.py +++ b/tests/test_qualification_policy.py @@ -1532,6 +1532,23 @@ def test_required_check_cannot_disconnect_the_reviewed_preflight(self) -> None: with self.assertRaisesRegex(PolicyError, "does not depend on the central action policy"): verify_workflow_source("cli", "main", workflow, disconnected) + def test_action_policy_preflight_may_run_unconditionally(self) -> None: + policy = policy_fixture() + workflow = policy["targets"]["waterline"]["workflows"][0] + source = FakeGitHubClient(policy).bytes( + "/repos/durable-workflow/waterline/contents/.github/workflows/php.yml?ref=" + "a" * 40 + ).decode() + source = source.replace( + " if: ${{ github.server_url == 'https://github.com' }}\n", + "", + 1, + ).replace( + " if: ${{ github.server_url == 'https://github.com' }}\n", + "", + 1, + ) + verify_workflow_source("waterline", "v2", workflow, source) + def test_each_product_preflight_rejects_an_unapproved_immutable_action_pin(self) -> None: policy = policy_fixture() source = self.trusted_pull_request_source().replace(CHECKOUT_PIN, "f" * 40)