1 name: PyPI Release
2
3 on:
4 push:
5 tags:
6 - "v*.*.*"
7 workflow_dispatch:
8
9 permissions:
10 id-token: write
11 contents: read
12
13 env:
14 CARGO_TERM_COLOR: always
15 CLI_CLIENT_SECRET: ${{ secrets.CLI_CLIENT_SECRET }}
16
17 jobs:
18 build-wheels:
19 name: Build PyPI wheels
20 runs-on: ${{ matrix.build.OS }}
21 strategy:
22 fail-fast: false
23 matrix:
24 build:
25 - {
26 NAME: linux-x64-glibc,
27 OS: ubuntu-latest,
28 TARGET: x86_64-unknown-linux-gnu,
29 MANYLINUX: "2014",
30 }
31 - {
32 NAME: linux-arm64-glibc,
33 OS: ubuntu-24.04-arm,
34 TARGET: aarch64-unknown-linux-gnu,
35 MANYLINUX: "2014",
36 }
37 - {
38 NAME: win32-x64-msvc,
39 OS: windows-2022,
40 TARGET: x86_64-pc-windows-msvc,
41 }
42 - {
43 NAME: win32-arm64-msvc,
44 OS: windows-2022,
45 TARGET: aarch64-pc-windows-msvc,
46 }
47 - { NAME: darwin-x64, OS: macos-latest, TARGET: x86_64-apple-darwin }
48 - {
49 NAME: darwin-arm64,
50 OS: macos-latest,
51 TARGET: aarch64-apple-darwin,
52 }
53 steps:
54 - name: Checkout
55 uses: actions/checkout@v6
56 with:
57 ref: ${{ github.event.inputs.tag || github.ref }}
58
59 - name: Set the release version
60 shell: bash
61 run: |
62 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
63 release_version="${GITHUB_REF_NAME#v}"
64 else
65 release_version="${{ github.event.inputs.tag }}"
66 release_version="${release_version#v}"
67 fi
68
69 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
70
71 - name: Read Rust toolchain
72 shell: bash
73 run: |
74 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
75 if [ -z "$rust_toolchain" ]; then
76 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
77 exit 1
78 fi
79
80 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
81
82 - name: Install toolkit
83 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
84 with:
85 toolchain: ${{ env.RUST_TOOLCHAIN }}
86
87 - name: Install Rust target
88 shell: bash
89 run: |
90 rustup target add ${{ matrix.build.TARGET }} --toolchain ${{ env.RUST_TOOLCHAIN }}
91 rustup target list --installed
92
93 - name: Build wheel
94 uses: PyO3/maturin-action@v1
95 with:
96 target: ${{ matrix.build.TARGET }}
97 manylinux: ${{ matrix.build.MANYLINUX || 'off' }}
98 working-directory: pypi
99 args: --release --locked --compatibility pypi --out dist
100 before-script-linux: yum install -y perl-core
101 docker-options: -e CLI_CLIENT_SECRET
102
103 - name: Upload wheel artifact
104 uses: actions/upload-artifact@v7
105 with:
106 name: wheels-${{ matrix.build.NAME }}
107 path: pypi/dist/*
108
109 build-sdist:
110 name: Build source distribution
111 runs-on: ubuntu-latest
112 steps:
113 - name: Checkout
114 uses: actions/checkout@v6
115 with:
116 ref: ${{ github.event.inputs.tag || github.ref }}
117
118 - name: Set the release version
119 shell: bash
120 run: |
121 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
122 release_version="${GITHUB_REF_NAME#v}"
123 else
124 release_version="${{ github.event.inputs.tag }}"
125 release_version="${release_version#v}"
126 fi
127
128 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
129
130 - name: Read Rust toolchain
131 shell: bash
132 run: |
133 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
134 if [ -z "$rust_toolchain" ]; then
135 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
136 exit 1
137 fi
138
139 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
140
141 - name: Install toolkit
142 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
143 with:
144 toolchain: ${{ env.RUST_TOOLCHAIN }}
145
146 - name: Build sdist
147 uses: PyO3/maturin-action@v1
148 with:
149 command: sdist
150 working-directory: pypi
151 args: --out dist
152
153 - name: Upload sdist artifact
154 uses: actions/upload-artifact@v7
155 with:
156 name: sdist
157 path: pypi/dist/*
158
159 publish-pypi:
160 name: Publish to PyPI
161 runs-on: ubuntu-latest
162 needs:
163 - build-wheels
164 - build-sdist
165
166 steps:
167 - name: Checkout
168 uses: actions/checkout@v6
169 with:
170 ref: ${{ github.event.inputs.tag || github.ref }}
171
172 - name: Set the release version
173 shell: bash
174 run: |
175 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
176 release_version="${GITHUB_REF_NAME#v}"
177 else
178 release_version="${{ github.event.inputs.tag }}"
179 release_version="${release_version#v}"
180 fi
181
182 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
183
184 - name: Download distribution artifacts
185 uses: actions/download-artifact@v7
186 with:
187 pattern: "*"
188 path: dist
189 merge-multiple: true
190
191 - name: Check whether release already exists on PyPI
192 id: pypi-check
193 shell: bash
194 run: |
195 if curl -fsS "https://pypi.org/pypi/smbcloud-cli/${RELEASE_VERSION}/json" >/dev/null 2>&1; then
196 echo "smbcloud-cli ${RELEASE_VERSION} already exists on PyPI, skipping publish"
197 echo "exists=true" >> "$GITHUB_OUTPUT"
198 else
199 echo "exists=false" >> "$GITHUB_OUTPUT"
200 fi
201
202 - name: Publish distribution
203 if: steps.pypi-check.outputs.exists != 'true'
204 uses: pypa/gh-action-pypi-publish@release/v1
205 with:
206 skip-existing: true