publish (manual) #31
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 (manual) | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| dry-run: | |
| description: "Dry run (no actual publish)" | |
| required: false | |
| default: "false" | |
| type: boolean | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| publish: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: dtolnay/rust-toolchain@stable | |
| - uses: Swatinem/rust-cache@v2 | |
| - name: Publish workspace crates in dependency order | |
| run: | | |
| DRY_RUN="${{ inputs.dry-run }}" | |
| EXTRA_ARGS="" | |
| if [ "$DRY_RUN" = "true" ]; then | |
| EXTRA_ARGS="--dry-run" | |
| echo "DRY RUN MODE -- no crates will be published" | |
| fi | |
| # Dependency order: leaves first, umbrella last. | |
| # Topo-sorted from the workspace dependency graph. | |
| CRATES=( | |
| # Tier 0: no internal deps | |
| layer0 | |
| neuron-tool | |
| # Tier 1: depend only on tier 0 | |
| neuron-effects-core | |
| neuron-secret | |
| neuron-crypto | |
| neuron-hooks | |
| neuron-hook-security | |
| neuron-state-memory | |
| neuron-state-fs | |
| neuron-turn | |
| neuron-mcp | |
| neuron-orch-local | |
| # Tier 2: depend on tier 1 | |
| neuron-effects-local | |
| neuron-orch-kit | |
| neuron-auth | |
| neuron-env-local | |
| neuron-turn-kit | |
| neuron-context | |
| neuron-op-single-shot | |
| # Tier 3: depend on tier 2 | |
| neuron-auth-static | |
| neuron-auth-file | |
| neuron-auth-oidc | |
| neuron-auth-k8s | |
| neuron-secret-env | |
| neuron-secret-keystore | |
| neuron-secret-vault | |
| neuron-secret-aws | |
| neuron-secret-gcp | |
| neuron-secret-k8s | |
| neuron-crypto-vault | |
| neuron-crypto-hardware | |
| neuron-op-react | |
| # Tier 4: depend on many crates | |
| neuron-provider-anthropic | |
| neuron-provider-openai | |
| neuron-provider-ollama | |
| # Umbrella (last) | |
| neuron | |
| ) | |
| for crate in "${CRATES[@]}"; do | |
| # Skip comments | |
| [[ "$crate" == '#'* ]] && continue | |
| echo "::group::$crate" | |
| # --no-verify skips rebuild (CI already validated). | |
| # Retry up to 3 times with 30s delay for index propagation. | |
| PUBLISHED=false | |
| SKIPPED=false | |
| for attempt in 1 2 3; do | |
| OUTPUT=$(cargo publish -p "$crate" --no-verify $EXTRA_ARGS 2>&1) && { | |
| echo "Published $crate successfully" | |
| PUBLISHED=true | |
| break | |
| } | |
| if echo "$OUTPUT" | grep -qE "already uploaded|already exists"; then | |
| echo "$crate already published, skipping" | |
| SKIPPED=true | |
| break | |
| fi | |
| if [ "$attempt" -lt 3 ]; then | |
| echo "Attempt $attempt failed, waiting 90s for index propagation / rate limit..." | |
| echo "$OUTPUT" | |
| sleep 90 | |
| fi | |
| done | |
| echo "::endgroup::" | |
| if [ "$PUBLISHED" = "false" ] && [ "$SKIPPED" = "false" ]; then | |
| echo "$OUTPUT" | |
| echo "::error::Failed to publish $crate after 3 attempts" | |
| exit 1 | |
| fi | |
| # Only sleep after a real publish (not a skip) to stay under rate limit. | |
| if [ "$PUBLISHED" = "true" ]; then | |
| sleep 65 # pause for rate limit: crates.io allows ~6 new crates per 5 min window | |
| fi | |
| done | |
| echo "All crates published successfully" | |
| env: | |
| CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} |