diff --git a/_project/scripts/ruleset_review_enforcement.py b/_project/scripts/ruleset_review_enforcement.py index a47bd2307..e9e8d10c0 100644 --- a/_project/scripts/ruleset_review_enforcement.py +++ b/_project/scripts/ruleset_review_enforcement.py @@ -119,15 +119,16 @@ def is_review_enforced(rules: list[dict[str, Any]]) -> bool: # v* tag-creation protection (tag-and-pypi-environment-admin-hardening w3) # --------------------------------------------------------------------------- -# Enforcement flag, mirroring ruleset_drift_check.DEVELOP_REVIEW_RULE_ENFORCED. -# The v* tag-creation ruleset was applied by admin on 2026-07-10 (ruleset id -# 18774756 ``v-tag-restricted``; see docs/operations/repo-admin-settings.md, -# "Tag creation restricted to release flow"), so this is flipped to True: -# ``tag_protection_findings`` for a missing/incomplete tag ruleset are now a -# BLOCKING drift finding rather than a non-blocking warning. The bypass list -# was confirmed to be the release-finalize identity only (User:57046) before -# flipping, per the runbook's "CONFIRM before enforcing" gate. -TAG_RULESET_ENFORCED = True +# WARN-until-applied flag, mirroring ruleset_drift_check.DEVELOP_REVIEW_RULE_ENFORCED. +# The v* tag-creation ruleset is a pending admin action (see +# docs/operations/repo-admin-settings.md, "Tag creation restricted to release +# flow"): the develop-PR GITHUB_TOKEN has no ``administration`` scope to POST a +# ruleset. While this is False, ``tag_protection_findings`` are surfaced as +# non-blocking warnings so the check can land BEFORE the admin acts without +# turning the (eventual) canary red. Flip to True once the runbook's live-state +# note records the applied ruleset id + conditions, exactly as +# DEVELOP_REVIEW_RULE_ENFORCED is flipped for the develop review rule. +TAG_RULESET_ENFORCED = False # The ref pattern the release flow tags with (make release-finalize pushes v*). TAG_REF_PATTERN = "refs/tags/v*" diff --git a/docs/operations/repo-admin-settings.md b/docs/operations/repo-admin-settings.md index 649809a6c..16a0e5dd6 100644 --- a/docs/operations/repo-admin-settings.md +++ b/docs/operations/repo-admin-settings.md @@ -385,21 +385,11 @@ Live-state note (fill in after applying — do not leave blank): ```text # Tag-creation ruleset live state -# checked: 2026-07-10 by: joeharris76 (admin) -# ruleset id: 18774756 enforcement: active conditions.ref_name.include: [refs/tags/v*] -# rules: [creation] bypass_actors: [User:57046 (always)] +# checked: by: +# ruleset id: enforcement: conditions.ref_name.include: <...> +# rules: bypass_actors: <...> ``` -Applied 2026-07-10: `v-tag-restricted` (id 18774756) is live and active. The -bypass list is a single `User` actor (57046, the release-finalize identity) — -confirmed to be the release identity only, not a broad Write/Admin role, which -is what `release-finalize`'s `git push origin v$(VERSION)` needs to still -succeed. With this confirmed, `TAG_RULESET_ENFORCED` in -`_project/scripts/ruleset_review_enforcement.py` is flipped to `True`, so a -future regression (ruleset deleted, made inactive, ref narrowed, creation rule -dropped, or bypass emptied) becomes a blocking drift finding instead of a -warning. - ### `pypi` environment required-reviewers gate (verify/pending admin action) `release.yml`'s `publish` job already scopes the real-PyPI publish to the diff --git a/tests/unit/release/test_ruleset_drift_review_coverage.py b/tests/unit/release/test_ruleset_drift_review_coverage.py index e6ae726be..51dfef065 100644 --- a/tests/unit/release/test_ruleset_drift_review_coverage.py +++ b/tests/unit/release/test_ruleset_drift_review_coverage.py @@ -224,35 +224,20 @@ def test_tag_protection_summary_only_payload_does_not_pass(): assert findings, "summary-only ruleset lacks a creation rule and must be flagged" -def test_tag_check_is_enforced_now_that_ruleset_is_applied(): - # The v* tag ruleset was applied 2026-07-10 (see repo-admin-settings.md - # live-state note), so the flag is flipped: a regression is now blocking. - assert _rre.TAG_RULESET_ENFORCED is True +def test_tag_check_is_warn_until_applied_by_default(): + # Mirror DEVELOP_REVIEW_RULE_ENFORCED: the flag is False until the admin + # POST lands, so the check lands non-blocking. + assert _rre.TAG_RULESET_ENFORCED is False -def test_tag_check_main_fails_when_missing_now_that_enforced(tmp_path, capsys): +def test_tag_check_main_warns_non_blocking_when_missing(tmp_path, capsys): import json as _json payload = tmp_path / "rulesets.json" payload.write_text(_json.dumps([]), encoding="utf-8") rc = _rre.main(["--rulesets-file", str(payload)]) out = capsys.readouterr().out - assert rc == 1, "missing tag ruleset must block now that TAG_RULESET_ENFORCED is True" - assert "Tag-creation ruleset - FAILED" in out - assert "target='tag'" in out - - -def test_tag_check_main_warns_non_blocking_when_flag_off(tmp_path, capsys, monkeypatch): - # Preserve coverage of the WARN-until-applied path the flag used to give by - # default: with the flag forced off, a missing ruleset is non-blocking. - import json as _json - - monkeypatch.setattr(_rre, "TAG_RULESET_ENFORCED", False) - payload = tmp_path / "rulesets.json" - payload.write_text(_json.dumps([]), encoding="utf-8") - rc = _rre.main(["--rulesets-file", str(payload)]) - out = capsys.readouterr().out - assert rc == 0 + assert rc == 0, "missing tag ruleset must be non-blocking while WARN-until-applied" assert "WARNING (non-blocking):" in out assert "target='tag'" in out @@ -373,26 +358,15 @@ def test_tag_protection_narrower_exclude_does_not_negate_coverage(): # --------------------------------------------------------------------------- -def test_tag_creation_findings_blocks_by_default_when_no_tag_ruleset_exists(): - # Live state after 2026-07-10: the v* tag ruleset is applied and - # TAG_RULESET_ENFORCED is True, so a missing target='tag' ruleset is a - # BLOCKING drift finding by default (no longer WARN-until-applied). +def test_tag_creation_findings_warns_non_blocking_when_no_tag_ruleset_exists(): + # Live state: only develop/main-release rulesets exist, no target='tag' + # ruleset yet -- must surface as a non-blocking warning by default + # (TAG_RULESET_ENFORCED is False), same WARN-until-applied pattern as the + # develop review rule. all_live = [ _live_develop_ruleset(review_count=0, code_owner_review=False), ] findings = tag_creation_findings(all_live) - assert findings and blocking_findings(findings) == findings - assert not any(f.startswith(WARNING_PREFIX) for f in findings) - assert any("target='tag'" in f for f in findings) - - -def test_tag_creation_findings_warns_when_enforcement_forced_off(): - # Preserve the pre-2026-07-10 WARN-until-applied coverage via an explicit - # enforce_tag_rule=False override. - all_live = [ - _live_develop_ruleset(review_count=0, code_owner_review=False), - ] - findings = tag_creation_findings(all_live, enforce_tag_rule=False) assert findings and all(f.startswith(WARNING_PREFIX) for f in findings) assert blocking_findings(findings) == [] assert any("target='tag'" in f for f in findings)