Skip to content

Bump rust from 1.95-bookworm to 1.96-bookworm #222

Bump rust from 1.95-bookworm to 1.96-bookworm

Bump rust from 1.95-bookworm to 1.96-bookworm #222

Workflow file for this run

# =============================================================================
# StealthOS Relay Server — CI/CD Pipeline
# =============================================================================
# Runs on every push/PR to main and on version tags.
# Tag a release with: git tag v0.1.0 && git push --tags
name: Release
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
branches: [main]
env:
CARGO_TERM_COLOR: always
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/stealth-relay
permissions:
contents: read
jobs:
# ---------------------------------------------------------------------------
# Lint, test, audit
# ---------------------------------------------------------------------------
check:
name: Check & Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cache cargo registry & build
uses: actions/cache@v5
with:
path: |
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: ${{ runner.os }}-cargo-
- name: Check formatting
run: cargo fmt --check --all
- name: Clippy lints
run: cargo clippy --workspace -- -D warnings
- name: Run tests
run: cargo test --workspace
- name: Install cargo-audit
run: cargo install cargo-audit --locked
- name: Security audit
run: cargo audit
# ---------------------------------------------------------------------------
# Cross-compile native binaries for all supported platforms
# ---------------------------------------------------------------------------
binaries:
name: Build binary (${{ matrix.artifact }})
needs: check
if: startsWith(github.ref, 'refs/tags/v')
permissions:
contents: write
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
artifact: stealth-relay-linux-amd64
use_cross: true
- target: aarch64-unknown-linux-gnu
os: ubuntu-latest
artifact: stealth-relay-linux-arm64
use_cross: true
- target: x86_64-apple-darwin
os: macos-latest
artifact: stealth-relay-darwin-amd64
use_cross: false
- target: aarch64-apple-darwin
os: macos-latest
artifact: stealth-relay-darwin-arm64
use_cross: false
- target: x86_64-pc-windows-msvc
os: windows-latest
artifact: stealth-relay-windows-amd64.exe
use_cross: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- name: Set version from git tag
shell: bash
run: |
VERSION="${GITHUB_REF_NAME#v}"
echo "Setting workspace version to $VERSION"
sed -i.bak "s/^version = .*/version = \"$VERSION\"/" Cargo.toml
rm -f Cargo.toml.bak
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install cross
if: matrix.use_cross
run: cargo install cross --locked
- name: Build (cross)
if: matrix.use_cross
run: cross build --release -p stealthos-server --target ${{ matrix.target }}
- name: Build (cargo)
if: ${{ !matrix.use_cross }}
run: cargo build --release -p stealthos-server --target ${{ matrix.target }}
env:
# Static link the C runtime on Windows so the binary has no VCRUNTIME dependency
RUSTFLAGS: ${{ matrix.os == 'windows-latest' && '-C target-feature=+crt-static' || '' }}
- name: Sign and notarize macOS binary
if: runner.os == 'macOS'
env:
APPLE_CERTIFICATE_B64: ${{ secrets.APPLE_CERTIFICATE_B64 }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_APP_PASSWORD: ${{ secrets.APPLE_APP_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
run: |
# Decode certificate
echo "$APPLE_CERTIFICATE_B64" | base64 --decode > /tmp/certificate.p12
# Create temporary keychain
KEYCHAIN_PATH="/tmp/build.keychain-db"
KEYCHAIN_PASSWORD="$(openssl rand -hex 16)"
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 and Apple WWDR intermediate
security import /tmp/certificate.p12 -P "$APPLE_CERTIFICATE_PASSWORD" \
-A -t cert -f pkcs12 -k "$KEYCHAIN_PATH"
curl -sO https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer
security import DeveloperIDG2CA.cer -k "$KEYCHAIN_PATH"
security set-key-partition-list -S apple-tool:,apple: \
-k "$KEYCHAIN_PASSWORD" "$KEYCHAIN_PATH"
security list-keychains -d user -s "$KEYCHAIN_PATH" login.keychain-db
# Find signing identity
IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" \
| grep "Developer ID Application" | head -1 | awk -F'"' '{print $2}')
echo "Signing with: $IDENTITY"
# Sign the binary (hardened runtime required for notarization)
BINARY="target/${{ matrix.target }}/release/stealth-relay"
codesign --force --options runtime --sign "$IDENTITY" --timestamp "$BINARY"
# Create zip for notarization (notarytool requires zip/dmg/pkg)
ditto -c -k "$BINARY" /tmp/notarize.zip
# Submit for notarization (don't block — Apple can take 30+ min).
# The binary is already code-signed, which prevents Gatekeeper warnings.
# Notarization adds offline verification and completes asynchronously.
xcrun notarytool submit /tmp/notarize.zip \
--apple-id "$APPLE_ID" \
--password "$APPLE_APP_PASSWORD" \
--team-id "$APPLE_TEAM_ID" || true
# Cleanup
security delete-keychain "$KEYCHAIN_PATH"
rm -f /tmp/certificate.p12 /tmp/notarize.zip DeveloperIDG2CA.cer
- name: Rename binary
shell: bash
run: |
src="target/${{ matrix.target }}/release/stealth-relay"
if [[ "${{ matrix.artifact }}" == *.exe ]]; then
src="${src}.exe"
fi
cp "$src" "${{ matrix.artifact }}"
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: ${{ matrix.artifact }}
path: ${{ matrix.artifact }}
# ---------------------------------------------------------------------------
# Create GitHub Release with binaries and SHA256 checksums
# ---------------------------------------------------------------------------
release:
name: GitHub Release
needs: binaries
if: startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: artifacts/
merge-multiple: true
- name: Generate SHA256 checksums
run: |
cd artifacts
sha256sum stealth-relay-* > SHA256SUMS.txt
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
with:
files: artifacts/*
generate_release_notes: true
# ---------------------------------------------------------------------------
# Multi-arch Docker build + push
# ---------------------------------------------------------------------------
docker:
name: Docker Build & Push
needs: check
runs-on: ubuntu-latest
if: github.event_name == 'push'
permissions:
contents: read
packages: write
id-token: write # Required for cosign OIDC signing.
steps:
- uses: actions/checkout@v6
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Set up QEMU (for arm64 cross-compilation)
uses: docker/setup-qemu-action@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v4
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels)
id: meta
uses: docker/metadata-action@v6
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,prefix=
- name: Extract version from ref
id: version
run: |
if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
echo "value=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
else
echo "value=" >> "$GITHUB_OUTPUT"
fi
- name: Build and push multi-arch image
uses: docker/build-push-action@v7
id: build
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: STEALTH_VERSION=${{ steps.version.outputs.value }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Install cosign
uses: sigstore/cosign-installer@v3
- name: Sign container image
env:
DIGEST: ${{ steps.build.outputs.digest }}
IMAGE_REF: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
run: |
IMAGE_LOWER=$(echo "$IMAGE_REF" | tr '[:upper:]' '[:lower:]')
cosign sign --yes "${IMAGE_LOWER}@${DIGEST}"