name: Release
on:
push:
tags: ["v*"]
permissions:
contents: write
id-token: write
env:
CARGO_TERM_COLOR: always
jobs:
build:
name: Build (${{ matrix.target }})
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include:
- target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
artifact: agentd-linux-x64
- target: x86_64-apple-darwin
runner: macos-latest
artifact: agentd-darwin-x64
- target: aarch64-apple-darwin
runner: macos-latest
artifact: agentd-darwin-arm64
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
with:
key: ${{ matrix.target }}
- name: Build
run: cargo build --release --target ${{ matrix.target }}
- name: Package archive
shell: bash
run: |
VERSION="${GITHUB_REF_NAME#v}"
ARCHIVE="agentd-${VERSION}-${{ matrix.target }}.tar.gz"
tar -czf "${ARCHIVE}" -C target/${{ matrix.target }}/release agentd
echo "ARCHIVE=${ARCHIVE}" >> "$GITHUB_ENV"
- name: Upload binary artifact
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.artifact }}
path: target/${{ matrix.target }}/release/agentd
if-no-files-found: error
- name: Upload archive artifact
uses: actions/upload-artifact@v4
with:
name: archive-${{ matrix.target }}
path: ${{ env.ARCHIVE }}
if-no-files-found: error
github-release:
name: GitHub Release
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
pattern: archive-*
merge-multiple: true
- name: Create release
uses: softprops/action-gh-release@v2
with:
generate_release_notes: true
files: "*.tar.gz"
publish-crates:
name: Publish to crates.io
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- name: Publish crates in dependency order
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_IO_TOKEN }}
run: |
set -euo pipefail
publish() {
local retries=3
for i in $(seq 1 $retries); do
echo "Publishing $1 (attempt $i/$retries)..."
local output
if output=$(cargo publish -p "$1" --no-verify 2>&1); then
echo "Waiting for crates.io to index $1..."
sleep 30
return 0
fi
echo "$output"
if echo "$output" | grep -q "already exists\|already uploaded"; then
echo "$1 already published, skipping"
return 0
fi
echo "Publish failed, waiting 90s before retry..."
sleep 90
done
echo "ERROR: Failed to publish $1 after $retries attempts" >&2
return 1
}
# Leaf crates (no internal deps)
publish smith-bus
publish smith-config
publish smith-attestation
# smith-protocol depends on smith-bus
publish smith-protocol
# smith-logging depends on smith-config, smith-bus
publish smith-logging
# smith-jailer depends on smith-protocol, smith-config
publish smith-jailer
# Root crate depends on all
publish agentd
publish-npm:
name: Publish to npm
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- uses: actions/download-artifact@v4
with:
path: artifacts
- name: Sync versions and place binaries
run: |
VERSION="${GITHUB_REF_NAME#v}"
bash scripts/npm-version-sync.sh "${VERSION}"
for pkg_dir in artifacts/agentd-*/; do
pkg="$(basename "${pkg_dir}")"
if [[ -f "${pkg_dir}/agentd" ]]; then
cp "${pkg_dir}/agentd" "npm/${pkg}/agentd"
chmod +x "npm/${pkg}/agentd"
echo "Placed binary for ${pkg}"
fi
done
- name: Publish packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: bash scripts/npm-publish.sh