feat(macos): native app menu, status item, window state, notifications #47
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| workflow_dispatch: {} | |
| push: | |
| tags: | |
| - 'v[0-9]+.[0-9]+.[0-9]+' | |
| permissions: | |
| contents: write | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - leg: win | |
| os: windows-latest | |
| args: '' | |
| - leg: linux-x64 | |
| os: ubuntu-22.04 | |
| args: '' | |
| - leg: linux-arm64 | |
| os: ubuntu-22.04-arm | |
| args: '' | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Setup Node.js | |
| uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 | |
| with: | |
| node-version: 20 | |
| cache: npm | |
| - name: Setup Rust | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| toolchain: "1.92.0" | |
| targets: ${{ matrix.leg == 'mac' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} | |
| - name: Rust cache | |
| uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 | |
| with: | |
| workspaces: src-tauri -> target | |
| - name: Setup MSVC environment (Windows, for vendored OpenSSL build) | |
| if: matrix.leg == 'win' | |
| uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1 | |
| - name: Install NASM (Windows, for vendored OpenSSL / SQLCipher) | |
| if: matrix.leg == 'win' | |
| shell: bash | |
| run: | | |
| choco install nasm -y | |
| echo "C:\\Program Files\\NASM" >> "$GITHUB_PATH" | |
| - name: Install Linux system dependencies | |
| if: startsWith(matrix.leg, 'linux') | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| libwebkit2gtk-4.1-dev \ | |
| libayatana-appindicator3-dev \ | |
| librsvg2-dev \ | |
| libxdo-dev \ | |
| build-essential \ | |
| file \ | |
| perl \ | |
| xdg-utils | |
| - name: Import Apple certificate | |
| if: matrix.leg == 'mac' && env.APPLE_CERTIFICATE != '' | |
| env: | |
| APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} | |
| APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} | |
| KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }} | |
| APPLE_SIGNING_IDENTITY_SECRET: ${{ secrets.APPLE_SIGNING_IDENTITY }} | |
| run: | | |
| echo "$APPLE_CERTIFICATE" | base64 --decode > cert.p12 | |
| security create-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | |
| security default-keychain -s build.keychain | |
| security unlock-keychain -p "$KEYCHAIN_PASSWORD" build.keychain | |
| security import cert.p12 -k build.keychain -P "$APPLE_CERTIFICATE_PASSWORD" -T /usr/bin/codesign | |
| security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$KEYCHAIN_PASSWORD" build.keychain | |
| rm cert.p12 | |
| if [ -n "$APPLE_SIGNING_IDENTITY_SECRET" ]; then | |
| SIGNING_IDENTITY="$APPLE_SIGNING_IDENTITY_SECRET" | |
| else | |
| SIGNING_IDENTITY=$(security find-identity -v -p codesigning build.keychain | grep '"' | head -1 | sed 's/.*"\(.*\)"/\1/') | |
| fi | |
| echo "APPLE_SIGNING_IDENTITY=$SIGNING_IDENTITY" >> $GITHUB_ENV | |
| - name: Write Apple API key | |
| if: matrix.leg == 'mac' && env.APPLE_API_KEY_CONTENT != '' | |
| env: | |
| APPLE_API_KEY_CONTENT: ${{ secrets.APPLE_API_KEY_CONTENT }} | |
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | |
| run: | | |
| mkdir -p ~/private_keys | |
| echo "$APPLE_API_KEY_CONTENT" | base64 --decode > ~/private_keys/AuthKey_${APPLE_API_KEY}.p8 | |
| - name: Build @aster/ui | |
| run: | | |
| git clone --depth=1 https://github.com/Aster-Privacy/aster-ui.git ../aster-ui | |
| cd ../aster-ui | |
| npm ci --no-audit --no-fund | |
| npm run build | |
| - name: Fetch aster-crypto source (Aster-Mail) | |
| run: git clone --depth=1 https://github.com/Aster-Privacy/Aster-Mail.git ../Aster-Mail | |
| - name: Install frontend dependencies | |
| run: npm ci --no-audit --no-fund | |
| - name: Build and publish release | |
| uses: tauri-apps/tauri-action@84b9d35b5fc46c1e45415bdb6144030364f7ebc5 # v0.6.2 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| APPLE_SIGNING_IDENTITY: ${{ env.APPLE_SIGNING_IDENTITY }} | |
| APPLE_API_KEY: ${{ secrets.APPLE_API_KEY }} | |
| APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }} | |
| APPLE_API_KEY_PATH: ${{ secrets.APPLE_API_KEY != '' && format('~/private_keys/AuthKey_{0}.p8', secrets.APPLE_API_KEY) || '' }} | |
| APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} | |
| with: | |
| tagName: v__VERSION__ | |
| releaseName: Aster Bridge __VERSION__ | |
| releaseDraft: false | |
| prerelease: true | |
| updaterJsonPreferNsis: true | |
| args: ${{ matrix.args }} | |
| tauriScript: npm run tauri | |
| - name: Unbundle host graphics libraries from the AppImage | |
| # linuxdeploy copies libwayland-client.so.0 and friends into the AppDir. | |
| # They shadow the host copies, Mesa's libEGL_mesa.so.0 then fails to | |
| # resolve wl_fixes_interface on any distribution newer than the runner, | |
| # and WebKitGTK aborts with EGL_BAD_PARAMETER before the window paints. | |
| if: startsWith(matrix.leg, 'linux') | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} | |
| TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| sudo apt-get install -y squashfs-tools | |
| V=$(node -p "require('./package.json').version") | |
| TAG="v${V}" | |
| shopt -s nullglob | |
| for img in src-tauri/target/release/bundle/appimage/*.AppImage; do | |
| bash scripts/fix_appimage_libs.sh "$img" | |
| rm -f "$img.sig" | |
| npm run tauri -- signer sign "$img" | |
| gh release upload "$TAG" "$img" "$img.sig" --clobber | |
| done | |
| - name: Build and publish the Arch Linux package | |
| # Arch has no .deb or .rpm, and the AppImage is not a package. Repack the | |
| # release deb into a pacman package inside an Arch container so | |
| # `pacman -U` installs Aster Bridge like any other Arch package. | |
| if: matrix.leg == 'linux-x64' | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| V=$(node -p "require('./package.json').version") | |
| TAG="v${V}" | |
| docker run --rm -e V="$V" -v "$PWD/packaging/arch:/pkg" archlinux:base-devel bash -c ' | |
| set -euo pipefail | |
| pacman -Sy --noconfirm --needed pacman-contrib >/dev/null | |
| useradd -m builder | |
| cp /pkg/PKGBUILD /home/builder/PKGBUILD | |
| chown -R builder:builder /home/builder | |
| su builder -c "cd /home/builder && sed -i \"s/^pkgver=.*/pkgver=$V/\" PKGBUILD && updpkgsums && makepkg -f --noconfirm --nodeps" | |
| cp /home/builder/*.pkg.tar.zst /pkg/ | |
| ' | |
| PKG="packaging/arch/aster-bridge-${V}-1-x86_64.pkg.tar.zst" | |
| test -f "$PKG" | |
| cp "$PKG" "packaging/arch/Aster-Bridge-x86_64.pkg.tar.zst" | |
| gh release upload "$TAG" "$PKG" "packaging/arch/Aster-Bridge-x86_64.pkg.tar.zst" --clobber | |
| - name: Rename assets to canonical names | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| V=$(node -p "require('./package.json').version") | |
| TAG="v${V}" | |
| TMP=$(mktemp -d) | |
| rename_asset() { | |
| local src="$1" dst="$2" | |
| if gh release download "$TAG" --pattern "$src" --dir "$TMP" --clobber 2>/dev/null; then | |
| mv "$TMP/$src" "$TMP/$dst" | |
| gh release upload "$TAG" "$TMP/$dst" --clobber | |
| fi | |
| } | |
| if [[ "${{ matrix.leg }}" == "linux-x64" ]]; then | |
| rename_asset "Aster.Bridge_${V}_amd64.AppImage" "Aster-Bridge-x86_64.AppImage" | |
| rename_asset "Aster.Bridge_${V}_amd64.AppImage.sig" "Aster-Bridge-x86_64.AppImage.sig" | |
| rename_asset "Aster.Bridge_${V}_amd64.deb" "Aster-Bridge-amd64.deb" | |
| rename_asset "Aster.Bridge_${V}_amd64.deb.sig" "Aster-Bridge-amd64.deb.sig" | |
| rename_asset "Aster.Bridge-${V}-1.x86_64.rpm" "Aster-Bridge-x86_64.rpm" | |
| rename_asset "Aster.Bridge-${V}-1.x86_64.rpm.sig" "Aster-Bridge-x86_64.rpm.sig" | |
| elif [[ "${{ matrix.leg }}" == "linux-arm64" ]]; then | |
| rename_asset "Aster.Bridge_${V}_aarch64.AppImage" "Aster-Bridge-aarch64.AppImage" | |
| rename_asset "Aster.Bridge_${V}_aarch64.AppImage.sig" "Aster-Bridge-aarch64.AppImage.sig" | |
| rename_asset "Aster.Bridge_${V}_arm64.deb" "Aster-Bridge-arm64.deb" | |
| rename_asset "Aster.Bridge_${V}_arm64.deb.sig" "Aster-Bridge-arm64.deb.sig" | |
| rename_asset "Aster.Bridge-${V}-1.aarch64.rpm" "Aster-Bridge-aarch64.rpm" | |
| rename_asset "Aster.Bridge-${V}-1.aarch64.rpm.sig" "Aster-Bridge-aarch64.rpm.sig" | |
| elif [[ "${{ matrix.leg }}" == "win" ]]; then | |
| rename_asset "Aster.Bridge_${V}_x64-setup.exe" "Aster-Bridge-x64-setup.exe" | |
| rename_asset "Aster.Bridge_${V}_x64-setup.exe.sig" "Aster-Bridge-x64-setup.exe.sig" | |
| rename_asset "Aster.Bridge_${V}_x64_en-US.msi" "Aster-Bridge-x64.msi" | |
| rename_asset "Aster.Bridge_${V}_x64_en-US.msi.sig" "Aster-Bridge-x64.msi.sig" | |
| elif [[ "${{ matrix.leg }}" == "mac" ]]; then | |
| rename_asset "Aster.Bridge_${V}_universal.dmg" "Aster-Bridge-universal.dmg" | |
| rename_asset "Aster.Bridge_${V}_universal.dmg.sig" "Aster-Bridge-universal.dmg.sig" | |
| rename_asset "Aster.Bridge_${V}_universal.app.tar.gz" "Aster-Bridge-universal.app.tar.gz" | |
| rename_asset "Aster.Bridge_${V}_universal.app.tar.gz.sig" "Aster-Bridge-universal.app.tar.gz.sig" | |
| fi | |
| update_latest_json: | |
| needs: build | |
| # Runs even when a leg fails: the legs that DID succeed have already published | |
| # their own partial latest.json, so skipping here would leave that partial file | |
| # standing as the manifest. Running always means the guard below still fires. | |
| if: always() | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Rebuild latest.json from every leg's signatures | |
| # Each build leg's tauri-action uploads its own latest.json with --clobber, | |
| # so the last leg to finish wins and the others' platforms vanish. v0.4.21 | |
| # shipped with only linux-aarch64 and Windows installs never saw the update. | |
| # Rebuild the manifest from the signatures actually on the release instead | |
| # of patching whichever partial file survived. | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| set -euo pipefail | |
| V=$(node -p "require('./package.json').version") | |
| TAG="v${V}" | |
| TMP=$(mktemp -d) | |
| BASE="https://github.com/${GITHUB_REPOSITORY}/releases/download/${TAG}" | |
| if ! gh release view "$TAG" >/dev/null 2>&1; then | |
| echo "::error::no release $TAG to build a manifest for; the build legs did not publish" | |
| exit 1 | |
| fi | |
| gh release download "$TAG" --pattern latest.json --dir "$TMP" --clobber | |
| gh release download "$TAG" --pattern '*.sig' --dir "$TMP" --clobber || true | |
| SIGDIR="$TMP" BASE="$BASE" V="$V" node -e ' | |
| const fs = require("fs"); | |
| const path = process.argv[1]; | |
| const dir = process.env.SIGDIR; | |
| const base = process.env.BASE; | |
| const v = process.env.V; | |
| const prior = JSON.parse(fs.readFileSync(path, "utf8")); | |
| const legs = { | |
| "windows-x86_64": ["Aster-Bridge-x64-setup.exe", `Aster.Bridge_${v}_x64-setup.exe`], | |
| "windows-x86_64-nsis": ["Aster-Bridge-x64-setup.exe", `Aster.Bridge_${v}_x64-setup.exe`], | |
| "windows-x86_64-msi": [`Aster.Bridge_${v}_x64_en-US.msi`], | |
| "linux-x86_64": ["Aster-Bridge-x86_64.AppImage", `Aster.Bridge_${v}_amd64.AppImage`], | |
| "linux-x86_64-appimage": ["Aster-Bridge-x86_64.AppImage", `Aster.Bridge_${v}_amd64.AppImage`], | |
| "linux-x86_64-deb": [`Aster.Bridge_${v}_amd64.deb`], | |
| "linux-x86_64-rpm": [`Aster.Bridge-${v}-1.x86_64.rpm`], | |
| "linux-aarch64": ["Aster-Bridge-aarch64.AppImage", `Aster.Bridge_${v}_aarch64.AppImage`], | |
| "linux-aarch64-appimage": ["Aster-Bridge-aarch64.AppImage", `Aster.Bridge_${v}_aarch64.AppImage`], | |
| "linux-aarch64-deb": [`Aster.Bridge_${v}_arm64.deb`], | |
| "linux-aarch64-rpm": [`Aster.Bridge-${v}-1.aarch64.rpm`], | |
| "darwin-aarch64": ["Aster-Bridge-universal.app.tar.gz", `Aster.Bridge_${v}_universal.app.tar.gz`], | |
| "darwin-x86_64": ["Aster-Bridge-universal.app.tar.gz", `Aster.Bridge_${v}_universal.app.tar.gz`], | |
| }; | |
| const manifest = { | |
| version: prior.version || v, | |
| notes: prior.notes || "", | |
| pub_date: prior.pub_date || new Date().toISOString(), | |
| platforms: {}, | |
| }; | |
| for (const [key, candidates] of Object.entries(legs)) { | |
| const hit = candidates.find((f) => fs.existsSync(`${dir}/${f}.sig`)); | |
| if (!hit) { | |
| console.log(`::warning::no signature for ${key} on this release; installs on that platform will not self-update`); | |
| continue; | |
| } | |
| manifest.platforms[key] = { | |
| signature: fs.readFileSync(`${dir}/${hit}.sig`, "utf8").trim(), | |
| url: `${base}/${hit}`, | |
| }; | |
| } | |
| const platforms = Object.keys(manifest.platforms); | |
| console.log("latest.json platforms:", platforms.join(", ")); | |
| const required = ["windows-x86_64", "linux-x86_64"]; | |
| const missing = required.filter((k) => !platforms.includes(k)); | |
| if (missing.length) { | |
| console.log(`::error::latest.json is missing ${missing.join(", ")} - those installs would never self-update`); | |
| process.exit(1); | |
| } | |
| if (!platforms.includes("linux-aarch64")) { | |
| console.log("::warning::latest.json is missing linux-aarch64; ARM installs will not self-update"); | |
| } | |
| if (!platforms.includes("darwin-aarch64")) { | |
| console.log("::warning::no macOS build on this release; Mac installs stay on their current version"); | |
| } | |
| fs.writeFileSync(path, JSON.stringify(manifest, null, 2)); | |
| ' "$TMP/latest.json" | |
| gh release upload "$TAG" "$TMP/latest.json" --clobber | |
| ensure_download_assets: | |
| needs: build | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: Ensure fixed-name bridge download assets exist | |
| # release.yml builds Windows + Linux only; the verify_release_assets.yml guard | |
| # cannot fire on a release created by GITHUB_TOKEN, so carry the macOS dmg over | |
| # from a prior release here, in-run, to stop /api/bridge/v1/download/macos-dmg 404ing. | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| REPO: ${{ github.repository }} | |
| shell: bash | |
| run: | | |
| set -uo pipefail | |
| V=$(node -p "require('./package.json').version" 2>/dev/null || echo "") | |
| if [ -z "$V" ]; then V="${GITHUB_REF_NAME#v}"; fi | |
| TAG="v${V}" | |
| TMP="$(mktemp -d)" | |
| REQUIRED=( | |
| Aster-Bridge-x64-setup.exe | |
| Aster-Bridge-x64.msi | |
| Aster-Bridge-x86_64.AppImage | |
| Aster-Bridge-amd64.deb | |
| Aster-Bridge-x86_64.rpm | |
| Aster-Bridge-universal.dmg | |
| ) | |
| OPTIONAL=( | |
| Aster-Bridge-aarch64.AppImage | |
| Aster-Bridge-arm64.deb | |
| Aster-Bridge-aarch64.rpm | |
| Aster-Bridge-x86_64.pkg.tar.zst | |
| ) | |
| declare -A SRC=( | |
| [Aster-Bridge-x64-setup.exe]="Aster.Bridge_${V}_x64-setup.exe" | |
| [Aster-Bridge-x64.msi]="Aster.Bridge_${V}_x64_en-US.msi" | |
| [Aster-Bridge-x86_64.AppImage]="Aster.Bridge_${V}_amd64.AppImage" | |
| [Aster-Bridge-amd64.deb]="Aster.Bridge_${V}_amd64.deb" | |
| [Aster-Bridge-x86_64.rpm]="Aster.Bridge-${V}-1.x86_64.rpm" | |
| [Aster-Bridge-aarch64.AppImage]="Aster.Bridge_${V}_aarch64.AppImage" | |
| [Aster-Bridge-arm64.deb]="Aster.Bridge_${V}_arm64.deb" | |
| [Aster-Bridge-aarch64.rpm]="Aster.Bridge-${V}-1.aarch64.rpm" | |
| [Aster-Bridge-universal.dmg]="Aster.Bridge_${V}_universal.dmg" | |
| [Aster-Bridge-x86_64.pkg.tar.zst]="aster-bridge-${V}-1-x86_64.pkg.tar.zst" | |
| ) | |
| assets() { gh release view "$TAG" --repo "$REPO" --json assets -q '.assets[].name'; } | |
| has() { assets | grep -qxF "$1"; } | |
| for name in "${REQUIRED[@]}" "${OPTIONAL[@]}"; do | |
| if has "$name"; then echo "ok: $name"; continue; fi | |
| src="${SRC[$name]:-}" | |
| if [ -n "$src" ] && has "$src"; then | |
| echo "::notice::self-healing $name from $src on $TAG" | |
| gh release download "$TAG" --repo "$REPO" --pattern "$src" --dir "$TMP" --clobber | |
| mv "$TMP/$src" "$TMP/$name" | |
| gh release upload "$TAG" "$TMP/$name" --repo "$REPO" --clobber | |
| continue | |
| fi | |
| if [ "$name" = "Aster-Bridge-universal.dmg" ]; then | |
| echo "::warning::no macOS build on $TAG; carrying over the dmg from the most recent release that has one" | |
| for prev in $(gh release list --repo "$REPO" --limit 40 --json tagName,isDraft -q '.[] | select(.isDraft==false) | .tagName'); do | |
| [ "$prev" = "$TAG" ] && continue | |
| if gh release view "$prev" --repo "$REPO" --json assets -q '.assets[].name' | grep -qxF "Aster-Bridge-universal.dmg"; then | |
| gh release download "$prev" --repo "$REPO" --pattern "Aster-Bridge-universal.dmg" --dir "$TMP" --clobber | |
| gh release upload "$TAG" "$TMP/Aster-Bridge-universal.dmg" --repo "$REPO" --clobber | |
| echo "::warning::carried over Aster-Bridge-universal.dmg from $prev - cut a fresh macOS build to replace it" | |
| break | |
| fi | |
| done | |
| continue | |
| fi | |
| done | |
| ABSENT_OPTIONAL=() | |
| for name in "${OPTIONAL[@]}"; do | |
| has "$name" || ABSENT_OPTIONAL+=("$name") | |
| done | |
| if [ ${#ABSENT_OPTIONAL[@]} -ne 0 ]; then | |
| echo "::warning::$TAG is missing optional assets: ${ABSENT_OPTIONAL[*]}. Those download links fall back to an older release." | |
| fi | |
| MISSING=() | |
| for name in "${REQUIRED[@]}"; do | |
| has "$name" || MISSING+=("$name") | |
| done | |
| if [ ${#MISSING[@]} -ne 0 ]; then | |
| echo "::error::Release $TAG is missing bridge download assets: ${MISSING[*]}" | |
| echo "The in-app Bridge downloads (/api/bridge/v1/download/<platform>) for these will 404. See the parent CLAUDE.md 'Website Download Assets'." | |
| exit 1 | |
| fi | |
| echo "All 6 bridge download assets present on $TAG." | |
| gh release edit "$TAG" --repo "$REPO" --prerelease=false --latest | |
| echo "Promoted $TAG to Latest." | |
| attest_provenance: | |
| needs: ensure_download_assets | |
| if: always() | |
| runs-on: ubuntu-22.04 | |
| continue-on-error: true | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| steps: | |
| - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | |
| - name: Download the canonical installers | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| shell: bash | |
| run: | | |
| # Provenance ties each shipped installer to this commit, this workflow | |
| # and this run. It is advisory: the job never blocks a release, so a | |
| # transient signing failure cannot keep an installer off the site. | |
| set -uo pipefail | |
| V=$(node -p "require('./package.json').version" 2>/dev/null || echo "") | |
| if [ -z "$V" ]; then V="${GITHUB_REF_NAME#v}"; fi | |
| TAG="v${V}" | |
| mkdir -p attest | |
| for a in Aster-Bridge-x64-setup.exe Aster-Bridge-x64.msi Aster-Bridge-x86_64.AppImage Aster-Bridge-amd64.deb Aster-Bridge-x86_64.rpm Aster-Bridge-universal.dmg; do | |
| gh release download "$TAG" --pattern "$a" --dir attest --clobber 2>/dev/null || \ | |
| echo "::warning::$a absent on $TAG, not attested" | |
| done | |
| ls -l attest || true | |
| - name: Attest build provenance | |
| uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2 | |
| with: | |
| subject-path: "attest/*" |