From 039755356ff7e506c3023232bae2bfd18f326a93 Mon Sep 17 00:00:00 2001 From: Jonathan Haas Date: Fri, 18 Sep 2026 11:23:02 -0700 Subject: [PATCH] fix(release): remove obsolete browser packaging --- .../check-release-workflow-contract.mjs | 20 ++++--- .../check-release-workflow-contract.test.mjs | 56 ++++++++++++------- .github/workflows/release.yml | 14 ----- 3 files changed, 48 insertions(+), 42 deletions(-) diff --git a/.github/workflows/check-release-workflow-contract.mjs b/.github/workflows/check-release-workflow-contract.mjs index bf2be031a..075a1ded9 100644 --- a/.github/workflows/check-release-workflow-contract.mjs +++ b/.github/workflows/check-release-workflow-contract.mjs @@ -380,6 +380,16 @@ export function validateReleaseWorkflow(source) { } if (!prepare || !binaries || !publish || !release || !canary) return failures; + for (const [name, job] of Object.entries(jobs)) { + if (job.steps.some((step) => + /(?:packages\/web\/dist|maestro-web-dist|release-web-dist)/u.test( + JSON.stringify([executableLines(step.run), step.with]), + ), + )) { + failures.push(`${name} must not require or package obsolete browser assets`); + } + } + if (!hasExactPermissions(permissions, { contents: "read" })) { failures.push("workflow default permissions must be exactly contents: read"); } @@ -604,7 +614,6 @@ export function validateReleaseWorkflow(source) { JSON.stringify([ "set -euo pipefail", `test "$(node -p "require('./package.json').version")" = "$RELEASE_VERSION"`, - "test -f packages/web/dist/index.html", "npm run check:rust-only-runtime", ]) ) { @@ -838,7 +847,6 @@ export function validateReleaseWorkflow(source) { ); for (const artifactName of [ "npm-tarball-${{ needs.prepare.outputs.release_tag }}", - "release-web-dist-${{ needs.prepare.outputs.release_tag }}", ]) { if ( !publishUploads.some( @@ -853,7 +861,7 @@ export function validateReleaseWorkflow(source) { step.uses.startsWith("actions/download-artifact@"), ); if ( - releaseDownloads.length !== 3 || + releaseDownloads.length !== 2 || !releaseDownloads.some( (step) => step.with.name === @@ -865,12 +873,6 @@ export function validateReleaseWorkflow(source) { step.with.pattern === "maestro-*" && step.with.path === "release-assets" && step.with["merge-multiple"] === "true", - ) || - !releaseDownloads.some( - (step) => - step.with.name === - "release-web-dist-${{ needs.prepare.outputs.release_tag }}" && - step.with.path === "release-assets", ) ) { failures.push("github-release must restore the exact immutable release artifacts"); diff --git a/.github/workflows/check-release-workflow-contract.test.mjs b/.github/workflows/check-release-workflow-contract.test.mjs index 3b3e8a689..4e1b25323 100644 --- a/.github/workflows/check-release-workflow-contract.test.mjs +++ b/.github/workflows/check-release-workflow-contract.test.mjs @@ -138,7 +138,6 @@ jobs: run: | set -euo pipefail test "$(node -p "require('./package.json').version")" = "$RELEASE_VERSION" - test -f packages/web/dist/index.html npm run check:rust-only-runtime - name: Publish to npm env: @@ -238,11 +237,6 @@ jobs: name: npm-tarball-\${{ needs.prepare.outputs.release_tag }} overwrite: true path: package.tgz - - uses: actions/upload-artifact@sha - with: - name: release-web-dist-\${{ needs.prepare.outputs.release_tag }} - overwrite: true - path: maestro-web-dist.tar.gz github-release: needs: [prepare, binaries, publish, post-publish-canary] runs-on: \${{ vars.PUBLIC_RELEASE_RUNNER || 'ubuntu-latest' }} @@ -262,10 +256,6 @@ jobs: pattern: maestro-* path: release-assets merge-multiple: true - - uses: actions/download-artifact@sha - with: - name: release-web-dist-\${{ needs.prepare.outputs.release_tag }} - path: release-assets - name: Verify release tag has not moved env: EXPECTED_RELEASE_SHA: \${{ needs.prepare.outputs.release_sha }} @@ -947,8 +937,8 @@ test("rejects a non-retryable or incomplete GitHub release job", () => { ); const missingArtifact = completeWorkflow.replace( - " name: release-web-dist-${{ needs.prepare.outputs.release_tag }}", - " name: wrong-web-artifact", + " name: npm-tarball-${{ needs.prepare.outputs.release_tag }}", + " name: wrong-npm-artifact", ); assert.ok( validateReleaseWorkflow(missingArtifact).some((failure) => @@ -1093,13 +1083,41 @@ test("required CI tooling lane runs the release workflow contracts", async () => ); }); -test("versioned browser asset is present in the release source tree", async () => { - const html = await readFile( - new URL("../../packages/web/dist/index.html", import.meta.url), - "utf8", - ); - assert.match(html, //iu); -}); +for (const [name, step] of [ + ["browser input requirement", " - run: test -f packages/web/dist/index.html"], + ["browser archive packaging", " - run: tar -czf maestro-web-dist.tar.gz -C packages/web/dist ."], + ["browser archive signing", " - run: sha256sum maestro-web-dist.tar.gz > SHA256SUMS"], + ["browser artifact upload", ` - uses: actions/upload-artifact@sha + with: + name: release-web-dist-${releaseSha} + path: maestro-web-dist.tar.gz`], + ["browser artifact download", ` - uses: actions/download-artifact@sha + with: + name: release-web-dist-${releaseSha} + path: release-assets`], +]) { + test(`rejects obsolete ${name}`, () => { + assert.deepEqual(validateReleaseWorkflow(completeWorkflow), []); + const workflow = completeWorkflow.replace( + " - name: Verify release tag has not moved", + `${step}\n - name: Verify release tag has not moved`, + ); + assert.ok(validateReleaseWorkflow(workflow).some((failure) => + failure.includes("obsolete browser assets"), + )); + }); +} + +for (const line of [ + ` test "$(node -p "require('./package.json').version")" = "$RELEASE_VERSION"`, + " npm run check:rust-only-runtime", +]) { + test(`rejects missing native input check: ${line.trim()}`, () => { + assert.ok(validateReleaseWorkflow(completeWorkflow.replace(line, "")).some((failure) => + failure.includes("exact native package input checks"), + )); + }); +} for (const line of [' git merge-base --is-ancestor "$release_sha" FETCH_HEAD', ' timeout 60s git fetch --no-tags origin main']) { test(`rejects missing ancestry guard: ${line.trim()}`, () => { diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 73a7b3dea..5174b6385 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -254,18 +254,9 @@ jobs: run: | set -euo pipefail test "$(node -p "require('./package.json').version")" = "$RELEASE_VERSION" - test -f packages/web/dist/index.html npm run check:rust-only-runtime - name: Materialize native npm package run: node scripts/materialize-native-package.mjs --input-dir release-binaries - - name: Package browser assets for native installs - run: tar -czf maestro-web-dist.tar.gz -C packages/web/dist . - - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a - with: - retention-days: 14 - name: release-web-dist-${{ needs.prepare.outputs.release_tag }} - overwrite: true - path: maestro-web-dist.tar.gz - id: pack run: | PACK_JSON=$(npm pack --json) @@ -465,10 +456,6 @@ jobs: pattern: maestro-* path: release-assets merge-multiple: true - - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.0 - with: - name: release-web-dist-${{ needs.prepare.outputs.release_tag }} - path: release-assets - name: Install cosign run: | set -euo pipefail @@ -514,7 +501,6 @@ jobs: maestro-darwin-x64 maestro-linux-arm64 maestro-linux-x64 - maestro-web-dist.tar.gz ) files+=(release-metadata.json version.json channel-manifest.json manifest.json) files+=(runtime-passport-maestro-*.json code-device-*.json)