Merge candidate 20260911T204017Z-core-runtime

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot] 2026-09-11 21:47:11 +01:00
commit 34ba9a5ed9
3 changed files with 85 additions and 0 deletions

View file

@ -993,12 +993,14 @@ jobs:
RELEASE_ID=$(echo "$EXISTING_RELEASE" | jq -r '.id // empty')
RELEASE_URL=$(echo "$EXISTING_RELEASE" | jq -r '.html_url // empty')
RELEASE_IS_DRAFT=$(echo "$EXISTING_RELEASE" | jq -r '.draft // false')
RELEASE_TARGET_COMMITISH=$(echo "$EXISTING_RELEASE" | jq -r '.target_commitish // empty')
RELEASE_PUBLISHED_AT=$(echo "$EXISTING_RELEASE" | jq -r '.published_at // empty')
RELEASE_ACTIVATION_COMMITTED=$(echo "$EXISTING_RELEASE" | jq -r 'any(.assets[]?; .name == "release-activation.json")')
python3 scripts/write_github_output.py release_id "${RELEASE_ID}"
python3 scripts/write_github_output.py release_url "${RELEASE_URL}"
python3 scripts/write_github_output.py release_is_draft "${RELEASE_IS_DRAFT}"
python3 scripts/write_github_output.py release_target_commitish "${RELEASE_TARGET_COMMITISH}"
python3 scripts/write_github_output.py release_published_at "${RELEASE_PUBLISHED_AT}"
python3 scripts/write_github_output.py release_activation_committed "${RELEASE_ACTIVATION_COMMITTED}"
@ -1032,6 +1034,7 @@ jobs:
WORKFLOW_OUTPUT_6: ${{ steps.existing_release.outputs.release_is_draft }}
WORKFLOW_OUTPUT_7: ${{ steps.existing_release.outputs.release_published_at }}
WORKFLOW_OUTPUT_8: ${{ steps.existing_release.outputs.release_activation_committed }}
WORKFLOW_OUTPUT_10: ${{ steps.existing_release.outputs.release_target_commitish }}
WORKFLOW_OUTPUT_9: ${{ needs.prepare.outputs.version }}
run: |
set -euo pipefail
@ -1045,6 +1048,7 @@ jobs:
IS_DRAFT="${WORKFLOW_OUTPUT_6}"
PUBLISHED_AT="${WORKFLOW_OUTPUT_7}"
ACTIVATION_COMMITTED="${WORKFLOW_OUTPUT_8}"
PREVIOUS_TARGET_COMMITISH="${WORKFLOW_OUTPUT_10}"
RELEASE_PAYLOAD=$(mktemp)
RELEASE_JSON_FILE=$(mktemp)
ACTUAL_BODY_FILE=$(mktemp)
@ -1068,6 +1072,13 @@ jobs:
if [ -n "$RELEASE_ID" ]; then
if [ "$IS_DRAFT" = "true" ] && [ "$ACTIVATION_COMMITTED" != "true" ]; then
if [ -n "$PUBLISHED_AT" ]; then
# Deleting a public tag does not make its version reusable.
# Only an exact retained commit proves same-identity recovery;
# a missing target or moving branch name is not such proof.
if [ "$PREVIOUS_TARGET_COMMITISH" != "$HEAD_SHA" ]; then
echo "::error::Previously published release ${TAG} identifies ${PREVIOUS_TARGET_COMMITISH:-unknown}, not HEAD (${HEAD_SHA}); use a new version."
exit 1
fi
echo "Resuming quarantined draft release for ${TAG}; GitHub retained historical published_at=${PUBLISHED_AT}."
fi
echo "Updating existing draft release for ${TAG}"

View file

