Release & Publish NuGet #25
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release & Publish NuGet | |
| on: | |
| push: | |
| tags: | |
| - 'v*' | |
| permissions: | |
| contents: write | |
| jobs: | |
| release: | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Setup NuGet | |
| uses: nuget/setup-nuget@v2 | |
| - name: Find MSBuild & VS paths | |
| id: vs | |
| shell: pwsh | |
| run: | | |
| $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" | |
| $vsPath = & $vswhere -latest -requires Microsoft.Component.MSBuild -property installationPath | |
| $msbuild = & $vswhere -latest -requires Microsoft.Component.MSBuild -find "MSBuild\**\Bin\MSBuild.exe" | Select-Object -First 1 | |
| Write-Host "VS Installation: $vsPath" | |
| Write-Host "MSBuild: $msbuild" | |
| "MSBUILD=$msbuild" >> $env:GITHUB_OUTPUT | |
| "VS_PATH=$vsPath" >> $env:GITHUB_OUTPUT | |
| - name: Extract version from tag | |
| id: version | |
| shell: pwsh | |
| run: | | |
| $tag = "${{ github.ref_name }}" | |
| $ver = $tag -replace '^v', '' | |
| "VERSION=$ver" >> $env:GITHUB_OUTPUT | |
| - name: Restore & Build UWP library | |
| shell: pwsh | |
| run: | | |
| # CCV ProjectReferences CompositionExpressions; both UWP projects | |
| # need their PackageReferences restored explicitly because | |
| # `nuget restore` doesn't follow ProjectReferences across legacy | |
| # UAP csprojs the way `dotnet restore` does for SDK-style ones. | |
| nuget restore src/CompositionExpressions/CompositionExpressions.csproj | |
| nuget restore src/CompositionCollectionView/CompositionCollectionView.csproj | |
| # Build the leaf first so its output is available when CCV is built. | |
| & "${{ steps.vs.outputs.MSBUILD }}" src/CompositionExpressions/CompositionExpressions.csproj ` | |
| /t:Build /p:Configuration=Release /p:Platform=AnyCPU | |
| & "${{ steps.vs.outputs.MSBUILD }}" src/CompositionCollectionView/CompositionCollectionView.csproj ` | |
| /t:Build /p:Configuration=Release /p:Platform=AnyCPU | |
| - name: Resolve AppxMSBuildToolsPath | |
| id: appx | |
| shell: pwsh | |
| run: | | |
| # dotnet build has .NET 10 but not VS's PRI task DLLs. We just need AppxMSBuildToolsPath. | |
| # The MrtCore.PriGen.targets construct: $(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\AppxPackage\ | |
| # We override AppxMSBuildToolsPath to point directly to VS's copy. | |
| $vsPath = "${{ steps.vs.outputs.VS_PATH }}" | |
| $msbuildDir = "$vsPath\MSBuild" | |
| $vsVerDir = Get-ChildItem "$msbuildDir\Microsoft\VisualStudio" -Directory -Filter "v*" | Select-Object -First 1 | |
| $appxPath = "$($vsVerDir.FullName)\AppxPackage" | |
| Write-Host "AppxMSBuildToolsPath: $appxPath" | |
| Write-Host "PRI DLL exists: $(Test-Path "$appxPath\Microsoft.Build.Packaging.Pri.Tasks.dll")" | |
| "APPX_PATH=$appxPath" >> $env:GITHUB_OUTPUT | |
| - name: Restore & Build WinAppSdk library (x64) | |
| shell: pwsh | |
| run: | | |
| dotnet restore src/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj -p:Platform=x64 | |
| dotnet build src/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj ` | |
| -c Release ` | |
| --no-restore ` | |
| -p:Platform=x64 ` | |
| "-p:AppxMSBuildToolsPath=${{ steps.appx.outputs.APPX_PATH }}\" | |
| - name: Restore & Build WinAppSdk library (ARM64) | |
| shell: pwsh | |
| run: | | |
| dotnet restore src/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj -p:Platform=ARM64 | |
| dotnet build src/CompositionCollectionView.WinAppSdk/CompositionCollectionView.WinAppSdk.csproj ` | |
| -c Release ` | |
| --no-restore ` | |
| -p:Platform=ARM64 ` | |
| "-p:AppxMSBuildToolsPath=${{ steps.appx.outputs.APPX_PATH }}\" | |
| - name: Pack NuGet | |
| shell: pwsh | |
| run: | | |
| $ErrorActionPreference = 'Stop' | |
| nuget pack CompositionExpressions.nuspec ` | |
| -Version ${{ steps.version.outputs.VERSION }} ` | |
| -OutputDirectory artifacts | |
| if ($LASTEXITCODE -ne 0) { throw "nuget pack CompositionExpressions failed" } | |
| nuget pack CompositionCollectionView.nuspec ` | |
| -Version ${{ steps.version.outputs.VERSION }} ` | |
| -OutputDirectory artifacts | |
| if ($LASTEXITCODE -ne 0) { throw "nuget pack CompositionCollectionView failed" } | |
| - name: Upload nupkg artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: nuget-packages | |
| path: artifacts/*.nupkg | |
| - name: Push to NuGet.org | |
| id: nuget_push | |
| continue-on-error: true | |
| shell: pwsh | |
| run: | | |
| $key = "${{ secrets.NUGET_API_KEY }}" | |
| if (-not $key) { | |
| Write-Warning "NUGET_API_KEY is not set — skipping push. Download packages from workflow artifacts." | |
| exit 0 | |
| } | |
| $failed = $false | |
| Get-ChildItem artifacts\*.nupkg | ForEach-Object { | |
| dotnet nuget push $_.FullName ` | |
| --api-key $key ` | |
| --source https://api.nuget.org/v3/index.json ` | |
| --skip-duplicate | |
| if ($LASTEXITCODE -ne 0) { $failed = $true } | |
| } | |
| if ($failed) { exit 1 } | |
| - name: Warn on push failure | |
| if: steps.nuget_push.outcome == 'failure' | |
| shell: pwsh | |
| run: | | |
| Write-Warning "NuGet push failed (key may be expired). Packages are attached to the GitHub Release and available as workflow artifacts. Update the NUGET_API_KEY secret and re-run this step." | |
| - name: Create GitHub Release | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| generate_release_notes: true | |
| files: artifacts/*.nupkg |