1 name: Crates.io Release
2
3 on:
4 push:
5 tags:
6 - "v*.*.*"
7 workflow_dispatch:
8 inputs:
9 tag:
10 description: "Release tag (e.g. v1.0.2)"
11 required: true
12
13 permissions:
14 contents: read
15
16 env:
17 CARGO_TERM_COLOR: always
18
19 jobs:
20 publish:
21 name: Publish to crates.io
22 runs-on: ubuntu-latest
23
24 steps:
25 - name: Checkout
26 uses: actions/checkout@v6
27 with:
28 ref: ${{ github.event.inputs.tag || github.ref }}
29
30 - name: Read Rust toolchain
31 shell: bash
32 run: |
33 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
34 if [ -z "$rust_toolchain" ]; then
35 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
36 exit 1
37 fi
38 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
39
40 - name: Install Rust toolchain
41 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
42 with:
43 toolchain: ${{ env.RUST_TOOLCHAIN }}
44
45 - name: Setup Rust cache
46 uses: Swatinem/rust-cache@v2
47 with:
48 key: crates-publish
49
50 - name: Check whether version already exists on crates.io
51 id: crates-check
52 shell: bash
53 run: |
54 VERSION=$(cargo metadata --no-deps --format-version 1 | \
55 python3 -c "import sys,json; pkgs=json.load(sys.stdin)['packages']; \
56 print(next(p['version'] for p in pkgs if p['name']=='sigit'))")
57 echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
58
59 if curl -fsS "https://crates.io/api/v1/crates/sigit/${VERSION}" >/dev/null 2>&1; then
60 echo "sigit ${VERSION} already exists on crates.io, skipping publish"
61 echo "exists=true" >> "$GITHUB_OUTPUT"
62 else
63 echo "exists=false" >> "$GITHUB_OUTPUT"
64 fi
65
66 - name: Publish to crates.io
67 if: steps.crates-check.outputs.exists != 'true'
68 env:
69 CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
70 run: cargo publish --locked