From b2defa71ee97de082f52feac12397a95f451ac7e Mon Sep 17 00:00:00 2001 From: t8y2 Date: Mon, 28 Sep 2026 01:21:32 +0800 Subject: [PATCH] ci(macos): compare native and cross Intel builds --- .../macos-intel-cross-compile-experiment.yml | 203 ++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 .github/workflows/macos-intel-cross-compile-experiment.yml diff --git a/.github/workflows/macos-intel-cross-compile-experiment.yml b/.github/workflows/macos-intel-cross-compile-experiment.yml new file mode 100644 index 000000000..67c35b17d --- /dev/null +++ b/.github/workflows/macos-intel-cross-compile-experiment.yml @@ -0,0 +1,203 @@ +name: macOS Intel Cross-Compile Experiment + +on: + push: + branches: + - dev/macos-arm-cross-intel-test + +permissions: + contents: read + +concurrency: + group: macos-intel-cross-compile-${{ github.ref }}-${{ github.run_attempt }} + cancel-in-progress: false + +env: + CARGO_INCREMENTAL: "0" + RUSTFLAGS: -C debuginfo=line-tables-only + RUSTC_WRAPPER: sccache + SCCACHE_GHA_ENABLED: ${{ secrets.SCCACHE_S3_BUCKET == '' && 'true' || 'false' }} + +jobs: + build: + name: x86_64 macOS (${{ matrix.mode }}) + strategy: + fail-fast: false + matrix: + include: + - mode: native-intel + platform: macos-15-intel + expected_host_arch: x86_64 + - mode: arm-cross + platform: macos-latest + expected_host_arch: arm64 + runs-on: ${{ matrix.platform }} + steps: + - uses: actions/checkout@v5 + + - name: Record runner hardware + shell: bash + run: | + set -euo pipefail + actual_arch=$(uname -m) + test "$actual_arch" = "${{ matrix.expected_host_arch }}" + { + echo "### ${{ matrix.mode }}" + echo + echo "- Runner: \`${{ matrix.platform }}\`" + echo "- Host architecture: \`${actual_arch}\`" + echo "- CPU: \`$(sysctl -n machdep.cpu.brand_string 2>/dev/null || true)\`" + echo "- Logical CPUs: \`$(sysctl -n hw.logicalcpu)\`" + echo "- Memory bytes: \`$(sysctl -n hw.memsize)\`" + } >> "$GITHUB_STEP_SUMMARY" + + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: 22 + + - name: Setup pnpm + uses: pnpm/action-setup@v6 + + - name: Install frontend dependencies + run: pnpm install + + - name: Setup Rust + uses: dtolnay/rust-toolchain@1.97.1 + with: + targets: x86_64-apple-darwin + + - name: Setup sccache + uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10 + with: + version: "v0.10.0" + + - name: Configure S3 sccache + if: env.SCCACHE_GHA_ENABLED != 'true' + shell: bash + env: + CACHE_BUCKET: ${{ secrets.SCCACHE_S3_BUCKET }} + CACHE_ENDPOINT: ${{ secrets.SCCACHE_S3_ENDPOINT }} + CACHE_REGION: ${{ secrets.SCCACHE_S3_REGION }} + CACHE_KEY_PREFIX: ${{ secrets.SCCACHE_S3_KEY_PREFIX }} + CACHE_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }} + CACHE_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }} + run: | + { + echo "SCCACHE_BUCKET=${CACHE_BUCKET}" + echo "SCCACHE_ENDPOINT=${CACHE_ENDPOINT}" + echo "SCCACHE_REGION=${CACHE_REGION}" + echo "SCCACHE_S3_KEY_PREFIX=${CACHE_KEY_PREFIX}" + echo "SCCACHE_S3_USE_SSL=true" + echo "AWS_ACCESS_KEY_ID=${CACHE_ACCESS_KEY_ID}" + echo "AWS_SECRET_ACCESS_KEY=${CACHE_SECRET_ACCESS_KEY}" + echo "SCCACHE_IDLE_TIMEOUT=0" + echo "CC=${SCCACHE_PATH} clang" + echo "CXX=${SCCACHE_PATH} clang++" + } >> "$GITHUB_ENV" + + - name: Compute Rust dependency hash + id: deps-hash + shell: bash + run: | + { + find . -name Cargo.toml -not -path './target/*' -print0 \ + | sort -z \ + | xargs -0 sed -E '/^version = /d' + grep -v '^version = ' Cargo.lock + } | sha256sum | cut -d' ' -f1 | { + read -r hash + echo "hash=${hash:0:20}" >> "$GITHUB_OUTPUT" + } + + - name: Rust cache + uses: swatinem/rust-cache@v2 + with: + workspaces: "./ -> target" + shared-key: experiment-${{ matrix.mode }}-x86_64-apple-darwin-${{ steps.deps-hash.outputs.hash }} + add-rust-environment-hash-key: false + cache-targets: false + cache-on-failure: true + + - name: Install Apple certificate + env: + APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + run: | + set -euo pipefail + test -n "$APPLE_CERTIFICATE" + CERTIFICATE_PATH=$RUNNER_TEMP/certificate.p12 + KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db + echo -n "$APPLE_CERTIFICATE" | base64 --decode -o "$CERTIFICATE_PATH" + security create-keychain -p "" "$KEYCHAIN_PATH" + security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH" + security unlock-keychain -p "" "$KEYCHAIN_PATH" + security import "$CERTIFICATE_PATH" -P "$APPLE_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k "$KEYCHAIN_PATH" + security set-key-partition-list -S apple-tool:,apple: -k "" "$KEYCHAIN_PATH" + security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db + + - name: Setup Tauri signing key + shell: bash + run: | + echo "${{ secrets.TAURI_SIGNING_PRIVATE_KEY_BASE64 }}" | base64 --decode > "$RUNNER_TEMP/updater.key" + KEY_B64=$(base64 < "$RUNNER_TEMP/updater.key" | tr -d '\r\n') + echo "TAURI_SIGNING_PRIVATE_KEY=$KEY_B64" >> "$GITHUB_ENV" + if [ -n "${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}" ]; then + echo "TAURI_SIGNING_PRIVATE_KEY_PASSWORD=${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}" >> "$GITHUB_ENV" + fi + + - name: Build signed and notarized Intel app + id: build + shell: bash + env: + APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} + run: | + set -euo pipefail + test -n "$APPLE_SIGNING_IDENTITY" + test -n "$APPLE_ID" + test -n "$APPLE_PASSWORD" + test -n "$APPLE_TEAM_ID" + started_at=$(date +%s) + pnpm tauri build --target x86_64-apple-darwin + completed_at=$(date +%s) + duration_seconds=$((completed_at - started_at)) + echo "duration_seconds=$duration_seconds" >> "$GITHUB_OUTPUT" + echo "- Build duration: **$((duration_seconds / 60))m $((duration_seconds % 60))s**" >> "$GITHUB_STEP_SUMMARY" + + - name: Verify Intel artifacts + shell: bash + run: | + set -euo pipefail + app_path="target/x86_64-apple-darwin/release/bundle/macos/DBX.app" + dmg_path=$(find target/x86_64-apple-darwin/release/bundle/dmg -maxdepth 1 -name '*.dmg' -print -quit) + binary_path="$app_path/Contents/MacOS/dbx" + test -d "$app_path" + test -f "$binary_path" + test -n "$dmg_path" + lipo -archs "$binary_path" | grep -qw x86_64 + codesign --verify --deep --strict --verbose=2 "$app_path" + spctl --assess --type execute --verbose=2 "$app_path" + xcrun stapler validate "$app_path" + { + echo "- Binary: \`$(file "$binary_path")\`" + echo "- App signature: verified" + echo "- Gatekeeper assessment: accepted" + echo "- App notarization ticket: validated" + } >> "$GITHUB_STEP_SUMMARY" + + - name: Upload Intel DMG + uses: actions/upload-artifact@v4 + with: + name: dbx-intel-${{ matrix.mode }}-${{ github.run_attempt }} + path: target/x86_64-apple-darwin/release/bundle/dmg/*.dmg + if-no-files-found: error + retention-days: 3 + + - name: Show sccache stats + if: always() + continue-on-error: true + shell: bash + run: ${SCCACHE_PATH} --show-stats