ci: cut over desktop releases to Electron

Repackages Electron app for legacy Tauri updater migration
Stops release and manual DMG workflows from building Tauri
Documents transition flow and cleanup timing
This commit is contained in:
Bohdan Triapitsyn
2026-05-21 16:37:06 +03:00
parent 6cc1afc963
commit 7d98f388c0
3 changed files with 249 additions and 493 deletions
+1 -108
View File
@@ -1,4 +1,4 @@
name: Build macOS DMG (arm64)
name: Build Electron macOS DMG (arm64)
on:
workflow_dispatch:
@@ -16,114 +16,7 @@ on:
required: false
default: ""
env:
CARGO_INCREMENTAL: 0
RUST_BACKTRACE: short
jobs:
build-macos-dmg-arm64:
name: Build DMG (arm64, ${{ inputs.macos_version }})
runs-on: ${{ inputs.macos_version }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.ref }}
- name: Setup bun
uses: oven-sh/setup-bun@v2
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: aarch64-apple-darwin
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: packages/desktop/src-tauri
key: aarch64-apple-darwin
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Install Apple Certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/certificate.p12
security import $RUNNER_TEMP/certificate.p12 \
-P "$APPLE_CERTIFICATE_PASSWORD" \
-A -t cert -f pkcs12 \
-k "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple:,codesign: \
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
- name: Set up notarization credentials
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
run: |
if [ -z "$APPLE_ID" ] || [ -z "$APPLE_TEAM_ID" ] || [ -z "$APPLE_PASSWORD" ]; then
echo "Error: Missing Apple notarization credentials"
exit 1
fi
xcrun notarytool store-credentials "openchamber-notarize" \
--apple-id "$APPLE_ID" \
--team-id "$APPLE_TEAM_ID" \
--password "$APPLE_PASSWORD"
- name: Build UI package
run: bun run --cwd packages/ui build
- name: Build Desktop app (arm64)
run: bun run --cwd packages/desktop build && bun run --cwd packages/desktop tauri build --target aarch64-apple-darwin
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Prepare DMG artifact
run: |
set -euo pipefail
mkdir -p artifacts
DMG_PATH="packages/desktop/src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg"
if ls $DMG_PATH 1> /dev/null 2>&1; then
DMG_FILE=$(ls $DMG_PATH | head -n 1)
DMG_NAME="OpenChamber_${{ inputs.macos_version }}_arm64.dmg"
cp "$DMG_FILE" "artifacts/$DMG_NAME"
else
echo "Error: DMG file not found at $DMG_PATH"
exit 1
fi
- name: Upload DMG artifact
uses: actions/upload-artifact@v4
with:
name: dmg-${{ inputs.macos_version }}-arm64
path: artifacts/*.dmg
retention-days: 7
build-macos-dmg-arm64-electron:
name: Build Electron DMG (arm64, ${{ inputs.macos_version }})
runs-on: ${{ inputs.macos_version }}
+183 -377
View File
@@ -78,299 +78,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-desktop-macos:
needs: create-release
runs-on: macos-26
strategy:
fail-fast: false
matrix:
target: [aarch64-apple-darwin, x86_64-apple-darwin]
include:
- target: aarch64-apple-darwin
arch: aarch64
platform: darwin-aarch64
- target: x86_64-apple-darwin
arch: x86_64
platform: darwin-x86_64
outputs:
version: ${{ needs.create-release.outputs.version }}
steps:
- uses: actions/checkout@v4
- name: Setup bun
uses: oven-sh/setup-bun@v2
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Rust stable
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Rust cache
uses: swatinem/rust-cache@v2
with:
workspaces: packages/desktop/src-tauri
key: ${{ matrix.target }}
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Install Apple Certificate
env:
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
run: |
# Create temporary keychain
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
KEYCHAIN_PASSWORD=$(openssl rand -base64 32)
security create-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
security unlock-keychain -p "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
# Import certificate
echo "$APPLE_CERTIFICATE" | base64 --decode > $RUNNER_TEMP/certificate.p12
security import $RUNNER_TEMP/certificate.p12 \
-P "$APPLE_CERTIFICATE_PASSWORD" \
-A -t cert -f pkcs12 \
-k "$KEYCHAIN_PATH"
security list-keychain -d user -s "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple:,codesign: \
-s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
- name: Set up notarization credentials
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
run: |
# Validate secrets are set
if [ -z "$APPLE_ID" ] || [ -z "$APPLE_TEAM_ID" ] || [ -z "$APPLE_PASSWORD" ]; then
echo "Error: Missing Apple notarization credentials"
exit 1
fi
xcrun notarytool store-credentials "openchamber-notarize" \
--apple-id "$APPLE_ID" \
--team-id "$APPLE_TEAM_ID" \
--password "$APPLE_PASSWORD"
- name: Build UI package
run: bun run --cwd packages/ui build
- name: Build Desktop app
# Note: We use inline commands instead of desktop:build to pass architecture-specific --target flag
# This enables cross-compilation for both arm64 and x86_64 from the same runner
run: |
export TAURI_ENV_TARGET_TRIPLE=${{ matrix.target }}
bun run --cwd packages/desktop build
bun run --cwd packages/desktop tauri build --target ${{ matrix.target }}
env:
TAURI_ENV_TARGET_TRIPLE: ${{ matrix.target }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
- name: Verify binary architectures
run: |
set -euo pipefail
BUNDLE_DIR="packages/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/macos"
if [ ! -d "$BUNDLE_DIR" ]; then
echo "❌ Error: bundle directory not found: $BUNDLE_DIR"
exit 1
fi
APP_PATH=$(find "$BUNDLE_DIR" -maxdepth 2 -name "*.app" -print -quit)
if [ -z "$APP_PATH" ]; then
echo "❌ Error: .app bundle not found under $BUNDLE_DIR"
exit 1
fi
echo "🔍 Verifying binary architectures in $APP_PATH"
# Extract raw architecture names (macOS file command reports ARM as "arm64")
MAIN_ARCH_RAW=$(file "$APP_PATH/Contents/MacOS/openchamber-desktop" | grep -oE 'arm64|x86_64|aarch64' | head -1)
SIDEARCH_ARCH_RAW=$(file "$APP_PATH/Contents/MacOS/openchamber-server" | grep -oE 'arm64|x86_64|aarch64' | head -1)
# Normalize architecture names (arm64 -> aarch64 for consistency with Rust/Tauri)
normalize_arch() {
case "$1" in
arm64) echo "aarch64" ;;
aarch64|x86_64) echo "$1" ;;
*) echo "unknown" ;;
esac
}
MAIN_ARCH=$(normalize_arch "$MAIN_ARCH_RAW")
SIDEARCH_ARCH=$(normalize_arch "$SIDEARCH_ARCH_RAW")
EXPECTED_ARCH=$(echo "${{ matrix.target }}" | grep -oE 'aarch64|x86_64' | head -1)
echo " Main: $MAIN_ARCH_RAW → $MAIN_ARCH"
echo " Sidecar: $SIDEARCH_ARCH_RAW → $SIDEARCH_ARCH"
echo " Expected: $EXPECTED_ARCH"
if [ "$MAIN_ARCH" != "$EXPECTED_ARCH" ]; then
echo "❌ ERROR: Main binary architecture mismatch!"
echo " Expected: $EXPECTED_ARCH"
echo " Got: $MAIN_ARCH (raw: $MAIN_ARCH_RAW)"
exit 1
fi
if [ "$SIDEARCH_ARCH" != "$EXPECTED_ARCH" ]; then
echo "❌ ERROR: Sidecar binary architecture mismatch!"
echo " Expected: $EXPECTED_ARCH"
echo " Got: $SIDEARCH_ARCH (raw: $SIDEARCH_ARCH_RAW)"
exit 1
fi
echo "✅ Architecture verification passed: both binaries match $EXPECTED_ARCH"
- name: Verify macOS entitlements
run: |
set -euo pipefail
BUNDLE_DIR="packages/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/macos"
if [ ! -d "$BUNDLE_DIR" ]; then
echo "Error: bundle directory not found: $BUNDLE_DIR"
exit 1
fi
APP_PATH=$(find "$BUNDLE_DIR" -maxdepth 2 -name "*.app" -print -quit)
if [ -z "$APP_PATH" ]; then
echo "Error: .app bundle not found under $BUNDLE_DIR"
echo "Contents:"; ls -la "$BUNDLE_DIR"
exit 1
fi
echo "Verifying app bundle: $APP_PATH"
codesign -vv "$APP_PATH"
ENTITLEMENTS=$(codesign -d --entitlements :- "$APP_PATH" 2>&1 || true)
echo "$ENTITLEMENTS"
if echo "$ENTITLEMENTS" | grep -q "com.apple.security.app-sandbox"; then
echo "Error: app sandbox entitlement is present"
exit 1
fi
for key in \
com.apple.security.cs.allow-jit \
com.apple.security.cs.allow-unsigned-executable-memory \
com.apple.security.cs.disable-executable-page-protection \
com.apple.security.cs.disable-library-validation
do
if ! echo "$ENTITLEMENTS" | grep -q "<key>$key</key>"; then
echo "Error: required entitlement missing: $key"
exit 1
fi
done
- name: Prepare release artifacts
run: |
mkdir -p artifacts
VERSION="${{ needs.create-release.outputs.version }}"
# Copy DMG (Tauri names it with the target triple in the path)
DMG_PATH="packages/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/dmg/*.dmg"
if ls $DMG_PATH 1> /dev/null 2>&1; then
DMG_FILE=$(ls $DMG_PATH | head -n 1)
DMG_NAME="OpenChamber_${VERSION}_${{ matrix.platform }}.dmg"
cp "$DMG_FILE" "artifacts/$DMG_NAME"
else
echo "Error: DMG file not found at $DMG_PATH"
exit 1
fi
# Copy tar.gz and signature for updater
TAR_PATH="packages/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/macos/*.tar.gz"
SIG_PATH="packages/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/macos/*.tar.gz.sig"
if ls $TAR_PATH 1> /dev/null 2>&1; then
TAR_FILE=$(ls $TAR_PATH | head -n 1)
TAR_BASE=$(basename "$TAR_FILE")
TAR_NAME="${TAR_BASE%.tar.gz}-${{ matrix.platform }}.tar.gz"
cp "$TAR_FILE" "artifacts/$TAR_NAME"
else
echo "Error: tar.gz file not found at $TAR_PATH"
exit 1
fi
if ls $SIG_PATH 1> /dev/null 2>&1; then
SIG_FILE=$(ls $SIG_PATH | head -n 1)
SIG_BASE=$(basename "$SIG_FILE")
SIG_NAME="${SIG_BASE%.tar.gz.sig}-${{ matrix.platform }}.tar.gz.sig"
cp "$SIG_FILE" "artifacts/$SIG_NAME"
else
echo "Error: signature file not found at $SIG_PATH"
exit 1
fi
echo "Successfully prepared artifacts:"
ls -lh artifacts/
- name: Generate update manifest
run: |
VERSION="${{ needs.create-release.outputs.version }}"
# Find the signature file for this platform
SIG_FILE=$(find artifacts -name "*-${{ matrix.platform }}.tar.gz.sig" | head -1)
if [ -f "$SIG_FILE" ]; then
SIGNATURE=$(cat "$SIG_FILE")
else
SIGNATURE=""
fi
# Find the tar.gz file name for this platform
TAR_FILE=$(find artifacts -name "*-${{ matrix.platform }}.tar.gz" ! -name "*.sig" | head -1)
TAR_NAME=$(basename "$TAR_FILE" 2>/dev/null || echo "OpenChamber-${{ matrix.platform }}.app.tar.gz")
cat > artifacts/latest-${{ matrix.platform }}.json << EOF
{
"version": "${VERSION}",
"notes": "See release notes at https://github.com/${{ github.repository }}/releases/tag/v${VERSION}",
"pub_date": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"platforms": {
"${{ matrix.platform }}": {
"signature": "${SIGNATURE}",
"url": "https://github.com/${{ github.repository }}/releases/download/v${VERSION}/${TAR_NAME}"
}
}
}
EOF
echo "Generated latest-${{ matrix.platform }}.json:"
cat artifacts/latest-${{ matrix.platform }}.json
- name: Upload release assets
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: |
artifacts/*.dmg
artifacts/*.tar.gz
artifacts/*.tar.gz.sig
artifacts/latest-${{ matrix.platform }}.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload manifest as artifact
uses: actions/upload-artifact@v4
with:
name: manifest-${{ matrix.platform }}
path: artifacts/latest-${{ matrix.platform }}.json
retention-days: 1
publish-npm:
needs: create-release
runs-on: ubuntu-latest
@@ -411,89 +118,6 @@ jobs:
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
combine-manifests:
needs: [create-release, build-desktop-macos]
runs-on: ubuntu-latest
steps:
- name: Download aarch64 manifest
uses: actions/download-artifact@v4
with:
name: manifest-darwin-aarch64
path: artifacts
- name: Download x86_64 manifest
uses: actions/download-artifact@v4
with:
name: manifest-darwin-x86_64
path: artifacts
- name: Combine manifests
run: |
VERSION="${{ needs.create-release.outputs.version }}"
PUB_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
REPO="${{ github.repository }}"
# Validate that both manifest files exist and are valid JSON
if [ ! -f artifacts/latest-darwin-aarch64.json ]; then
echo "Error: aarch64 manifest not found"
exit 1
fi
if [ ! -f artifacts/latest-darwin-x86_64.json ]; then
echo "Error: x86_64 manifest not found"
exit 1
fi
# Validate JSON structure
if ! jq empty artifacts/latest-darwin-aarch64.json 2>/dev/null; then
echo "Error: aarch64 manifest is not valid JSON"
exit 1
fi
if ! jq empty artifacts/latest-darwin-x86_64.json 2>/dev/null; then
echo "Error: x86_64 manifest is not valid JSON"
exit 1
fi
# Validate platform data exists in manifests
if ! jq -e '.platforms["darwin-aarch64"]' artifacts/latest-darwin-aarch64.json > /dev/null; then
echo "Error: darwin-aarch64 platform data not found in manifest"
exit 1
fi
if ! jq -e '.platforms["darwin-x86_64"]' artifacts/latest-darwin-x86_64.json > /dev/null; then
echo "Error: darwin-x86_64 platform data not found in manifest"
exit 1
fi
# Use jq to properly combine the manifests
jq -n \
--arg version "$VERSION" \
--arg notes "See release notes at https://github.com/${REPO}/releases/tag/v${VERSION}" \
--arg pub_date "$PUB_DATE" \
--slurpfile aarch64 artifacts/latest-darwin-aarch64.json \
--slurpfile x86_64 artifacts/latest-darwin-x86_64.json \
'{
version: $version,
notes: $notes,
pub_date: $pub_date,
platforms: {
"darwin-aarch64": $aarch64[0].platforms["darwin-aarch64"],
"darwin-x86_64": $x86_64[0].platforms["darwin-x86_64"]
}
}' > artifacts/latest.json
echo "Generated combined latest.json:"
cat artifacts/latest.json
- name: Upload combined manifest
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: artifacts/latest.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
build-desktop-electron-macos:
needs: create-release
runs-on: macos-26
@@ -617,6 +241,31 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Stage signed Electron app for Tauri updater repackage
run: |
set -euo pipefail
APP_DIR="packages/electron/dist/mac"
[ -d "packages/electron/dist/mac-arm64" ] && APP_DIR="packages/electron/dist/mac-arm64"
APP_PATH=$(find "$APP_DIR" -maxdepth 2 -name "*.app" -print -quit)
if [ -z "$APP_PATH" ]; then
echo "Error: .app not found under packages/electron/dist/mac*"
ls -la packages/electron/dist/
exit 1
fi
rm -rf electron-app-artifact
mkdir -p electron-app-artifact
cp -R "$APP_PATH" electron-app-artifact/OpenChamber.app
- name: Upload signed Electron app for Tauri updater repackage
uses: actions/upload-artifact@v4
with:
name: electron-app-${{ matrix.arch }}
path: electron-app-artifact/OpenChamber.app
retention-days: 1
- name: Upload per-arch latest-mac.yml for merge
uses: actions/upload-artifact@v4
with:
@@ -624,6 +273,163 @@ jobs:
path: packages/electron/dist/latest-mac.yml
retention-days: 1
repackage-electron-as-tauri-update:
needs: [create-release, build-desktop-electron-macos]
runs-on: macos-26
strategy:
fail-fast: false
matrix:
include:
- arch: arm64
platform: darwin-aarch64
- arch: x64
platform: darwin-x86_64
steps:
- uses: actions/checkout@v4
- name: Download signed Electron app
uses: actions/download-artifact@v4
with:
name: electron-app-${{ matrix.arch }}
path: staged
- name: Install minisign
run: brew install minisign
- name: Tar and sign Electron app as Tauri update payload
env:
TAURI_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
VERSION: ${{ needs.create-release.outputs.version }}
run: |
set -euo pipefail
if [ ! -d staged/OpenChamber.app ]; then
echo "Error: staged/OpenChamber.app not found"
ls -la staged
exit 1
fi
cd staged
TARBALL="OpenChamber.app.tar.gz"
tar -czf "$TARBALL" OpenChamber.app
printf '%s\n' "$TAURI_KEY" > ../tauri-signing.key
printf '%s\n' "$TAURI_KEY_PASSWORD" | minisign -S -s ../tauri-signing.key -m "$TARBALL" -W
mv "$TARBALL" "OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz"
mv "${TARBALL}.minisig" "OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz.sig"
- name: Generate Tauri latest platform manifest
env:
VERSION: ${{ needs.create-release.outputs.version }}
REPO: ${{ github.repository }}
run: |
set -euo pipefail
SIG=$(cat staged/OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz.sig)
TAR="OpenChamber-${VERSION}-${{ matrix.platform }}.app.tar.gz"
jq -n \
--arg version "$VERSION" \
--arg notes "OpenChamber has moved to Electron. This update replaces the Tauri shell with the Electron build. Subsequent updates will be delivered via the Electron auto-updater." \
--arg pub_date "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
--arg platform "${{ matrix.platform }}" \
--arg signature "$SIG" \
--arg url "https://github.com/${REPO}/releases/download/v${VERSION}/${TAR}" \
'{ version: $version, notes: $notes, pub_date: $pub_date, platforms: { ($platform): { signature: $signature, url: $url } } }' \
> staged/latest-${{ matrix.platform }}.json
- name: Upload tarball and signature to release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: |
staged/*.app.tar.gz
staged/*.app.tar.gz.sig
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload per-platform Tauri manifest for merge
uses: actions/upload-artifact@v4
with:
name: tauri-manifest-${{ matrix.platform }}
path: staged/latest-${{ matrix.platform }}.json
retention-days: 1
combine-manifests:
needs: [create-release, repackage-electron-as-tauri-update]
runs-on: ubuntu-latest
steps:
- name: Download Tauri updater manifests
uses: actions/download-artifact@v4
with:
pattern: tauri-manifest-*
path: artifacts
merge-multiple: true
- name: Combine manifests
run: |
set -euo pipefail
VERSION="${{ needs.create-release.outputs.version }}"
PUB_DATE="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
if [ ! -f artifacts/latest-darwin-aarch64.json ]; then
echo "Error: aarch64 manifest not found"
exit 1
fi
if [ ! -f artifacts/latest-darwin-x86_64.json ]; then
echo "Error: x86_64 manifest not found"
exit 1
fi
if ! jq empty artifacts/latest-darwin-aarch64.json 2>/dev/null; then
echo "Error: aarch64 manifest is not valid JSON"
exit 1
fi
if ! jq empty artifacts/latest-darwin-x86_64.json 2>/dev/null; then
echo "Error: x86_64 manifest is not valid JSON"
exit 1
fi
if ! jq -e '.platforms["darwin-aarch64"]' artifacts/latest-darwin-aarch64.json > /dev/null; then
echo "Error: darwin-aarch64 platform data not found in manifest"
exit 1
fi
if ! jq -e '.platforms["darwin-x86_64"]' artifacts/latest-darwin-x86_64.json > /dev/null; then
echo "Error: darwin-x86_64 platform data not found in manifest"
exit 1
fi
jq -n \
--arg version "$VERSION" \
--arg notes "OpenChamber has moved to Electron. This update replaces the Tauri shell with the Electron build. Subsequent updates will be delivered via the Electron auto-updater." \
--arg pub_date "$PUB_DATE" \
--slurpfile aarch64 artifacts/latest-darwin-aarch64.json \
--slurpfile x86_64 artifacts/latest-darwin-x86_64.json \
'{
version: $version,
notes: $notes,
pub_date: $pub_date,
platforms: {
"darwin-aarch64": $aarch64[0].platforms["darwin-aarch64"],
"darwin-x86_64": $x86_64[0].platforms["darwin-x86_64"]
}
}' > artifacts/latest.json
cat artifacts/latest.json
- name: Upload combined Tauri updater manifest
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.create-release.outputs.version }}
files: artifacts/latest.json
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
combine-electron-manifests:
needs: [create-release, build-desktop-electron-macos]
runs-on: ubuntu-latest
@@ -657,7 +463,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
finalize-release:
needs: [create-release, build-desktop-macos, build-desktop-electron-macos, publish-npm, combine-manifests, combine-electron-manifests]
needs: [create-release, build-desktop-electron-macos, repackage-electron-as-tauri-update, publish-npm, combine-manifests, combine-electron-manifests]
runs-on: ubuntu-latest
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}