build: release 0.2.82 (#4552) #4803
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: Build and Cross-Compile | |
| on: | |
| workflow_dispatch: | |
| # Skip PRs - only build on main and releases to reduce CI costs | |
| push: | |
| branches: [main] | |
| tags: ['v*'] | |
| # Cancel in-progress runs when a new commit is pushed to the same ref. | |
| # On main, never cancel — each merge must complete its build (#3311). | |
| concurrency: | |
| group: cross-compile-${{ github.ref }} | |
| cancel-in-progress: ${{ github.ref != 'refs/heads/main' }} | |
| jobs: | |
| build-x86_64-linux: | |
| name: Build for x86_64-unknown-linux-musl | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.94.0 | |
| targets: x86_64-unknown-linux-musl | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install musl toolchain | |
| run: sudo apt-get update && sudo apt-get install -y musl-tools musl-dev | |
| - name: Compile for x86_64-unknown-linux-musl | |
| # Only build freenet and fdev - cdylib crates (contracts) don't support musl | |
| run: cargo build --release --target x86_64-unknown-linux-musl -p freenet -p fdev | |
| - name: Upload freenet binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-x86_64-linux-freenet | |
| path: target/x86_64-unknown-linux-musl/release/freenet | |
| - name: Upload fdev binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-x86_64-linux-fdev | |
| path: target/x86_64-unknown-linux-musl/release/fdev | |
| build-arm64-linux: | |
| name: Build for aarch64-unknown-linux-musl | |
| runs-on: ubuntu-24.04-arm | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.94.0 | |
| targets: aarch64-unknown-linux-musl | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Install musl toolchain | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y musl-tools musl-dev | |
| - name: Compile for aarch64-unknown-linux-musl | |
| # Only build freenet and fdev - cdylib crates (contracts) don't support musl | |
| run: cargo build --release --target aarch64-unknown-linux-musl -p freenet -p fdev | |
| - name: Upload freenet binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-arm64-linux-freenet | |
| path: target/aarch64-unknown-linux-musl/release/freenet | |
| - name: Upload fdev binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-arm64-linux-fdev | |
| path: target/aarch64-unknown-linux-musl/release/fdev | |
| build-arm64-macos: | |
| name: Build for aarch64-apple-darwin | |
| runs-on: macos-latest # Apple Silicon runner | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.94.0 | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Compile for aarch64-apple-darwin | |
| env: | |
| # Support macOS 11 (Big Sur) and later for broader compatibility | |
| MACOSX_DEPLOYMENT_TARGET: "11.0" | |
| # Force static linking of liblzma to avoid dependency on Homebrew's xz | |
| # Without this, the binary links to /opt/homebrew/opt/xz/lib/liblzma.5.dylib | |
| # which doesn't exist on fresh macOS installations | |
| LZMA_API_STATIC: "1" | |
| run: cargo build --release | |
| - name: Ad-hoc sign binaries | |
| run: | | |
| # Ad-hoc sign binaries so they can run without Gatekeeper blocking | |
| codesign -s - --force target/release/freenet | |
| codesign -s - --force target/release/fdev | |
| # Verify signatures | |
| codesign -v target/release/freenet | |
| codesign -v target/release/fdev | |
| - name: Upload freenet binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-arm64-macos-freenet | |
| path: target/release/freenet | |
| - name: Upload fdev binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-arm64-macos-fdev | |
| path: target/release/fdev | |
| build-x86_64-macos: | |
| name: Build for x86_64-apple-darwin | |
| runs-on: macos-latest # Cross-compile from Apple Silicon to x86_64 | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.94.0 | |
| targets: x86_64-apple-darwin | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Compile for x86_64-apple-darwin | |
| env: | |
| # Support macOS 11 (Big Sur) and later - the last version to support Intel Macs | |
| MACOSX_DEPLOYMENT_TARGET: "11.0" | |
| # Force static linking of liblzma to avoid dependency on Homebrew's xz | |
| LZMA_API_STATIC: "1" | |
| run: cargo build --release --target x86_64-apple-darwin -p freenet -p fdev | |
| - name: Ad-hoc sign binaries | |
| run: | | |
| # Ad-hoc sign binaries so they can run without Gatekeeper blocking | |
| codesign -s - --force target/x86_64-apple-darwin/release/freenet | |
| codesign -s - --force target/x86_64-apple-darwin/release/fdev | |
| # Verify signatures | |
| codesign -v target/x86_64-apple-darwin/release/freenet | |
| codesign -v target/x86_64-apple-darwin/release/fdev | |
| - name: Upload freenet binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-x86_64-macos-freenet | |
| path: target/x86_64-apple-darwin/release/freenet | |
| - name: Upload fdev binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-x86_64-macos-fdev | |
| path: target/x86_64-apple-darwin/release/fdev | |
| build-x86_64-windows: | |
| name: Build for x86_64-pc-windows-msvc | |
| runs-on: windows-latest | |
| timeout-minutes: 60 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: 1.94.0 | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Compile for x86_64-pc-windows-msvc | |
| run: cargo build --release | |
| - name: Smoke test | |
| run: | | |
| target/release/freenet.exe --version | |
| target/release/freenet.exe service --help | |
| - name: Upload freenet binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-x86_64-windows-freenet | |
| path: target/release/freenet.exe | |
| - name: Upload fdev binary | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: binaries-x86_64-windows-fdev | |
| path: target/release/fdev.exe | |
| build-macos-dmg: | |
| name: Build Freenet.dmg (universal, signed + notarized) | |
| runs-on: macos-latest | |
| timeout-minutes: 30 | |
| needs: [build-arm64-macos, build-x86_64-macos] | |
| # Run on release tags (the normal path) OR on manual workflow_dispatch | |
| # invocations (so maintainers can produce a signed test DMG from any | |
| # branch without cutting a release). We intentionally skip PR builds | |
| # and regular main-push builds so we don't burn Apple notarization | |
| # quota on every commit and so fork PRs can't see the signing secrets. | |
| if: | | |
| startsWith(github.ref, 'refs/tags/v') | |
| || github.event_name == 'workflow_dispatch' | |
| steps: | |
| - uses: actions/checkout@v7 | |
| - name: Download ARM64 macOS freenet binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-arm64-macos-freenet | |
| path: bin-arm64 | |
| - name: Download x86_64 macOS freenet binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-x86_64-macos-freenet | |
| path: bin-x86_64 | |
| - name: Install packaging dependencies | |
| run: | | |
| brew install create-dmg librsvg | |
| - name: Generate app icon from SVG | |
| run: | | |
| ICON_PATH="$RUNNER_TEMP/freenet.icns" | |
| ./scripts/generate-macos-icns.sh \ | |
| crates/core/src/bin/commands/assets/freenet_logo.svg \ | |
| "$ICON_PATH" | |
| echo "ICON_ICNS=$ICON_PATH" >> "$GITHUB_ENV" | |
| - name: Import Developer ID signing certificate | |
| env: | |
| P12_BASE64: ${{ secrets.APPLE_DEVELOPER_ID_P12_BASE64 }} | |
| P12_PASSWORD: ${{ secrets.APPLE_DEVELOPER_ID_P12_PASSWORD }} | |
| run: | | |
| # Decode the .p12 into a file that `security import` can read. | |
| CERT_PATH="$RUNNER_TEMP/cert.p12" | |
| echo "$P12_BASE64" | base64 -d > "$CERT_PATH" | |
| # Stand up an ephemeral keychain for this job. | |
| KEYCHAIN_PATH="$RUNNER_TEMP/build.keychain-db" | |
| KEYCHAIN_PASSWORD="$(uuidgen)" | |
| 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 the cert and authorize codesign to use it without prompts. | |
| security import "$CERT_PATH" -k "$KEYCHAIN_PATH" \ | |
| -P "$P12_PASSWORD" -T /usr/bin/codesign | |
| security set-key-partition-list \ | |
| -S apple-tool:,apple:,codesign: \ | |
| -s -k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH" | |
| # Make the new keychain the default search so codesign finds the cert. | |
| security list-keychains -d user -s "$KEYCHAIN_PATH" \ | |
| $(security list-keychains -d user | tr -d '"') | |
| rm "$CERT_PATH" | |
| - name: Decode App Store Connect API key | |
| env: | |
| P8_BASE64: ${{ secrets.APPLE_ASC_API_KEY_P8_BASE64 }} | |
| run: | | |
| # notarytool reads the key from a file path at submit time. | |
| KEY_PATH="$RUNNER_TEMP/AuthKey.p8" | |
| echo "$P8_BASE64" | base64 -d > "$KEY_PATH" | |
| chmod 600 "$KEY_PATH" | |
| echo "ASC_API_KEY_PATH=$KEY_PATH" >> "$GITHUB_ENV" | |
| - name: Extract freenet version from Cargo.toml | |
| id: version | |
| run: | | |
| V=$(grep '^version' crates/core/Cargo.toml | head -1 | cut -d'"' -f2) | |
| echo "version=$V" >> "$GITHUB_OUTPUT" | |
| echo "Freenet version: $V" | |
| - name: Build signed + notarized Freenet.dmg | |
| env: | |
| VERSION: ${{ steps.version.outputs.version }} | |
| FREENET_ARM64_BIN: bin-arm64/freenet | |
| FREENET_X86_BIN: bin-x86_64/freenet | |
| CODESIGN_IDENTITY: "Developer ID Application: Ian CLARKE (R55ZESJCXG)" | |
| ASC_API_KEY_ID: ${{ secrets.APPLE_ASC_API_KEY_ID }} | |
| ASC_API_ISSUER_ID: ${{ secrets.APPLE_ASC_API_KEY_ISSUER_ID }} | |
| # ASC_API_KEY_PATH set by the previous step via $GITHUB_ENV. | |
| run: | | |
| chmod +x bin-arm64/freenet bin-x86_64/freenet | |
| ./scripts/package-macos.sh | |
| - name: Clean up secrets from runner | |
| if: always() | |
| run: | | |
| rm -f "$RUNNER_TEMP/AuthKey.p8" || true | |
| # The ephemeral keychain is removed automatically when the runner | |
| # VM is torn down, but belt-and-braces: delete it explicitly. | |
| security delete-keychain "$RUNNER_TEMP/build.keychain-db" 2>/dev/null || true | |
| - name: Upload DMG as workflow artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: freenet-macos-universal-dmg | |
| path: dist/macos/Freenet-*.dmg | |
| attach-to-release: | |
| name: Attach binaries to GitHub release | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| needs: [build-x86_64-linux, build-arm64-linux, build-arm64-macos, build-x86_64-macos, build-x86_64-windows, build-macos-dmg] | |
| if: startsWith(github.ref, 'refs/tags/v') | |
| permissions: | |
| contents: write | |
| steps: | |
| # Linux x86_64 | |
| - name: Download x86_64 Linux freenet binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-x86_64-linux-freenet | |
| path: artifacts/x86_64-linux-freenet | |
| - name: Download x86_64 Linux fdev binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-x86_64-linux-fdev | |
| path: artifacts/x86_64-linux-fdev | |
| # Linux ARM64 | |
| - name: Download ARM64 Linux freenet binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-arm64-linux-freenet | |
| path: artifacts/arm64-linux-freenet | |
| - name: Download ARM64 Linux fdev binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-arm64-linux-fdev | |
| path: artifacts/arm64-linux-fdev | |
| # macOS ARM64 | |
| - name: Download ARM64 macOS freenet binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-arm64-macos-freenet | |
| path: artifacts/arm64-macos-freenet | |
| - name: Download ARM64 macOS fdev binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-arm64-macos-fdev | |
| path: artifacts/arm64-macos-fdev | |
| # macOS x86_64 | |
| - name: Download x86_64 macOS freenet binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-x86_64-macos-freenet | |
| path: artifacts/x86_64-macos-freenet | |
| - name: Download x86_64 macOS fdev binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-x86_64-macos-fdev | |
| path: artifacts/x86_64-macos-fdev | |
| # Windows x86_64 | |
| - name: Download x86_64 Windows freenet binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-x86_64-windows-freenet | |
| path: artifacts/x86_64-windows-freenet | |
| - name: Download x86_64 Windows fdev binary | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: binaries-x86_64-windows-fdev | |
| path: artifacts/x86_64-windows-fdev | |
| # macOS universal DMG (signed + notarized) | |
| - name: Download Freenet.dmg | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: freenet-macos-universal-dmg | |
| path: artifacts/macos-dmg | |
| - name: Prepare release assets | |
| run: | | |
| # Create tar.gz files for each binary with binstall-compatible naming | |
| # Linux x86_64 (musl for maximum compatibility) | |
| cd artifacts/x86_64-linux-freenet && tar -czvf ../../freenet-x86_64-unknown-linux-musl.tar.gz freenet && cd ../.. | |
| cd artifacts/x86_64-linux-fdev && tar -czvf ../../fdev-x86_64-unknown-linux-musl.tar.gz fdev && cd ../.. | |
| # Linux ARM64 (musl for maximum compatibility) | |
| cd artifacts/arm64-linux-freenet && tar -czvf ../../freenet-aarch64-unknown-linux-musl.tar.gz freenet && cd ../.. | |
| cd artifacts/arm64-linux-fdev && tar -czvf ../../fdev-aarch64-unknown-linux-musl.tar.gz fdev && cd ../.. | |
| # macOS ARM64 | |
| cd artifacts/arm64-macos-freenet && tar -czvf ../../freenet-aarch64-apple-darwin.tar.gz freenet && cd ../.. | |
| cd artifacts/arm64-macos-fdev && tar -czvf ../../fdev-aarch64-apple-darwin.tar.gz fdev && cd ../.. | |
| # macOS x86_64 | |
| cd artifacts/x86_64-macos-freenet && tar -czvf ../../freenet-x86_64-apple-darwin.tar.gz freenet && cd ../.. | |
| cd artifacts/x86_64-macos-fdev && tar -czvf ../../fdev-x86_64-apple-darwin.tar.gz fdev && cd ../.. | |
| # Windows x86_64 (zip for backwards compat + bare exe for direct download) | |
| cd artifacts/x86_64-windows-freenet && zip ../../freenet-x86_64-pc-windows-msvc.zip freenet.exe && cd ../.. | |
| cd artifacts/x86_64-windows-fdev && zip ../../fdev-x86_64-pc-windows-msvc.zip fdev.exe && cd ../.. | |
| cp artifacts/x86_64-windows-freenet/freenet.exe freenet.exe | |
| # macOS universal installer (signed + notarized) | |
| # Upload both the versioned name (Freenet-X.Y.Z.dmg) and a | |
| # stable alias (Freenet.dmg) so the quickstart page can link | |
| # to /releases/latest/download/Freenet.dmg without hardcoding | |
| # a version. | |
| cp artifacts/macos-dmg/Freenet-*.dmg . | |
| cp artifacts/macos-dmg/Freenet-*.dmg Freenet.dmg | |
| # Display the created files | |
| ls -lh *.tar.gz *.zip *.exe *.dmg | |
| - name: Generate SHA256 checksums | |
| run: | | |
| # Generate checksums for all available release assets | |
| sha256sum *.tar.gz *.zip *.exe *.dmg 2>/dev/null > SHA256SUMS.txt || true | |
| # Display checksums | |
| echo "=== SHA256 Checksums ===" | |
| cat SHA256SUMS.txt | |
| - name: Upload binaries to release | |
| env: | |
| # Coalesce on RELEASE_PAT so the `gh release edit --draft=false` | |
| # below fires a `release.published` event that downstream workflows | |
| # (`gateway-update.yml`, `release-announce.yml`) can react to. | |
| # GITHUB_TOKEN suppresses workflow-triggering events as an | |
| # anti-recursion safeguard, which broke the v0.2.57 release | |
| # cascade and required manual `workflow_dispatch`. See issue #4118 | |
| # and `AGENTS.md` → "Release Workflow & RELEASE_PAT". | |
| GH_TOKEN: ${{ secrets.RELEASE_PAT || secrets.GITHUB_TOKEN }} | |
| run: | | |
| # Extract the tag name (e.g., v0.1.30) | |
| TAG_NAME="${GITHUB_REF#refs/tags/}" | |
| # Collect all release assets | |
| ASSETS="" | |
| for f in *.tar.gz *.zip *.exe *.dmg; do | |
| [ -f "$f" ] && ASSETS="$ASSETS $f" | |
| done | |
| ASSETS="$ASSETS SHA256SUMS.txt" | |
| # Upload all available archives and checksums to the release | |
| gh release upload "$TAG_NAME" $ASSETS \ | |
| --repo ${{ github.repository }} \ | |
| --clobber | |
| # Publish the release now that binaries are attached. | |
| # The release is created as a draft by release.sh/release.yml to | |
| # prevent the installer from seeing a version before binaries exist. | |
| gh release edit "$TAG_NAME" \ | |
| --repo ${{ github.repository }} \ | |
| --draft=false | |
| echo "✅ Release $TAG_NAME published with all binaries attached" |