1 name: NuGet CLI Release
2
3 on:
4 workflow_dispatch:
5 inputs:
6 tag:
7 description: "Release tag (e.g. v0.3.39)"
8 required: true
9
10 permissions:
11 contents: read
12
13 env:
14 CARGO_TERM_COLOR: always
15 CLI_CLIENT_SECRET: ${{ secrets.CLI_CLIENT_SECRET }}
16 DOTNET_VERSION: 8.0.x
17 NUGET_PACKAGE_ID: SmbCloud.Cli
18
19 jobs:
20 build-native-binaries:
21 name: Build native binary (${{ matrix.build.NAME }})
22 runs-on: ${{ matrix.build.OS }}
23 strategy:
24 fail-fast: false
25 matrix:
26 build:
27 - {
28 NAME: linux-x64,
29 OS: ubuntu-latest,
30 TARGET: x86_64-unknown-linux-gnu,
31 }
32 - {
33 NAME: linux-arm64,
34 OS: ubuntu-24.04-arm,
35 TARGET: aarch64-unknown-linux-gnu,
36 }
37 - {
38 NAME: windows-x64,
39 OS: windows-2022,
40 TARGET: x86_64-pc-windows-msvc,
41 }
42 - {
43 NAME: windows-arm64,
44 OS: windows-2022,
45 TARGET: aarch64-pc-windows-msvc,
46 }
47 - {
48 NAME: darwin-x64,
49 OS: macos-15-intel,
50 TARGET: x86_64-apple-darwin,
51 }
52 - {
53 NAME: darwin-arm64,
54 OS: macos-latest,
55 TARGET: aarch64-apple-darwin,
56 }
57 steps:
58 - name: Checkout
59 uses: actions/checkout@v6
60 with:
61 ref: ${{ github.event.inputs.tag || github.ref }}
62
63 - name: Set the release version
64 shell: bash
65 run: |
66 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
67 release_version="${GITHUB_REF_NAME#v}"
68 else
69 release_version="${{ github.event.inputs.tag }}"
70 release_version="${release_version#v}"
71 fi
72
73 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
74
75 - name: Read Rust toolchain
76 shell: bash
77 run: |
78 rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
79 if [ -z "$rust_toolchain" ]; then
80 echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
81 exit 1
82 fi
83
84 echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
85
86 - name: Install toolkit
87 uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
88 with:
89 toolchain: ${{ env.RUST_TOOLCHAIN }}
90 targets: ${{ matrix.build.TARGET }}
91
92 - name: Setup Rust cache
93 uses: Swatinem/rust-cache@v2
94 with:
95 key: nuget-${{ matrix.build.TARGET }}
96
97 - name: Build
98 env:
99 GH_OAUTH_CLIENT_ID: ${{ secrets.GH_OAUTH_CLIENT_ID }}
100 GH_OAUTH_CLIENT_SECRET: ${{ secrets.GH_OAUTH_CLIENT_SECRET }}
101 GH_OAUTH_REDIRECT_URI: ${{ secrets.GH_OAUTH_REDIRECT_URI }}
102 shell: bash
103 run: cargo build --release --locked --target ${{ matrix.build.TARGET }} --package smbcloud-cli
104
105 - name: Prepare artifact
106 shell: bash
107 run: |
108 executable_name="smb"
109 if [[ "${{ matrix.build.OS }}" == "windows-2022" ]]; then
110 executable_name="smb.exe"
111 fi
112
113 mkdir -p "nuget-artifacts/native/${{ matrix.build.NAME }}"
114 cp "target/${{ matrix.build.TARGET }}/release/${executable_name}" "nuget-artifacts/native/${{ matrix.build.NAME }}/${executable_name}"
115
116 - name: Upload native artifact
117 uses: actions/upload-artifact@v7
118 with:
119 name: nuget-native-${{ matrix.build.NAME }}
120 path: nuget-artifacts/native
121
122 pack-nuget:
123 name: Pack NuGet .NET tool
124 runs-on: ubuntu-latest
125 needs: build-native-binaries
126 steps:
127 - name: Checkout
128 uses: actions/checkout@v6
129 with:
130 ref: ${{ github.event.inputs.tag || github.ref }}
131
132 - name: Set the release version
133 shell: bash
134 run: |
135 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
136 release_version="${GITHUB_REF_NAME#v}"
137 else
138 release_version="${{ github.event.inputs.tag }}"
139 release_version="${release_version#v}"
140 fi
141
142 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
143
144 - name: Download native artifacts
145 uses: actions/download-artifact@v7
146 with:
147 pattern: nuget-native-*
148 path: nuget/smbcloud-cli/native
149 merge-multiple: true
150
151 - name: Setup .NET SDK
152 uses: actions/setup-dotnet@v4
153 with:
154 dotnet-version: ${{ env.DOTNET_VERSION }}
155
156 - name: Pack .NET tool
157 shell: bash
158 run: |
159 dotnet pack nuget/smbcloud-cli/SmbCloud.Cli.csproj \
160 --configuration Release \
161 --output nuget/dist \
162 -p:PackageVersion=${RELEASE_VERSION}
163
164 - name: Upload package artifact
165 uses: actions/upload-artifact@v7
166 with:
167 name: nuget-package
168 path: nuget/dist/*.nupkg
169
170 smoke-test:
171 name: Smoke test (${{ matrix.os }})
172 runs-on: ${{ matrix.os }}
173 needs: pack-nuget
174 strategy:
175 fail-fast: false
176 matrix:
177 os:
178 - ubuntu-latest
179 - windows-2022
180 - macos-latest
181 steps:
182 - name: Checkout
183 uses: actions/checkout@v6
184 with:
185 ref: ${{ github.event.inputs.tag || github.ref }}
186
187 - name: Set the release version
188 shell: bash
189 run: |
190 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
191 release_version="${GITHUB_REF_NAME#v}"
192 else
193 release_version="${{ github.event.inputs.tag }}"
194 release_version="${release_version#v}"
195 fi
196
197 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
198
199 - name: Download package artifact
200 uses: actions/download-artifact@v7
201 with:
202 name: nuget-package
203 path: nuget/dist
204
205 - name: Setup .NET SDK
206 uses: actions/setup-dotnet@v4
207 with:
208 dotnet-version: ${{ env.DOTNET_VERSION }}
209
210 - name: Install tool from local package
211 shell: pwsh
212 run: |
213 $packageSource = (Resolve-Path "nuget/dist").Path
214 @"
215 <?xml version="1.0" encoding="utf-8"?>
216 <configuration>
217 <packageSources>
218 <clear />
219 <add key="local" value="$packageSource" />
220 </packageSources>
221 </configuration>
222 "@ | Set-Content -Path "nuget/NuGet.Config"
223
224 dotnet tool install `
225 --tool-path ".tool" `
226 --configfile "nuget/NuGet.Config" `
227 --version "$env:RELEASE_VERSION" `
228 "$env:NUGET_PACKAGE_ID"
229
230 - name: Run smb --version
231 shell: pwsh
232 run: |
233 $toolPath = if ($IsWindows) { ".\.tool\smb.exe" } else { "./.tool/smb" }
234 & $toolPath --version
235
236 publish-nuget:
237 name: Publish to NuGet
238 runs-on: ubuntu-latest
239 needs: smoke-test
240 steps:
241 - name: Checkout
242 uses: actions/checkout@v6
243 with:
244 ref: ${{ github.event.inputs.tag || github.ref }}
245
246 - name: Set the release version
247 shell: bash
248 run: |
249 if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
250 release_version="${GITHUB_REF_NAME#v}"
251 else
252 release_version="${{ github.event.inputs.tag }}"
253 release_version="${release_version#v}"
254 fi
255
256 echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
257
258 - name: Download package artifact
259 uses: actions/download-artifact@v7
260 with:
261 name: nuget-package
262 path: nuget/dist
263
264 - name: Setup .NET SDK
265 uses: actions/setup-dotnet@v4
266 with:
267 dotnet-version: ${{ env.DOTNET_VERSION }}
268
269 - name: Check whether release already exists on NuGet
270 id: nuget-check
271 shell: bash
272 run: |
273 package_index_url="https://api.nuget.org/v3-flatcontainer/smbcloud.cli/index.json"
274 if curl -fsS "${package_index_url}" | grep -F "\"${RELEASE_VERSION}\"" >/dev/null; then
275 echo "${NUGET_PACKAGE_ID} ${RELEASE_VERSION} already exists on NuGet, skipping publish"
276 echo "exists=true" >> "$GITHUB_OUTPUT"
277 else
278 echo "exists=false" >> "$GITHUB_OUTPUT"
279 fi
280
281 - name: Publish package
282 if: steps.nuget-check.outputs.exists != 'true'
283 env:
284 NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
285 shell: bash
286 run: |
287 dotnet nuget push nuget/dist/*.nupkg \
288 --api-key "${NUGET_API_KEY}" \
289 --source https://api.nuget.org/v3/index.json \
290 --skip-duplicate