Skip to content

Add Preview workflows and enforce versioning rules (#1088) #342

Add Preview workflows and enforce versioning rules (#1088)

Add Preview workflows and enforce versioning rules (#1088) #342

Workflow file for this run

name: Build and Release
on:
push:
branches: [ main, 'release/*.x' ]
workflow_dispatch:
env:
configuration: Release
concurrency:
group: release-${{ github.ref }}
cancel-in-progress: false
jobs:
release:
runs-on: windows-latest
environment:
name: release
permissions:
contents: write
outputs:
nbgv: ${{ steps.nbgv.outputs.SemVer2 }}
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Validate publish branch
shell: pwsh
env:
REF_NAME: ${{ github.ref_name }}
run: |
$ErrorActionPreference = 'Stop'
if ($env:REF_NAME -ne 'main' -and $env:REF_NAME -notmatch '^release/(0|[1-9]\d*)\.x$') {
throw "release.yml triggered on '$env:REF_NAME' which is neither 'main' nor 'release/<major>.x'. Refusing to publish."
}
Write-Host "OK: publishing from '$env:REF_NAME'."
- name: Setup .NET (With cache)
uses: actions/setup-dotnet@v5.0.1
with:
dotnet-version: |
6.0.x
7.0.x
8.0.x
9.0.x
10.0.x
cache: true
cache-dependency-path: |
**/Directory.Packages.props
**/*.sln
**/*.csproj
**/global.json
**/nuget.config
- name: NBGV
id: nbgv
uses: dotnet/nbgv@v0.5.1
with:
setAllVars: true
- name: Verify version matches branch policy
shell: pwsh
env:
SEMVER2: ${{ steps.nbgv.outputs.SemVer2 }}
PRERELEASE: ${{ steps.nbgv.outputs.PrereleaseVersion }}
REF_NAME: ${{ github.ref_name }}
run: |
$ErrorActionPreference = 'Stop'
if ($env:REF_NAME -eq 'main' -and -not $env:PRERELEASE) {
throw "Refusing to publish stable '$env:SEMVER2' from main. main must always publish prereleases. Check version.json for an accidental switch to a non-prerelease form."
}
if ($env:PRERELEASE -and $env:REF_NAME -match '^release/(0|[1-9]\d*)\.x$') {
throw "Refusing to publish prerelease '$env:SEMVER2' from a release branch ('$env:REF_NAME'). Release branches must only publish stable versions."
}
if (-not $env:PRERELEASE) {
Write-Host "Stable release ($env:SEMVER2); skipping prerelease regression check."
exit 0
}
if ($env:SEMVER2 -notmatch '^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)-') {
throw "Could not parse SemVer2 '$env:SEMVER2'"
}
$major = $matches[1]
$minor = $matches[2]
git fetch --tags --force origin
if ($LASTEXITCODE -ne 0) { throw "git fetch --tags failed (exit $LASTEXITCODE); cannot validate prerelease regression." }
$majorEsc = [regex]::Escape($major)
$minorEsc = [regex]::Escape($minor)
$stableTags = git tag --list "$major.$minor.*" | Where-Object { $_ -match "^${majorEsc}\.${minorEsc}\.\d+$" }
if ($stableTags) {
$list = $stableTags -join ', '
throw "Stable for $major.$minor has already shipped (tags: $list); cannot publish prerelease '$env:SEMVER2'. Bump main's version.json to the next minor or major preview line."
}
Write-Host "OK: no stable $major.$minor.* tag exists; '$env:SEMVER2' is safe to publish."
- name: NuGet Restore
run: dotnet restore DynamicData.sln
working-directory: src
- name: Run Tests
run: dotnet test --no-restore --configuration Release DynamicData.sln
working-directory: src
- name: Pack
run: dotnet pack --no-restore --no-build --configuration Release DynamicData.sln
working-directory: src
- name: NuGet Push
env:
NUGET_AUTH_TOKEN: ${{ secrets.NUGET_API_KEY }}
SOURCE_URL: https://api.nuget.org/v3/index.json
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$packages = Get-ChildItem -Path src -Recurse -Filter '*.nupkg' | Where-Object { $_.FullName -like '*\bin\Release\*' }
if (-not $packages) { throw "No .nupkg files found under src/**/bin/Release/." }
foreach ($pkg in $packages) {
dotnet nuget push -s $env:SOURCE_URL -k $env:NUGET_AUTH_TOKEN --skip-duplicate $pkg.FullName
if ($LASTEXITCODE -ne 0) { throw "dotnet nuget push failed for $($pkg.Name) (exit $LASTEXITCODE)." }
}
- name: Changelog
uses: glennawatson/ChangeLog@0464dd89b26f61fecf24b41d675f8ffdb11c4c3f # v1
id: changelog
- name: Create GitHub Release
uses: softprops/action-gh-release@v2.6.2
with:
tag_name: ${{ steps.nbgv.outputs.SemVer2 }}
name: ${{ steps.nbgv.outputs.SemVer2 }}
prerelease: ${{ steps.nbgv.outputs.PrereleaseVersion != '' }}
body: |
${{ steps.changelog.outputs.commitLog }}