Skip to content

feat(hosted): inactive-user TTL reclaim (#4561 P5) (#4577) #4821

feat(hosted): inactive-user TTL reclaim (#4561 P5) (#4577)

feat(hosted): inactive-user TTL reclaim (#4561 P5) (#4577) #4821

Workflow file for this run

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"