@ -5452,3 +5452,20 @@ must not alter permissions, environments, source identity, rollback, signing
backend selection or release qualification. Local contract success does not
establish hosted action execution, signature acceptance, image publication or
production deployment.
### Quarantined release identity after tag deletion
Draft preparation retains the existing release's target_commitish. A historical
published_at is evidence that the version was exposed even if its Git tag is
now absent. Before PATCH, such a draft must retain an exact target equal to the
admitted checkout SHA; changed, absent and branch-name targets fail closed.
Same-SHA quarantined recovery remains available unless the activation marker
has committed the packet. Never-published private drafts remain replaceable.
This guard complements, rather than replaces, PR2056's immutable public-tag
check and qualification-first Git, Docker and Helm writers.
The executable release policy regression runs the actual absent-tag check and
draft shell with recording fake APIs. It must reject changed/unknown/branch
historical targets before any API mutation, admit same-identity recovery and
private replacement, and preserve activated/published refusals. This is local
workflow proof, not publication or installed acceptance.

View file

@ -303,6 +303,63 @@ STAGED_GOVERNANCE_INPUT_ERRORS = (
class ReleasePromotionPolicyTest(unittest.TestCase):
def test_quarantined_draft_identity_before_patch(self):
workflow = yaml.safe_load(read(".github/workflows/create-release.yml"))
steps = workflow["jobs"]["create_release"]["steps"]
create = next(step for step in steps if step.get("name") == "Create draft release")
locate = next(step for step in steps if step.get("id") == "existing_release")
self.assertIn(".target_commitish // empty", locate["run"])
self.assertIn('write_github_output.py release_target_commitish "${RELEASE_TARGET_COMMITISH}"',
locate["run"])
self.assertEqual(create["env"]["WORKFLOW_OUTPUT_10"],
"${{ steps.existing_release.outputs.release_target_commitish }}")
check = next(step for step in steps
if step.get("name") == "Check existing public tag without changing it")
self.assertLess(steps.index(check), steps.index(create))
script = (check["run"] + "\n" + create["run"]).replace(
"${{ github.repository }}", "fixture/pulse")
# Execute the actual draft shell with an absent-tag fake Git and a
# recording API sentinel. No network or public writer is available.
head = "a" * 40
cases = [
("different", "b" * 40, "2026-09-01T00:00:00Z", "true", "false", False),
("unknown", "", "2026-09-01T00:00:00Z", "true", "false", False),
("branch", "main", "2026-09-01T00:00:00Z", "true", "false", False),
("same", head, "2026-09-01T00:00:00Z", "true", "false", True),
("private", "b" * 40, "", "true", "false", True),
("activated", head, "2026-09-01T00:00:00Z", "true", "true", False),
("published", head, "2026-09-01T00:00:00Z", "false", "false", False),
]
for label, target, published, draft, activated, allowed in cases:
with self.subTest(label=label), tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / "notes").write_text("Fixture notes")
(root / "git").write_text(
"#!/bin/bash\n"
'if [ "$*" = "rev-parse HEAD" ]; then echo ' + head + '; exit 0; fi\n'
'if [ "$1" = "ls-remote" ]; then exit 0; fi\nexit 98\n'
)
(root / "gh").write_text(
"#!/bin/bash\nprintf '%s\\n' \"$*\" >> \"$CALLS\"\nexit 73\n"
)
for name in ("git", "gh"):
(root / name).chmod(0o755)
env = dict(os.environ, PATH=f"{root}:/usr/bin:/bin", TMPDIR=tmp,
CALLS=str(root / "calls"), TAG="v6.4.4-beta.4")
values = ["v6.4.4-beta.4", str(root / "notes"), "true", "123",
"https://example.invalid/release", draft, published, activated,
"6.4.4-beta.4", target]
env.update({f"WORKFLOW_OUTPUT_{i}": v for i, v in enumerate(values, 1)})
result = subprocess.run(["bash", "-euo", "pipefail", "-c", script],
cwd=root, env=env, text=True, capture_output=True)
calls = (root / "calls").read_text() if (root / "calls").exists() else ""
if allowed:
self.assertEqual(result.returncode, 73, result.stdout + result.stderr)
self.assertIn("-X PATCH", calls)
else:
self.assertEqual(result.returncode, 1, result.stdout + result.stderr)
self.assertEqual(calls, "", "refusal must precede API mutation")
def test_reviewed_action_manifests_cover_all_release_consumers(self) -> None:
# Snapshot is derived from each immutable upstream action.yml, not from
# our consumers: unknown inputs therefore fail rather than being blessed.