Skip to content

v1.0.0 - Initial Stable Release #1

v1.0.0 - Initial Stable Release

v1.0.0 - Initial Stable Release #1

name: Release - Stable
on:
release:
types: [published]
concurrency:
group: ${{ github.workflow }}-${{ github.event.release.id }}
cancel-in-progress: true
jobs:
test-multiplatform:
name: Test on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
permissions:
contents: read
steps:
- name: Checkout tag
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.release.tag_name }}
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore
working-directory: ./src
- name: Build solution
run: dotnet build -c Release --no-restore
working-directory: ./src
- name: Run tests
run: dotnet test -c Release --no-build --no-restore --verbosity normal
working-directory: ./src
publish:
# Only process releases from develop branch
if: github.event.release.target_commitish == 'develop'
runs-on: ubuntu-latest
needs: test-multiplatform
permissions:
contents: read
env:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: '1'
DOTNET_CLI_TELEMETRY_OPTOUT: '1'
steps:
- name: Checkout tag
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.release.tag_name }}
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.x
- name: Extract and validate release version
run: |
TAG="${{ github.event.release.tag_name }}"
echo "Release tag: $TAG"
# Remove 'v' prefix if present
if [[ "$TAG" =~ ^v[0-9] ]]; then
VERSION="${TAG#v}"
else
echo "::error ::Tag must start with 'v' followed by version number (e.g., v1.2.3)"
exit 1
fi
# Validate it's a proper release version (X.Y.Z format, no suffix)
if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
echo "::error ::Invalid release version format. Expected X.Y.Z (e.g., 1.2.3), got: $VERSION"
exit 1
fi
echo "Using release version: $VERSION"
echo "RELEASE_VERSION=$VERSION" >> $GITHUB_ENV
- name: Restore dependencies
run: dotnet restore
working-directory: ./src
- name: Build solution (stable)
run: dotnet build -c Release --no-restore -p:Version=${{ env.RELEASE_VERSION }} -p:AssemblyVersion=${{ env.RELEASE_VERSION }} -p:FileVersion=${{ env.RELEASE_VERSION }}
working-directory: ./src
- name: Pack NuGet packages (stable)
run: dotnet pack -c Release --no-restore /p:IncludeSymbols=true /p:SymbolPackageFormat=snupkg -o ../artifacts -p:Version=${{ env.RELEASE_VERSION }}
working-directory: ./src
- name: Ensure packages exist
run: |
shopt -s nullglob
files=(artifacts/*.nupkg artifacts/*.snupkg)
(( ${#files[@]} )) || { echo "::error ::No packages found in artifacts/"; exit 1; }
- name: Upload artifacts (audit)
uses: actions/upload-artifact@v4
with:
name: packages-${{ env.RELEASE_VERSION }}
path: artifacts
retention-days: 7
- name: Push to NuGet.org
env:
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
run: |
shopt -s nullglob
for p in artifacts/*.nupkg artifacts/*.snupkg; do
dotnet nuget push "$p" --source https://api.nuget.org/v3/index.json --api-key "$NUGET_API_KEY" --skip-duplicate
done