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