Skip to content

v1.16.0 — symbi-shell crate + agentpin 0.3.0 #30

v1.16.0 — symbi-shell crate + agentpin 0.3.0

v1.16.0 — symbi-shell crate + agentpin 0.3.0 #30

Workflow file for this run

name: Publish to crates.io
on:
release:
types: [published]
# Manual re-run (e.g. after a transient runner failure). Publishes whatever
# versions are in the checked-out main; already-published versions are skipped.
workflow_dispatch: {}
env:
CARGO_TERM_COLOR: always
# Least privilege: publishing uses CARGO_REGISTRY_TOKEN, not the GITHUB_TOKEN,
# so the workflow only needs read access to check out the source.
permissions:
contents: read
jobs:
publish:
name: Publish crates
# Restrict CARGO_REGISTRY_TOKEN use to canonical history: a release event
# (runs at the tag) or a manual dispatch from `main`. This stops a
# workflow_dispatch from an arbitrary branch from publishing untrusted code
# to crates.io with the production token.
if: github.event_name == 'release' || github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- name: Free disk space
run: |
# cargo publish verifies each crate by building its full dependency
# tree (incl. the large lance/datafusion/arrow stack) into a shared
# target/, which exhausts the runner's disk. Reclaim space first.
sudo rm -rf /usr/share/dotnet /usr/local/lib/android /opt/ghc /opt/hostedtoolcache/CodeQL
sudo docker image prune --all --force
df -h /
- name: Checkout
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # stable (pinned)
with:
toolchain: stable
- name: Install protoc
run: sudo apt-get install -y protobuf-compiler
- name: Cache cargo registry
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-publish-${{ hashFiles('**/Cargo.lock') }}
- name: Publish crates in dependency order
env:
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
run: |
publish_crate() {
local crate="$1"
echo "::group::Publishing $crate"
# Check if this exact version is already on crates.io
local version
if [ "$crate" = "symbi" ]; then
version=$(cargo metadata --no-deps --format-version=1 | jq -r '.packages[] | select(.name == "symbi") | .version')
else
version=$(cargo metadata --no-deps --format-version=1 | jq -r ".packages[] | select(.name == \"$crate\") | .version")
fi
# Try to check crates.io for existing version
local published
published=$(cargo search "$crate" --limit 1 2>/dev/null | grep "^$crate " | sed 's/.*= "\(.*\)".*/\1/')
if [ "$published" = "$version" ]; then
echo "✓ $crate v$version already published, skipping"
echo "::endgroup::"
return 0
fi
# Publish (capture output to detect "already uploaded" errors)
local output
if [ "$crate" = "symbi" ]; then
output=$(cargo publish 2>&1) || true
else
output=$(cargo publish -p "$crate" 2>&1) || true
fi
echo "$output"
echo "::endgroup::"
# Check if publish succeeded or crate was already uploaded.
# crates.io returns varying messages for already-published versions:
# - "already uploaded" (older cargo)
# - "already exists on crates.io" (current cargo)
# Both are non-fatal for a release workflow — the desired state is
# reached either way.
if echo "$output" | grep -qE "already uploaded|already exists on crates\.io"; then
echo "✓ $crate v$version already published, skipping"
return 0
elif echo "$output" | grep -qE "Published|Uploading.*to registry"; then
echo "✓ Published $crate v$version"
return 0
else
echo "::error::Failed to publish $crate"
return 1
fi
}
# Tier 1: No workspace dependencies
publish_crate symbi-dsl || exit 1
publish_crate symbi-invis-strip || exit 1
publish_crate symbi-approval-relay || exit 1
publish_crate repl-proto || exit 1
echo "Waiting 30s for crates.io index..."
sleep 30
# Tier 2: Depends on symbi-dsl + symbi-invis-strip
publish_crate symbi-runtime || exit 1
echo "Waiting 30s for crates.io index..."
sleep 30
# Tier 3: Depends on symbi-runtime
publish_crate repl-core || exit 1
publish_crate symbi-channel-adapter || exit 1
echo "Waiting 30s for crates.io index..."
sleep 30
# Tier 4: Depends on repl-core, repl-proto, symbi-runtime
publish_crate repl-cli || exit 1
publish_crate repl-lsp || exit 1
publish_crate symbi-shell || exit 1
echo "Waiting 30s for crates.io index..."
sleep 30
# Tier 5: Root binary (depends on symbi-runtime, symbi-dsl, symbi-channel-adapter)
publish_crate symbi || exit 1
echo ""
echo "All crates published successfully!"