diff --git a/docs/release-control/v6/internal/subsystems/deployment-installability.md b/docs/release-control/v6/internal/subsystems/deployment-installability.md index 636c9d334..36fdc6a4d 100644 --- a/docs/release-control/v6/internal/subsystems/deployment-installability.md +++ b/docs/release-control/v6/internal/subsystems/deployment-installability.md @@ -42,6 +42,14 @@ upgrade must recover those values from both split and `--key=value` service arguments and reproduce them in the generated systemd command without discarding existing explicit disk exclusions. +The accelerated exact-SHA release worker must preserve release-gate fidelity +under its own resource envelope. Bounded frontend static checks and integration +image preparation may overlap, but the full frontend test suite and the +race-enabled backend release suite must run serially. Both suites saturate the +dedicated worker when combined; concurrent execution can stretch otherwise +passing monitoring tests into load-induced failures and must not be used as a +release-latency optimization. + ## Canonical Files 1. `internal/updates/` diff --git a/scripts/release-preflight-worker.sh b/scripts/release-preflight-worker.sh index 3c91ccda8..a43195785 100755 --- a/scripts/release-preflight-worker.sh +++ b/scripts/release-preflight-worker.sh @@ -135,11 +135,14 @@ phase frontend-build npm --prefix frontend-modern run build rm -rf internal/api/frontend-modern mkdir -p internal/api/frontend-modern cp -R frontend-modern/dist internal/api/frontend-modern/ -run_frontend_quality() { +run_frontend_static_quality() { phase frontend-lint npm --prefix frontend-modern run lint phase frontend-headers npm --prefix frontend-modern run lint:headers phase frontend-duplication npm --prefix frontend-modern run lint:cpd phase frontend-types npm --prefix frontend-modern run type-check +} + +run_frontend_tests() { phase frontend-tests npm --prefix frontend-modern test } @@ -163,12 +166,12 @@ run_integration_prep() { phase mock-github-image docker build --tag pulse-mock-github:test tests/integration/mock-github-server } -# These lanes have no output dependency on one another. Running them together -# makes the critical path the slowest lane instead of their sum. +# Static frontend checks and integration preparation are bounded enough to +# overlap safely. Keep the full frontend and race-enabled backend test suites +# serial: both saturate this worker, and concurrent execution can turn healthy +# monitoring tests into load-induced release-gate failures. parallel_pids=() -run_frontend_quality & -parallel_pids+=("$!") -run_backend & +run_frontend_static_quality & parallel_pids+=("$!") run_integration_prep & parallel_pids+=("$!") @@ -185,6 +188,9 @@ while [ "$remaining" -gt 0 ]; do fi done +run_frontend_tests +run_backend + PLAYWRIGHT_VERSION="$(node -p "require('./tests/integration/node_modules/@playwright/test/package.json').version")" PLAYWRIGHT_IMAGE="mcr.microsoft.com/playwright:v${PLAYWRIGHT_VERSION}-noble" diff --git a/scripts/release_control/internal/release_preflight_test.py b/scripts/release_control/internal/release_preflight_test.py index 75eed7419..93ac45a00 100755 --- a/scripts/release_control/internal/release_preflight_test.py +++ b/scripts/release_control/internal/release_preflight_test.py @@ -217,6 +217,23 @@ class ReleasePreflightTest(unittest.TestCase): ) self.assertIn("is not reachable from a fetched origin branch", runner) + def test_worker_serializes_resource_intensive_test_suites(self) -> None: + worker = (ROOT / "scripts/release-preflight-worker.sh").read_text() + scheduling_block = re.search( + r"# Static frontend checks.*?run_backend\n", + worker, + flags=re.DOTALL, + ) + self.assertIsNotNone(scheduling_block) + block = scheduling_block.group(0) + + self.assertIn("run_frontend_static_quality &", block) + self.assertIn("run_integration_prep &", block) + self.assertNotIn("run_frontend_tests &", block) + self.assertNotIn("run_backend &", block) + self.assertLess(block.index("done\n"), block.index("run_frontend_tests\n")) + self.assertLess(block.index("run_frontend_tests\n"), block.index("run_backend\n")) + def test_api_shard_plan_is_deterministic_complete_and_disjoint(self) -> None: test_names = [ f"TestReleaseCase{index:04d}"