Skip to content

Release & Publish NuGet #25

Release & Publish NuGet

Release & Publish NuGet #25

Workflow file for this run

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