Skip to content

Commit 4718569

Browse files
CLI release-plan recovery cannot create a previously absent exact tag with its GitHub Actions token.
1 parent 5fb4f0c commit 4718569

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

scripts/ci/cli_release_verifier_contract.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,3 +250,42 @@ def run(arguments: list[str], **_kwargs: object) -> object:
250250
self.assertEqual(len(self.recovery.CLI_ASSETS), len(attestations))
251251
self.assertEqual("php", calls[-1][0])
252252

253+
def test_phar_execution_receives_no_workflow_credentials_or_other_secrets(self) -> None:
254+
version = "0.1.94"
255+
commit = "36bde75882980e834854a145c9ad0f61ceec4659"
256+
phar_environment: dict[object, object] | None = None
257+
258+
def run(arguments: list[str], **kwargs: object) -> object:
259+
nonlocal phar_environment
260+
if Path(arguments[0]).name == "php":
261+
environment = kwargs.get("env")
262+
if isinstance(environment, dict):
263+
phar_environment = environment
264+
return mock.Mock(
265+
returncode=0,
266+
stdout=f"dw {version} (commit {commit[:12]}, built 2026-07-20)",
267+
stderr="",
268+
)
269+
return mock.Mock(returncode=0, stdout="verified", stderr="")
270+
271+
inherited_secrets = {
272+
"GITHUB_TOKEN": "github-token",
273+
"GH_TOKEN": "gh-token",
274+
"AWS_SECRET_ACCESS_KEY": "cloud-secret",
275+
"DATABASE_URL": "postgres://user:password@example.invalid/database",
276+
}
277+
allowed_path = "/opt/php/bin:/usr/bin"
278+
with (
279+
mock.patch.dict(self.recovery.os.environ, {**inherited_secrets, "PATH": allowed_path}, clear=False),
280+
mock.patch.object(self.recovery.shutil, "which", return_value="/usr/bin/tool"),
281+
mock.patch.object(self.recovery.subprocess, "run", side_effect=run),
282+
):
283+
self.recovery.verify_cli(
284+
self.release_client(version),
285+
self.recovery.COMPONENTS["cli"],
286+
version,
287+
commit,
288+
)
289+
290+
self.assertEqual({"PATH": allowed_path}, phar_environment)
291+
self.assertTrue(inherited_secrets.keys().isdisjoint(phar_environment or {}))

scripts/ci/component-release-recovery.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1196,7 +1196,11 @@ def verify_cli(client: PublicClient, component: Component, version: str, commit:
11961196
if shutil.which("php") is None:
11971197
raise RecoveryError("PHP is required to verify CLI release source metadata", "registry-publication")
11981198
phar_version = subprocess.run(
1199-
["php", str(directory / "dw.phar"), "--version"], check=False, text=True, capture_output=True
1199+
["php", str(directory / "dw.phar"), "--version"],
1200+
check=False,
1201+
text=True,
1202+
capture_output=True,
1203+
env={"PATH": os.environ.get("PATH", os.defpath)},
12001204
)
12011205
expected_identity = f"{version} (commit {commit[:12]},"
12021206
if phar_version.returncode or expected_identity not in phar_version.stdout:

0 commit comments

Comments
 (0)