v1.16.0 — symbi-shell crate + agentpin 0.3.0 #30
Workflow file for this run
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: 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!" |