Skip to content

Publish Crates

Publish Crates #3

name: Publish Crates
on:
workflow_dispatch:
inputs:
crate_list:
description: Space-separated crate package names to publish in order
required: true
type: string
dry_run:
description: Run cargo publish --dry-run only
required: false
default: "true"
type: choice
options: ["true", "false"]
env:
CARGO_TERM_COLOR: always
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- uses: 1password/install-cli-action@v2
- name: Verify 1Password service account secret
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
run: |
if [ -z "$OP_SERVICE_ACCOUNT_TOKEN" ]; then
echo "ERROR: OP_SERVICE_ACCOUNT_TOKEN secret is not configured." >&2
echo "Set it as a repository or organisation secret to enable crates.io publishing." >&2
exit 1
fi
- name: Get crates.io token from 1Password
id: token
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
run: |
TOKEN=$(op read "op://TerraphimPlatform/crates.io.token/token")
echo "token=$TOKEN" >> $GITHUB_OUTPUT
- name: Publish crates in dependency order
env:
CARGO_REGISTRY_TOKEN: ${{ steps.token.outputs.token }}
CRATE_LIST: ${{ inputs.crate_list }}
DRY_RUN: ${{ inputs.dry_run }}
run: |
set -euo pipefail
for crate in $CRATE_LIST; do
manifest="crates/$crate/Cargo.toml"
if [ ! -f "$manifest" ]; then
echo "Missing manifest for $crate at $manifest" >&2
exit 1
fi
version=$(grep -m1 '^version' "$manifest" | sed 's/.*"\(.*\)".*/\1/')
if curl -fsS "https://crates.io/api/v1/crates/$crate/$version" >/dev/null 2>&1; then
echo "$crate $version already exists on crates.io; skipping"
continue
fi
if [ "$DRY_RUN" = "true" ]; then
cargo publish --manifest-path "$manifest" --dry-run
else
cargo publish --manifest-path "$manifest"
fi
done