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. v0.3.35)"
11 required: true
12
13 permissions:
14 contents: read
15
16 env:
17 CARGO_TERM_COLOR: always
18 CLI_CLIENT_SECRET: ${{ secrets.CLI_CLIENT_SECRET }}
19
20 jobs:
21 publish:
22 name: Publish to crates.io
23 runs-on: ubuntu-latest
24
25 steps:
26 - name: Checkout
27 uses: actions/checkout@v6
28 with:
29 ref: ${{ github.event.inputs.tag || github.ref }}
30
31 - name: Set the release version
32 shell: bash
33 run: |
34 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
35 release_version="${GITHUB_REF_NAME#v}"
36 else
37 release_version="${{ github.event.inputs.tag }}"
38 release_version="${release_version#v}"
39 fi
40
41 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
42
43 - name: Read Rust toolchain
44 shell: bash
45 run: |
46 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
47 if [ -z "$rust_toolchain" ]; then
48 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
49 exit 1
50 fi
51
52 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
53
54 - name: Install toolkit
55 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
56 with:
57 toolchain: ${{ env.RUST_TOOLCHAIN }}
58
59 - name: Setup Rust cache
60 uses: Swatinem/rust-cache@v2
61 with:
62 key: publish
63
64 - name: Verify Cargo.toml version matches tag
65 shell: bash
66 run: |
67 CARGO_VERSION=$(cargo metadata --no-deps --format-version 1 \
68 | jq -r '.packages[] | select(.name == "smbcloud-cli") | .version')
69
70 echo "Cargo.toml version : ${CARGO_VERSION}"
71 echo "Release tag version: ${RELEASE_VERSION}"
72
73 if [[ "${CARGO_VERSION}" != "${RELEASE_VERSION}" ]]; then
74 echo "::error::Version mismatch — bump version in Cargo.toml before releasing."
75 exit 1
76 fi
77
78 - name: Check whether release already exists on crates.io
79 id: crates-check
80 shell: bash
81 run: |
82 if curl -fsS \
83 -H "User-Agent: smbcloud-cli-release-workflow" \
84 "https://crates.io/api/v1/crates/smbcloud-cli/${RELEASE_VERSION}" \
85 >/dev/null 2>&1; then
86 echo "smbcloud-cli ${RELEASE_VERSION} already exists on crates.io, skipping publish"
87 echo "exists=true" >> "$GITHUB_OUTPUT"
88 else
89 echo "exists=false" >> "$GITHUB_OUTPUT"
90 fi
91
92 - name: Publish to crates.io
93 if: steps.crates-check.outputs.exists != 'true'
94 shell: bash
95 env:
96 CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
97 run: cargo publish --locked --package smbcloud-cli