From 07280c33435109875028f70f394c7b16ed844c95 Mon Sep 17 00:00:00 2001 From: oratis Date: Sat, 8 Aug 2026 18:31:43 +0800 Subject: [PATCH] ci: validate releases in the same environment as CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The v0.3.0 tag failed on a test that had been passing on main for months. Not a regression — release.yml's validate job runs `pnpm test` on a bare ubuntu-latest, while ci.yml installs bubblewrap and slirp4netns first. The deny-all-net fallback test spawns `bwrap`, so it died with ENOENT before it could assert anything. This was the first release.yml run the repo has ever had (v0.3.0 is the only tag), so the gap had never been exercised. A release gate weaker than CI is worse than no gate: it makes a green CI stop predicting a green release, and the only signal is a failed tag. The validate job now mirrors ci.yml's sandbox setup and its DC_SANDBOX_NET_TEST opt-in, with a comment on both sides noting they move together. Co-Authored-By: Claude Opus 5 --- .github/workflows/release.yml | 22 +++++++++++++++++++++- docs/RELEASING.md | 4 +++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 953726c..5f4330f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,10 +29,30 @@ jobs: node-version: '22' cache: 'pnpm' - run: pnpm install --frozen-lockfile + + # The release gate must validate in the same environment as CI. Without + # this, `pnpm test` here runs against a weaker box than ci.yml uses, so a + # green CI stops predicting a green release — which is exactly how the + # first v0.3.0 tag failed: the deny-all-net fallback test spawns `bwrap`, + # and this runner had no bubblewrap installed. + # Kept byte-for-byte in step with the "Install sandbox tools" step in + # ci.yml; change both together. + - name: Install sandbox tools + run: | + sudo apt-get update + sudo apt-get install -y bubblewrap slirp4netns curl + sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true + sudo sysctl -w net.ipv4.ip_unprivileged_port_start=53 || true + - run: pnpm typecheck - run: pnpm lint - run: pnpm format:check - - run: pnpm test + - name: Test + # Matches ci.yml: opts in the selective-allowlist integration test, which + # self-skips when bwrap/slirp4netns are absent. + env: + DC_SANDBOX_NET_TEST: '1' + run: pnpm test - run: pnpm docs:check - run: pnpm release:check diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 0474043..f8232b2 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -69,7 +69,9 @@ git push origin v0.1.3 The `release.yml` workflow fires on any `v*` tag push. Its validation and publication graph is: -1. **validate** — typecheck, lint, format, tests, docs, `pnpm release:check`, and the Playwright +1. **validate** — installs the same sandbox tooling `ci.yml` does (bubblewrap + slirp4netns; the + deny-all-net fallback test spawns `bwrap`), then typecheck, lint, format, tests, docs, + `pnpm release:check`, and the Playwright desktop protocol journey. The release gate starts the real bundled app-server twice and verifies protocol capabilities, thread persistence, thin-client boundaries, bundle budgets, and timing. 2. **publish-cli** — bumps `apps/cli/package.json` to the tag version,