mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
fix(release): prevent Playwright runner download fallback
Exact admission attempted to fetch playwright@1.63.0 when the mounted runner was unavailable. Invoke the npm-ci-installed CLI directly so missing or inaccessible dependencies fail closed without substituting a registry package. Preserve the existing container identity and gates; this does not claim to resolve the observed EACCES. Exercise shell arguments and failure propagation with a mocked Docker command. Change-source: pulse-maintainer
This commit is contained in:
@@ -2145,6 +2145,17 @@ artifact-selection behaviour.
|
||||
secrets, and seed hosted approvals through a single explicit tenant runtime
|
||||
restart when a release proof needs transactionally visible approval state.
|
||||
|
||||
Browser execution must invoke the npm-ci-installed
|
||||
`/work/node_modules/@playwright/test/cli.js` directly with Node inside the
|
||||
selected Playwright image. Missing or inaccessible mounted dependencies
|
||||
must fail admission rather than trigger an npx registry download of a
|
||||
substitute runner. Preserve the existing container UID/GID, mount, image
|
||||
version selection and exit status. The executed-shell fixture in
|
||||
`scripts/release_control/internal/release_preflight_test.py` verifies the
|
||||
runner path, argument quoting, container identity and failure propagation
|
||||
with mocked Docker; it is not browser qualification or proof that the
|
||||
retained spawn-sh EACCES failure has been repaired.
|
||||
|
||||
## Forbidden Paths
|
||||
|
||||
1. Leaving deployment bootstrap, installer, or update-runtime files unowned under broad monitoring or generic API ownership
|
||||
|
||||
@@ -257,6 +257,9 @@ else
|
||||
--tag pulse:test \
|
||||
.
|
||||
fi
|
||||
# Use only the npm-ci-installed runner. npx may fetch a different version when
|
||||
# the mounted dependency tree is missing or inaccessible, masking the actual
|
||||
# admission failure and breaking parity with the selected browser image.
|
||||
run_playwright() {
|
||||
docker run --rm \
|
||||
--network host \
|
||||
@@ -269,7 +272,7 @@ run_playwright() {
|
||||
--volume "$REPOSITORY_DIR/tests/integration:/work" \
|
||||
--workdir /work \
|
||||
"$PLAYWRIGHT_IMAGE" \
|
||||
npx playwright test "$@"
|
||||
node /work/node_modules/@playwright/test/cli.js test "$@"
|
||||
}
|
||||
|
||||
run_rehearsal_smoke() {
|
||||
|
||||
@@ -264,6 +264,39 @@ class ReleasePreflightTest(unittest.TestCase):
|
||||
self.assertIn('--env "PLAYWRIGHT_BASE_URL=${PULSE_E2E_BASE_URL}"', worker)
|
||||
self.assertNotIn("localhost:7655", worker)
|
||||
|
||||
def test_browser_uses_installed_runner_and_preserves_failure(self) -> None:
|
||||
worker = (ROOT / "scripts/release-preflight-worker.sh").read_text()
|
||||
function = re.search(
|
||||
r"run_playwright\(\) \{.*?\n\}", worker, flags=re.DOTALL
|
||||
).group(0)
|
||||
# Exercise the real shell function without starting Docker or a browser.
|
||||
# A failed container must propagate, not become a successful admission.
|
||||
for status in (0, 13):
|
||||
with self.subTest(status=status):
|
||||
result = subprocess.run(
|
||||
["bash", "-c", """
|
||||
docker() { printf '%s\n' "$@"; return """ + str(status) + """; }
|
||||
REPOSITORY_DIR='/tmp/worker with spaces/repo'
|
||||
PLAYWRIGHT_IMAGE='mcr.microsoft.com/playwright:v1.61.1-noble'
|
||||
PULSE_E2E_BASE_URL='http://localhost:27655'
|
||||
""" + function + """
|
||||
run_playwright 'tests/a test.spec.ts' --project=chromium
|
||||
"""],
|
||||
text=True, capture_output=True, check=False,
|
||||
)
|
||||
self.assertEqual(result.returncode, status, result.stderr)
|
||||
args = result.stdout.splitlines()
|
||||
self.assertEqual(args[-5:], [
|
||||
"node", "/work/node_modules/@playwright/test/cli.js",
|
||||
"test", "tests/a test.spec.ts", "--project=chromium",
|
||||
])
|
||||
self.assertNotIn("npx", args)
|
||||
self.assertEqual(args[args.index("--volume") + 1],
|
||||
"/tmp/worker with spaces/repo/tests/integration:/work")
|
||||
self.assertEqual(args[args.index("--user") + 1],
|
||||
f"{os.getuid()}:{os.getgid()}")
|
||||
self.assertIn("mcr.microsoft.com/playwright:v1.61.1-noble", args)
|
||||
|
||||
def test_worker_serializes_resource_intensive_test_suites(self) -> None:
|
||||
worker = (ROOT / "scripts/release-preflight-worker.sh").read_text()
|
||||
scheduling_block = re.search(
|
||||
|
||||
Reference in New Issue
Block a user