From 517c523bc97bfafd208999ca56b71490a920e100 Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Thu, 29 Oct 2026 01:16:38 +1100 Subject: [PATCH] ci(release): publish a signed Intel macOS DMG Build the macOS preview job as an aarch64/x64 matrix. The Intel leg cross-compiles x86_64-apple-darwin on the Apple Silicon runner with the pinned Rust release from rustup, since Hermit's Rust ships only the host standard library. Both legs are signed, notarized and verified, and the preview feed gains a darwin-x86_64 updater entry. Co-authored-by: Jitter <2b2e6415e748c35180847a37aadae06a11e30dddc76b784e7fd9354c4eb42e7a@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 Signed-off-by: Matt Toohey --- .github/workflows/release.yml | 72 +++++++++++++------ README.md | 7 +- docs/releases.md | 18 ++--- scripts/preview-feed.mjs | 1 + scripts/prune-preview-releases.mjs | 1 + tests/integration/desktop-release.test.mjs | 12 +++- tests/integration/packaging.test.mjs | 32 ++++++--- tests/integration/preview-feed.test.mjs | 4 +- .../prune-preview-releases.test.mjs | 1 + 9 files changed, 103 insertions(+), 45 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b8e9aa14ee..17d8047358 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -31,8 +31,13 @@ concurrency: jobs: build: if: github.repository == 'block/buzz-app' && !inputs.candidates && !inputs.promote_version - name: Build, sign, and notarize + name: Build, sign, and notarize (${{ matrix.arch }}) runs-on: macos-latest + strategy: + matrix: + include: + - { target: aarch64-apple-darwin, arch: aarch64, lipo: arm64 } + - { target: x86_64-apple-darwin, arch: x64, lipo: x86_64 } timeout-minutes: 120 permissions: contents: read @@ -42,6 +47,7 @@ jobs: env: CI: "true" CARGO_TERM_COLOR: always + TARGET: ${{ matrix.target }} steps: - name: Require main and signing configuration env: @@ -59,9 +65,18 @@ jobs: with: persist-credentials: false - uses: ./.github/actions/setup + # Hermit's Rust ships only the runner's (Apple Silicon) standard library. + # Cross-compile with the same pinned release from rustup, as Windows does. + - name: Select pinned Rust with the Intel standard library + if: matrix.arch == 'x64' + run: | + version=$(rustc --version | cut -d' ' -f2) + rustup toolchain install "$version" --profile minimal --target "$TARGET" + echo "RUSTUP_TOOLCHAIN=$version" >> "$GITHUB_ENV" + echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: - key: macos-prerelease + key: macos-prerelease-${{ matrix.arch }} cache-all-crates: true - name: Set preview version @@ -85,14 +100,16 @@ jobs: env: TAURI_BUNDLER_DMG_IGNORE_CI: "true" run: | - rm -rf target/release/bundle - pnpm tauri build --ci --no-sign --bundles dmg --config "$RUNNER_TEMP/release.json" -- --locked + # Fail fast if the selected Rust lacks this target's standard library. + test -d "$(rustc --print target-libdir --target "$TARGET")" || { echo "::error::Rust has no $TARGET standard library"; exit 1; } + rm -rf "target/$TARGET/release/bundle" + pnpm tauri build --ci --no-sign --bundles dmg --target "$TARGET" --config "$RUNNER_TEMP/release.json" -- --locked - name: Locate unsigned DMG id: unsigned run: | shopt -s nullglob - dmgs=(target/release/bundle/dmg/*.dmg) + dmgs=("target/$TARGET/release/bundle/dmg/"*.dmg) test "${#dmgs[@]}" -eq 1 || { echo '::error::Expected exactly one DMG'; exit 1; } echo "path=${dmgs[0]}" >> "$GITHUB_OUTPUT" @@ -104,11 +121,12 @@ jobs: codesign-s3-bucket: ${{ secrets.CODESIGN_S3_BUCKET }} unsigned-artifact-path: ${{ steps.unsigned.outputs.path }} entitlements-plist-path: src-tauri/entitlements.plist - artifact-name: buzz-app-${{ github.run_id }}-${{ github.run_attempt }}-arm64 + artifact-name: buzz-app-${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.lipo }} - name: Verify release DMG env: SIGNED_DMG: ${{ steps.codesign.outputs.signed-dmg-path }} + LIPO_ARCH: ${{ matrix.lipo }} run: | app_dir=$(mktemp -d "$RUNNER_TEMP/verify-release.XXXXXX") hdiutil attach "$SIGNED_DMG" -readonly -nobrowse -mountpoint "$app_dir" >/dev/null @@ -118,17 +136,22 @@ jobs: -R '=anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and certificate leaf[subject.OU] = EYF346PHUG' "$app" spctl --assess --type execute --verbose=4 "$app" xcrun stapler validate "$app" + test "$(lipo -archs "$app/Contents/MacOS/Buzz")" = "$LIPO_ARCH" || { echo "::error::Buzz is not $LIPO_ARCH"; exit 1; } + # Promotion inspects only the Apple Silicon executable, so check each leg here. + for value in "$BUZZ_UPDATER_PUBLIC_KEY" "$BUZZ_UPDATER_ENDPOINT"; do + grep -aqF "$value" "$app/Contents/MacOS/Buzz" || { echo '::error::Buzz does not embed the updater configuration'; exit 1; } + done test -n "$(/usr/libexec/PlistBuddy -c 'Print :NSMicrophoneUsageDescription' "$app/Contents/Info.plist")" codesign --display --entitlements :- "$app" > "$RUNNER_TEMP/signed-entitlements.plist" test "$(/usr/libexec/PlistBuddy -c 'Print :com.apple.security.device.audio-input' "$RUNNER_TEMP/signed-entitlements.plist")" = true || { echo '::error::Signed app is missing microphone entitlement'; exit 1; } goose="$app/Contents/Resources/bin/goose-acp" test -x "$goose" || { echo '::error::Signed app is missing goose-acp'; exit 1; } - test "$(lipo -archs "$goose")" = arm64 || { echo '::error::goose-acp is not arm64'; exit 1; } + test "$(lipo -archs "$goose")" = "$LIPO_ARCH" || { echo "::error::goose-acp is not $LIPO_ARCH"; exit 1; } codesign --verify --strict --verbose=2 \ -R '=anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and certificate leaf[subject.OU] = EYF346PHUG' "$goose" command="$app/Contents/Resources/bin/buzz-agent-command" test -x "$command" || { echo '::error::Signed app is missing buzz-agent-command'; exit 1; } - test "$(lipo -archs "$command")" = arm64 || { echo '::error::buzz-agent-command is not arm64'; exit 1; } + test "$(lipo -archs "$command")" = "$LIPO_ARCH" || { echo "::error::buzz-agent-command is not $LIPO_ARCH"; exit 1; } codesign --verify --strict --verbose=2 \ -R '=anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[subject.OU] = EYF346PHUG' "$command" @@ -136,12 +159,13 @@ jobs: env: SIGNED_DMG: ${{ steps.codesign.outputs.signed-dmg-path }} VERSION: ${{ steps.version.outputs.version }} + ARCH: ${{ matrix.arch }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} run: | set -euo pipefail mkdir release-assets - cp "$SIGNED_DMG" "release-assets/Buzz_${VERSION}_aarch64.dmg" + cp "$SIGNED_DMG" "release-assets/Buzz_${VERSION}_${ARCH}.dmg" # Package the verified, Apple-signed and stapled app from the release DMG. app_dir=$(mktemp -d "$RUNNER_TEMP/updater-app.XXXXXX") @@ -149,7 +173,7 @@ jobs: trap 'hdiutil detach "$app_dir" >/dev/null' EXIT app="$app_dir/Buzz.app" test -d "$app" || { echo '::error::Signed DMG contains no app'; exit 1; } - archive="$PWD/release-assets/Buzz_${VERSION}_aarch64.app.tar.gz" + archive="$PWD/release-assets/Buzz_${VERSION}_${ARCH}.app.tar.gz" # ditto copies the complete signed bundle (including symlinks and metadata). staged_app=$(mktemp -d "$RUNNER_TEMP/updater-staging.XXXXXX") ditto "$app" "$staged_app/Buzz.app" @@ -161,7 +185,7 @@ jobs: - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: - name: signed-macos-release + name: signed-macos-${{ matrix.arch }} path: release-assets/ if-no-files-found: error retention-days: 7 @@ -176,8 +200,12 @@ jobs: steps: - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: signed-macos-release - path: build-assets/macos + name: signed-macos-aarch64 + path: build-assets/macos-aarch64 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + name: signed-macos-x64 + path: build-assets/macos-x64 - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: windows-x64-candidate @@ -196,15 +224,17 @@ jobs: SOURCE_SHA: ${{ github.sha }} run: | set -euo pipefail - for platform in macos windows linux; do + for platform in macos-aarch64 macos-x64 windows linux; do (cd "build-assets/$platform" && sha256sum --check SHA256SUMS) done # Exact names also reject mixed versions after a partial-job rerun. # Rerun all jobs so every platform uses the same run attempt/version. mkdir release-assets - cp "build-assets/macos/Buzz_${VERSION}_aarch64.dmg" release-assets/ - cp "build-assets/macos/Buzz_${VERSION}_aarch64.app.tar.gz" release-assets/ - cp "build-assets/macos/Buzz_${VERSION}_aarch64.app.tar.gz.sig" release-assets/ + for arch in aarch64 x64; do + for asset in dmg app.tar.gz app.tar.gz.sig; do + cp "build-assets/macos-$arch/Buzz_${VERSION}_$arch.$asset" release-assets/ + done + done cp "build-assets/windows/Buzz_${VERSION}_x64_unsigned.exe" release-assets/ cp "build-assets/linux/Buzz_${VERSION}_amd64.deb" release-assets/ cp "build-assets/linux/Buzz_${VERSION}_x86_64.AppImage" release-assets/ @@ -223,7 +253,7 @@ jobs: gh release create "v$VERSION" release-assets/* \ --target "$SOURCE_SHA" --prerelease --latest=false \ --title "Buzz $VERSION (desktop preview)" \ - --notes "Desktop preview from commit $SOURCE_SHA, built by Actions run $GITHUB_RUN_ID. Includes Apple Silicon macOS (signed and notarized), Windows x64 (unsigned NSIS installer), and Linux x64 (Ubuntu 24.04 deb and AppImage). Windows/Linux still require desktop acceptance. Updater-enabled installs update from the preview feed." + --notes "Desktop preview from commit $SOURCE_SHA, built by Actions run $GITHUB_RUN_ID. Includes Apple Silicon and Intel macOS (signed and notarized), Windows x64 (unsigned NSIS installer), and Linux x64 (Ubuntu 24.04 deb and AppImage). Windows/Linux still require desktop acceptance. Updater-enabled installs update from the preview feed." promote_preview: name: Promote verified preview @@ -253,13 +283,11 @@ jobs: archive="Buzz_${VERSION}_aarch64.app.tar.gz" mkdir -p "$RUNNER_TEMP/candidate" "$RUNNER_TEMP/current" "$RUNNER_TEMP/served" gh release view "v$VERSION" --json isPrerelease --jq .isPrerelease | grep -qx true - for asset in "$archive" "Buzz_${VERSION}_x64_unsigned.exe" "Buzz_${VERSION}_amd64.deb" "Buzz_${VERSION}_x86_64.AppImage"; do + for asset in "$archive" "Buzz_${VERSION}_x64.app.tar.gz" "Buzz_${VERSION}_x64_unsigned.exe" "Buzz_${VERSION}_amd64.deb" "Buzz_${VERSION}_x86_64.AppImage"; do gh release download "v$VERSION" --pattern "$asset" --pattern "$asset.sig" --dir "$RUNNER_TEMP/candidate" [[ -s "$RUNNER_TEMP/candidate/$asset" && -s "$RUNNER_TEMP/candidate/$asset.sig" ]] done - # Previews built before the executable became `Buzz` stay re-promotable until pruned. - executable=$(tar -tzf "$RUNNER_TEMP/candidate/$archive" | grep -xE 'Buzz\.app/Contents/MacOS/(Buzz|buzz-foundation)') - tar -xOzf "$RUNNER_TEMP/candidate/$archive" "$executable" > "$RUNNER_TEMP/candidate/Buzz" + tar -xOzf "$RUNNER_TEMP/candidate/$archive" Buzz.app/Contents/MacOS/Buzz > "$RUNNER_TEMP/candidate/Buzz" test -s "$RUNNER_TEMP/candidate/Buzz" current='' if gh release view preview-feed >/dev/null 2>&1; then diff --git a/README.md b/README.md index ac26e4f18e..ce3ea2c92e 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Get the newest build from the [releases page](https://github.com/block/buzz-app/ | Platform | Download | Notes | | --- | --- | --- | -| macOS (Apple Silicon) | `Buzz_…_aarch64.dmg` | Signed and notarized. Intel Macs aren't supported. | +| macOS (Apple Silicon) | `Buzz_…_aarch64.dmg` | Signed and notarized. | +| macOS (Intel) | `Buzz_…_x64.dmg` | Signed and notarized. | | Windows (x64) | `Buzz_…_x64_unsigned.exe` | Not code-signed, so Windows SmartScreen warns you before it runs. | | Linux (x64) | `Buzz_…_amd64.deb` or `Buzz_…_x86_64.AppImage` | Built on Ubuntu 24.04. | @@ -94,8 +95,8 @@ edit files there. ## Preview limitations - Builds come straight from `main`; there's no stable release channel yet. -- macOS builds are for Apple Silicon only. The Windows installer is unsigned, - and Windows and Linux get less testing than macOS. +- The Windows installer is unsigned, and Intel macOS, Windows and Linux get + less testing than Apple Silicon macOS. - Claude and Codex agents need macOS or Linux. Goose and Pi work everywhere. - Buzz doesn't back up your key, so keep your own copy (see step 2). - Bringing your identity over from Buzz 0.X doesn't bring your communities diff --git a/docs/releases.md b/docs/releases.md index 0c4605fd6c..b47f5779c4 100644 --- a/docs/releases.md +++ b/docs/releases.md @@ -4,13 +4,13 @@ The **Desktop previews** workflow builds all supported desktop platforms from `main` and publishes one GitHub prerelease, tagged `v-preview..` at the built commit: -- **Apple Silicon macOS:** signed/notarized DMG and a signed updater archive with - its `.sig`. +- **Apple Silicon and Intel macOS:** a signed/notarized DMG and a signed updater + archive with its `.sig` for each architecture. - **Windows x64:** unsigned NSIS `.exe` installer and its updater `.sig`. - **Linux x64:** Ubuntu 24.04 `.deb` and AppImage, each with its updater `.sig`. -- **Provenance:** `SOURCE_COMMIT` and one `SHA256SUMS` covering all nine asset files. +- **Provenance:** `SOURCE_COMMIT` and one `SHA256SUMS` covering all twelve asset files. -Publication waits for all three platform jobs, their existing payload checks and +Publication waits for every platform job, their existing payload checks and the Windows/Linux updater signatures. A failed platform blocks publication and automatic feed promotion; it does not publish a partial release. Downloads are checked against each job's checksums before assembly. If a job fails, use @@ -24,9 +24,11 @@ Runs are scheduled at **00:17, 06:17, 12:17, and 18:17 UTC**. To start one manua gh workflow run release.yml --repo block/buzz-app --ref main ``` -The macOS build uses `macos-latest` and the repository's pinned toolchain. The -workflow publishes an Apple-signed/notarized DMG and a separately Tauri-signed -updater `.app.tar.gz` and `.sig` for Apple Silicon. The updater archive is +The macOS builds run on Apple Silicon `macos-latest` with the repository's +pinned toolchain; the Intel build cross-compiles `x86_64-apple-darwin` with the +same Rust release from rustup, because Hermit's Rust ships only the host's +standard library. Each publishes an Apple-signed/notarized DMG and a separately +Tauri-signed updater `.app.tar.gz` and `.sig`. The updater archive is rebuilt from the verified app in the signed DMG; built-in Tauri artifact creation remains disabled because this DMG-only build does not emit an updater archive. @@ -97,7 +99,7 @@ enable the client flag alone: existing unbound signatures would fail. A signatur mismatch fails before the rolling manifest is replaced. The job builds the Tauri manifest with each artifact's signature from that -release and an immutable versioned asset URL: `darwin-aarch64`, `windows-x86_64`, +release and an immutable versioned asset URL: `darwin-aarch64`, `darwin-x86_64`, `windows-x86_64`, `linux-x86_64-deb` and `linux-x86_64-appimage`. Linux has no generic entry, so a deb install never receives an AppImage. The job refuses full-SemVer rollback and changed same-version metadata, and replaces the rolling manifest last. The diff --git a/scripts/preview-feed.mjs b/scripts/preview-feed.mjs index ce262fa88c..89806d2c84 100644 --- a/scripts/preview-feed.mjs +++ b/scripts/preview-feed.mjs @@ -21,6 +21,7 @@ const release = `v${version}`; // Linux entries are installer-specific: a deb install must never receive an AppImage. const assets = { "darwin-aarch64": `Buzz_${version}_aarch64.app.tar.gz`, + "darwin-x86_64": `Buzz_${version}_x64.app.tar.gz`, "windows-x86_64": `Buzz_${version}_x64_unsigned.exe`, "linux-x86_64-deb": `Buzz_${version}_amd64.deb`, "linux-x86_64-appimage": `Buzz_${version}_x86_64.AppImage`, diff --git a/scripts/prune-preview-releases.mjs b/scripts/prune-preview-releases.mjs index 9a8430ba65..b5e20c024f 100644 --- a/scripts/prune-preview-releases.mjs +++ b/scripts/prune-preview-releases.mjs @@ -36,6 +36,7 @@ assert.match(manifest.version, versionPattern); const protectedTag = `v${manifest.version}`; const assets = { "darwin-aarch64": "aarch64.app.tar.gz", + "darwin-x86_64": "x64.app.tar.gz", "windows-x86_64": "x64_unsigned.exe", "linux-x86_64-deb": "amd64.deb", "linux-x86_64-appimage": "x86_64.AppImage", diff --git a/tests/integration/desktop-release.test.mjs b/tests/integration/desktop-release.test.mjs index f989260e35..f9fac98923 100644 --- a/tests/integration/desktop-release.test.mjs +++ b/tests/integration/desktop-release.test.mjs @@ -27,11 +27,16 @@ const version = `${baseVersion}-preview.42.2`; const sha = "a".repeat(40); const hash = (bytes) => createHash("sha256").update(bytes).digest("hex"); const assets = { - macos: [ + "macos-aarch64": [ `Buzz_${version}_aarch64.dmg`, `Buzz_${version}_aarch64.app.tar.gz`, `Buzz_${version}_aarch64.app.tar.gz.sig`, ], + "macos-x64": [ + `Buzz_${version}_x64.dmg`, + `Buzz_${version}_x64.app.tar.gz`, + `Buzz_${version}_x64.app.tar.gz.sig`, + ], windows: [`Buzz_${version}_x64_unsigned.exe`], linux: [`Buzz_${version}_amd64.deb`, `Buzz_${version}_x86_64.AppImage`], signatures: [ @@ -143,7 +148,7 @@ function fixture(t) { }; } -test("actual assembly command collects all nine assets and emits one complete checksum file", (t) => { +test("actual assembly command collects all twelve assets and emits one complete checksum file", (t) => { const { dir, run } = fixture(t); const result = run(); assert.equal(result.status, 0, result.stderr); @@ -169,6 +174,7 @@ for (const failure of [ "corrupt", "mixed version", "missing platform", + "missing Intel macOS", "missing signature", ]) { test(`actual assembly refuses ${failure} before publication`, (t) => { @@ -182,6 +188,8 @@ for (const failure of [ writeFileSync(join(windows, "SHA256SUMS"), `${hash(file)} ./${older}\n`); } if (failure === "missing platform") rmSync(windows, { recursive: true }); + if (failure === "missing Intel macOS") + rmSync(join(dir, "build-assets/macos-x64"), { recursive: true }); if (failure === "missing signature") rmSync(join(dir, "build-assets/signatures", assets.signatures[2])); assert.notEqual(run().status, 0); diff --git a/tests/integration/packaging.test.mjs b/tests/integration/packaging.test.mjs index 8680fc6a31..d4bd3535c7 100644 --- a/tests/integration/packaging.test.mjs +++ b/tests/integration/packaging.test.mjs @@ -113,20 +113,34 @@ test("all-platform releases preserve candidate isolation and read-only installer assert.deepEqual( downloads.map((step) => step.with.path), [ - "build-assets/macos", + "build-assets/macos-aarch64", + "build-assets/macos-x64", "build-assets/windows", "build-assets/linux", "build-assets/signatures", ], ); - for (const [index, job] of [ - jobs.build, - jobs.windows, - jobs.linux, - jobs.updater_signatures, - ].entries()) { - assert.equal(downloads[index].with.name, job.steps.at(-1).with.name); - } + assert.deepEqual(jobs.build.strategy.matrix.include, [ + { target: "aarch64-apple-darwin", arch: "aarch64", lipo: "arm64" }, + { target: "x86_64-apple-darwin", arch: "x64", lipo: "x86_64" }, + ]); + const build = jobs.build.steps.find( + (step) => step.name === "Build unsigned app and DMG", + ).run; + assert.match(build, /target-libdir --target "\$TARGET"/); + assert.match(build, /pnpm tauri build .*--target "\$TARGET"/); + const macos = jobs.build.steps.at(-1).with.name; + assert.deepEqual( + downloads.map((step) => step.with.name), + [ + ...jobs.build.strategy.matrix.include.map(({ arch }) => + macos.replace(/\$\{\{ matrix\.arch \}\}/, arch), + ), + ...[jobs.windows, jobs.linux, jobs.updater_signatures].map( + (job) => job.steps.at(-1).with.name, + ), + ], + ); const publication = jobs.publish.steps.at(-1).run; assert.match( publication, diff --git a/tests/integration/preview-feed.test.mjs b/tests/integration/preview-feed.test.mjs index e3e9318228..f8d017f968 100644 --- a/tests/integration/preview-feed.test.mjs +++ b/tests/integration/preview-feed.test.mjs @@ -51,6 +51,7 @@ function fixture(dir, version = "0.0.0-preview.22.1") { mkdirSync(assetDir); const installers = [ `Buzz_${version}_aarch64.app.tar.gz`, + `Buzz_${version}_x64.app.tar.gz`, `Buzz_${version}_x64_unsigned.exe`, `Buzz_${version}_amd64.deb`, `Buzz_${version}_x86_64.AppImage`, @@ -173,6 +174,7 @@ test("preview feed signs every desktop installer into its updater target", () => const { platforms } = JSON.parse(readFileSync(manifest, "utf8")); const targets = [ "darwin-aarch64", + "darwin-x86_64", "windows-x86_64", "linux-x86_64-deb", "linux-x86_64-appimage", @@ -186,7 +188,7 @@ test("preview feed signs every desktop installer into its updater target", () => url: `https://github.com/block/buzz-app/releases/download/v0.0.0-preview.22.1/${name}`, }); }); - const [, windows, deb] = installers; + const [, , windows, deb] = installers; const data = JSON.parse(readFileSync(manifest, "utf8")); delete data.platforms["windows-x86_64"]; writeFileSync(manifest, JSON.stringify(data)); diff --git a/tests/integration/prune-preview-releases.test.mjs b/tests/integration/prune-preview-releases.test.mjs index 28a9084966..71ead22664 100644 --- a/tests/integration/prune-preview-releases.test.mjs +++ b/tests/integration/prune-preview-releases.test.mjs @@ -56,6 +56,7 @@ function fixture(t) { platforms: Object.fromEntries( Object.entries({ "darwin-aarch64": "aarch64.app.tar.gz", + "darwin-x86_64": "x64.app.tar.gz", "windows-x86_64": "x64_unsigned.exe", "linux-x86_64-deb": "amd64.deb", "linux-x86_64-appimage": "x86_64.AppImage",