1 name: Release SDK Rust (crates.io)
2
3 on:
4 push:
5 tags:
6 - "[0-9]+.[0-9]+.[0-9]+"
7 workflow_dispatch:
8
9 permissions:
10 contents: read
11
12 jobs:
13 # Cheap ubuntu gate: version agreement, crates.io publishability, tag match.
14 # Blocks the expensive job below so a metadata fault never costs runner time.
15 preflight:
16 uses: ./.github/workflows/release-preflight.yml
17 with:
18 tag: ${{ github.ref_type == 'tag' && github.ref_name || '' }}
19
20 publish:
21 needs: preflight
22 name: cargo publish
23 runs-on: macos-26
24
25 env:
26 GRESIQ_API_KEY_DEV: ${{ secrets.GRESIQ_API_KEY_DEV }}
27 GRESIQ_API_SECRET_DEV: ${{ secrets.GRESIQ_API_SECRET_DEV }}
28 GRESIQ_API_KEY_PRODUCTION: ${{ secrets.GRESIQ_API_KEY_PRODUCTION }}
29 GRESIQ_API_SECRET_PRODUCTION: ${{ secrets.GRESIQ_API_SECRET_PRODUCTION }}
30 HF_TOKEN: ${{ secrets.HF_TOKEN }}
31
32 steps:
33 - name: Checkout
34 uses: actions/checkout@v6
35
36 - name: Read Rust toolchain
37 run: |
38 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
39 if [ -z "$rust_toolchain" ]; then
40 echo "::error::Failed to read channel from rust-toolchain.toml"
41 exit 1
42 fi
43 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
44
45 - name: Install stable Rust toolchain
46 uses: dtolnay/rust-toolchain@stable
47 with:
48 toolchain: ${{ env.RUST_TOOLCHAIN }}
49
50 # Skip a version already on crates.io instead of hard-failing. crates.io is
51 # immutable, so a re-run of a partially-failed release would otherwise die
52 # here on "already uploaded" — the npm workflow has had this guard all along.
53 #
54 # The check must not go through cargo. `cargo info onde@$VERSION` run from
55 # inside this workspace resolves against the local package rather than the
56 # registry, so it answered yes for every version, the skip was always
57 # taken, and 1.2.3 and 1.2.4 were tagged, reported green, and never
58 # published. crates-io-published.py queries the index directly.
59 - name: Check whether this version is already published
60 id: published
61 run: |
62 VERSION="$(python3 scripts/sync-release-version.py --print)"
63 if python3 scripts/crates-io-published.py "$VERSION"; then
64 echo "skip=true" >> "$GITHUB_OUTPUT"
65 else
66 status=$?
67 if [ "$status" -ne 1 ]; then
68 echo "::error::Could not determine whether onde ${VERSION} is published"
69 exit "$status"
70 fi
71 echo "skip=false" >> "$GITHUB_OUTPUT"
72 fi
73
74 # --locked forbids resolving anything other than the committed Cargo.lock,
75 # so the crate published is built from the same graph CI tested.
76 - name: cargo publish --dry-run
77 if: steps.published.outputs.skip != 'true'
78 run: cargo publish --dry-run --locked
79
80 - name: cargo publish
81 if: startsWith(github.ref, 'refs/tags/') && steps.published.outputs.skip != 'true'
82 env:
83 CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
84 run: cargo publish --locked
85
86 # A green run that published nothing is the exact failure this workflow
87 # already shipped twice, so assert the upload landed rather than trusting
88 # the exit code above.
89 - name: Verify the version reached crates.io
90 if: startsWith(github.ref, 'refs/tags/') && steps.published.outputs.skip != 'true'
91 run: |
92 VERSION="$(python3 scripts/sync-release-version.py --print)"
93 python3 scripts/crates-io-published.py "$VERSION" --wait