From c00318df891aec5fd43cebddfd33026178f8b4d8 Mon Sep 17 00:00:00 2001 From: SarthakWade Date: Wed, 12 Aug 2026 18:56:10 +0530 Subject: [PATCH 1/2] ci: add release packaging dry runs --- .github/workflows/release.yml | 57 ++++++++++++++++++++++++++++++++++- CHANGELOG.md | 2 ++ README.md | 5 +++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3d57ba5..ffc908b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,6 +4,21 @@ on: push: tags: - "v*" + pull_request: + paths: + - ".github/workflows/release.yml" + - "apps/headless/Dockerfile.linux" + - "apps/headless/build.sh" + - "apps/headless/build-linux.sh" + - "apps/headless/install-linux.sh" + - "apps/headless/Package.swift" + workflow_dispatch: + inputs: + dry_run: + description: Build and verify release packages without publishing + required: true + default: true + type: boolean permissions: contents: read @@ -13,9 +28,28 @@ jobs: runs-on: ubuntu-latest outputs: version: ${{ steps.version.outputs.version }} + publish: ${{ steps.version.outputs.publish }} steps: - id: version - run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + env: + DRY_RUN: ${{ inputs.dry_run }} + run: | + set -eu + if [ "$GITHUB_EVENT_NAME" = "push" ]; then + case "$GITHUB_REF" in + refs/tags/v*) ;; + *) echo "release publishing requires a v* tag" >&2; exit 64 ;; + esac + echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" + echo "publish=true" >> "$GITHUB_OUTPUT" + else + if [ "$GITHUB_EVENT_NAME" = "workflow_dispatch" ] && [ "$DRY_RUN" != "true" ]; then + echo "manual release runs must use dry_run=true; publish by pushing a v* tag" >&2 + exit 64 + fi + echo "version=0.0.${GITHUB_RUN_NUMBER}" >> "$GITHUB_OUTPUT" + echo "publish=false" >> "$GITHUB_OUTPUT" + fi macos: needs: version @@ -36,8 +70,14 @@ jobs: env: VERSION: ${{ needs.version.outputs.version }} run: | + set -eu cd apps/headless ditto -c -k --keepParent Headless.app "Headless-${VERSION}-macos.zip" + test -s "Headless-${VERSION}-macos.zip" + unzip -t "Headless-${VERSION}-macos.zip" + unzip -Z1 "Headless-${VERSION}-macos.zip" | grep -qx 'Headless.app/Contents/MacOS/Headless' + unzip -Z1 "Headless-${VERSION}-macos.zip" | grep -qx 'Headless.app/Contents/Resources/bin/headless' + unzip -Z1 "Headless-${VERSION}-macos.zip" | grep -qx 'Headless.app/Contents/Resources/bin/headless-mcp' - uses: actions/upload-artifact@v7 with: name: macos @@ -56,8 +96,15 @@ jobs: env: VERSION: ${{ needs.version.outputs.version }} run: | + set -eu cp apps/headless/build/headless-linux-amd64.tar.gz \ "apps/headless/build/headless-${VERSION}-linux-amd64.tar.gz" + archive="apps/headless/build/headless-${VERSION}-linux-amd64.tar.gz" + test -s "$archive" + tar -tzf "$archive" > archive-contents.txt + for expected in headless headless-host headless-mcp install-linux.sh Headless_HeadlessProtocol.resources/AgentRuntime.js; do + grep -qx "$expected" archive-contents.txt + done - uses: actions/upload-artifact@v7 with: name: linux-amd64 @@ -76,8 +123,15 @@ jobs: env: VERSION: ${{ needs.version.outputs.version }} run: | + set -eu cp apps/headless/build/headless-linux-arm64.tar.gz \ "apps/headless/build/headless-${VERSION}-linux-arm64.tar.gz" + archive="apps/headless/build/headless-${VERSION}-linux-arm64.tar.gz" + test -s "$archive" + tar -tzf "$archive" > archive-contents.txt + for expected in headless headless-host headless-mcp install-linux.sh Headless_HeadlessProtocol.resources/AgentRuntime.js; do + grep -qx "$expected" archive-contents.txt + done - uses: actions/upload-artifact@v7 with: name: linux-arm64 @@ -85,6 +139,7 @@ jobs: publish: needs: [version, macos, linux-amd64, linux-arm64] + if: needs.version.outputs.publish == 'true' runs-on: ubuntu-latest permissions: contents: write diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a6f257..7b4599f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,8 @@ Cutting that release is tracked in ### Changed +- The release workflow can now exercise and verify every package without + publishing, manually or on pull requests that change packaging inputs. - macOS WebKit and Linux Chromium now share one `HostCore` dispatcher and lifecycle implementation behind small engine adapters, eliminating the two divergent copies of flow, capture, recording, report, trace, and error logic. diff --git a/README.md b/README.md index 870c5eb..2826a35 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,11 @@ Assets: macOS `Headless.app` zip, Linux amd64/arm64 tarballs. See the Actions `Release` workflow and the release notes on each tag for install caveats (Gatekeeper; Linux Chromium/FFmpeg). +The `Release` workflow can also be run manually with `dry_run` enabled. That +builds, verifies, and uploads all three workflow artifacts without creating a +GitHub Release. Pull requests that change release packaging run the same dry +run automatically. + ## Tests ```sh From 2aa9411e59a3482e6e9ff6678bd21a3587349fd3 Mon Sep 17 00:00:00 2001 From: SarthakWade Date: Wed, 12 Aug 2026 19:57:25 +0530 Subject: [PATCH 2/2] ci: harden release dry-run gate --- .github/workflows/release.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ffc908b..a295279 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,6 +7,7 @@ on: pull_request: paths: - ".github/workflows/release.yml" + - ".github/scripts/**" - "apps/headless/Dockerfile.linux" - "apps/headless/build.sh" - "apps/headless/build-linux.sh" @@ -139,7 +140,10 @@ jobs: publish: needs: [version, macos, linux-amd64, linux-arm64] - if: needs.version.outputs.publish == 'true' + if: >- + github.event_name == 'push' && + startsWith(github.ref, 'refs/tags/v') && + needs.version.outputs.publish == 'true' runs-on: ubuntu-latest permissions: contents: write