|
43 | 43 | - stable |
44 | 44 | - preview |
45 | 45 | - development |
| 46 | + sign-windows: |
| 47 | + type: boolean |
| 48 | + description: Sign Windows executable? |
| 49 | + default: true |
46 | 50 | test-release-artifacts: |
47 | 51 | type: boolean |
48 | 52 | description: "[Debug] Test release artifacts?" |
@@ -131,6 +135,14 @@ jobs: |
131 | 135 | platform-id: win-x64 |
132 | 136 | out-name: StabilityMatrix.exe |
133 | 137 | runs-on: windows-latest |
| 138 | + # Binds the OIDC subject to the environment (branch-agnostic), so releases from |
| 139 | + # any branch (main, dev, ...) match a single federated credential. |
| 140 | + environment: release |
| 141 | + # OIDC (id-token) is required for passwordless Azure login used by code signing. |
| 142 | + # contents: read is the minimum needed for checkout (overrides the workflow-level contents: write). |
| 143 | + permissions: |
| 144 | + id-token: write |
| 145 | + contents: read |
134 | 146 | steps: |
135 | 147 | - uses: actions/checkout@v3 |
136 | 148 |
|
@@ -175,14 +187,51 @@ jobs: |
175 | 187 | - name: Post Build |
176 | 188 | run: mv ./out/StabilityMatrix.Avalonia.exe ./out/${{ env.out-name }} |
177 | 189 |
|
| 190 | + # Passwordless login via OIDC federated credentials (no client secret stored). |
| 191 | + # Skipped when sign-windows is explicitly disabled (escape hatch for unsigned releases). |
| 192 | + - name: Azure Login (OIDC) |
| 193 | + if: ${{ github.event.inputs.sign-windows != 'false' }} |
| 194 | + uses: azure/login@v2 |
| 195 | + with: |
| 196 | + client-id: ${{ secrets.AZURE_CLIENT_ID }} |
| 197 | + tenant-id: ${{ secrets.AZURE_TENANT_ID }} |
| 198 | + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} |
| 199 | + |
| 200 | + # The signing action installs its tooling (sign CLI, SDK build tools) via NuGet |
| 201 | + # with --add-source, which NuGet rejects while our packageSourceMapping is active. |
| 202 | + # Move our config aside for the sign step; restored immediately after. |
| 203 | + - name: Disable NuGet source mapping for signing |
| 204 | + if: ${{ github.event.inputs.sign-windows != 'false' }} |
| 205 | + run: Rename-Item NuGet.Config NuGet.Config.disabled |
| 206 | + |
| 207 | + # Authenticode-sign the published single-file exe before upload, so every |
| 208 | + # downstream channel (GitHub release, B2 / matrix auto-update) ships signed bytes. |
| 209 | + - name: Sign Windows executable |
| 210 | + if: ${{ github.event.inputs.sign-windows != 'false' }} |
| 211 | + uses: azure/trusted-signing-action@v2.0.0 |
| 212 | + with: |
| 213 | + endpoint: ${{ vars.SIGNING_ENDPOINT }} |
| 214 | + signing-account-name: ${{ vars.SIGNING_ACCOUNT_NAME }} |
| 215 | + certificate-profile-name: ${{ vars.SIGNING_CERT_PROFILE_NAME }} |
| 216 | + files-folder: ${{ github.workspace }}\out |
| 217 | + files-folder-filter: exe |
| 218 | + file-digest: SHA256 |
| 219 | + timestamp-rfc3161: http://timestamp.acs.microsoft.com |
| 220 | + timestamp-digest: SHA256 |
| 221 | + |
| 222 | + # Restore the config even if signing failed, so the tree stays consistent. |
| 223 | + - name: Restore NuGet source mapping |
| 224 | + if: ${{ always() && github.event.inputs.sign-windows != 'false' }} |
| 225 | + run: Rename-Item NuGet.Config.disabled NuGet.Config |
| 226 | + |
178 | 227 | - name: Upload Artifact |
179 | 228 | uses: actions/upload-artifact@v4 |
180 | 229 | with: |
181 | 230 | name: StabilityMatrix-${{ env.platform-id }} |
182 | 231 | path: ./out/${{ env.out-name }} |
183 | 232 | retention-days: 1 |
184 | 233 | if-no-files-found: error |
185 | | - |
| 234 | + |
186 | 235 | release-macos: |
187 | 236 | name: Release (macos-arm64) |
188 | 237 | env: |
|
0 commit comments