From 73c91c20f8578a4ab1c52044a191d0e650c3174a Mon Sep 17 00:00:00 2001 From: axunonb Date: Sat, 6 Dec 2025 15:09:59 +0100 Subject: [PATCH] Update CI Publish Workflow --- .github/workflows/Publish.yml | 83 +++++++++++----------- .github/workflows/PublishResolveVersion.sh | 52 ++++++++++++++ 2 files changed, 92 insertions(+), 43 deletions(-) create mode 100644 .github/workflows/PublishResolveVersion.sh diff --git a/.github/workflows/Publish.yml b/.github/workflows/Publish.yml index b35f1e94..128f26c7 100644 --- a/.github/workflows/Publish.yml +++ b/.github/workflows/Publish.yml @@ -1,54 +1,40 @@ -name: Publish +name: Publish NuGet Package # This job builds and publishes the package to NuGet. # It depends on the included tests job to complete successfully. -# The version number is determined by the existing tag provided -# when manually triggering the workflow. -# The tag is not limited to a certain branch. +# This workflow finds the most recent tag that starts with +# the selected major version (sorted by creatordate) +# and runs the test, build and publish tasks for that tag. on: workflow_dispatch: - inputs: - version_tag: - description: 'Enter an existing version tag to publish (e.g., "v5.1.0" or "v6.0.0-pre.1")' - required: true - type: string - + inputs: + major_version: + description: 'Select the major version to publish (tag prefix). The workflow will pick the most recent tag that starts with this value (e.g. v3 -> v3.2.1).' + required: true + type: choice + options: + - v3 + # - v4 jobs: tests: - runs-on: ubuntu-22.04 - # ubuntu-latest = ubuntu-24.04 does not include mono needed for tests (2025-08-01) + runs-on: ubuntu-22.04 # ubuntu-24.04 does not include mono needed for net4x tests outputs: - VERSION: ${{ steps.set_version.outputs.VERSION }} + VERSION: ${{ steps.resolve.outputs.VERSION }} + TAG_NAME: ${{ steps.resolve.outputs.TAG_NAME }} steps: - name: Checkout repository uses: actions/checkout@v5 with: fetch-depth: 0 # Fetch all history for all tags and branches - - name: Verify tag exists - run: | - git fetch --tags --quiet - if ! git rev-parse "${{ inputs.version_tag }}" >/dev/null 2>&1; then - echo "::error::Tag '${{ inputs.version_tag }}' does not exist." - echo "Available tags:" - git tag -l - exit 1 - fi - - - name: Checkout tag - uses: actions/checkout@v5 - with: - fetch-depth: 0 # Fetch all history for all tags and branches - ref: ${{ inputs.version_tag }} - - - name: Set VERSION output - id: set_version + - name: Show matching major version tags and select latest by creatordate + id: resolve + shell: bash run: | - Version="${{ inputs.version_tag }}" - # Strip 'v' prefix for VERSION variable - Version="${Version#v}" - echo "VERSION=$Version" >> $GITHUB_ENV - echo "VERSION=$Version" >> $GITHUB_OUTPUT - echo "Version: $Version" + set -euo pipefail + # Call the script to resolve the latest tag for the requested major version. + # Script writes TAG_NAME and VERSION to $GITHUB_OUTPUT and $GITHUB_ENV when run on Actions. + chmod +x .github/workflows/PublishResolveVersion.sh + .github/workflows/PublishResolveVersion.sh "${{ github.event.inputs.major_version }}" - name: Set Git config for line endings run: git config --global core.autocrlf true @@ -57,12 +43,20 @@ jobs: uses: actions/setup-dotnet@v5 with: dotnet-version: | + 10.0.x 8.0.x 6.0.x 3.1.x + - name: Checkout tag + uses: actions/checkout@v5 + with: + fetch-depth: 0 # Fetch all history for all tags and branches + ref: ${{ steps.resolve.outputs.TAG_NAME }} + - name: Remove Demo run: dotnet sln ./src/SmartFormat.sln remove ./src/Demo/Demo.csproj + - name: Restore dependencies run: dotnet restore ./src/SmartFormat.sln @@ -73,7 +67,7 @@ jobs: run: dotnet test ./src/SmartFormat.sln --no-build --configuration Release --verbosity quiet publish: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 needs: tests steps: @@ -81,7 +75,8 @@ jobs: uses: actions/checkout@v5 with: fetch-depth: 0 # Fetch all history for all tags and branches - ref: ${{ inputs.version_tag }} + # Reuse the tag name from tests job + ref: ${{ needs.tests.outputs.TAG_NAME }} - name: Set Git config for line endings run: git config --global core.autocrlf true @@ -90,7 +85,7 @@ jobs: uses: actions/setup-dotnet@v5 with: dotnet-version: | - 8.0.x + 10.0.x - name: Use verified version run: | @@ -112,7 +107,7 @@ jobs: - name: Build and pack for publishing run: | - # For version e.g. "5.1.0-pre.1", the FileVersion will be "5.1.0" and the AssemblyVersion will be "5.0.0" + # For version e.g. "3.1.0-pre.1", the FileVersion will be "3.1.0" and the AssemblyVersion will be "3.0.0" # AssemblyVersion must only change for major releases dotnet build ./src/SmartFormat.Deploy.sln --configuration Release \ -p:Version=${{env.VERSION}} \ @@ -134,14 +129,16 @@ jobs: - name: Store artifacts uses: actions/upload-artifact@v4 with: - name: nuget-packages_${{env.VERSION}}.${{github.run_number}} + name: SmartFormat-Packages_${{env.VERSION}}.${{github.run_number}} path: | ${{ github.workspace }}/artifacts/ - name: Push package to NuGet # Does not fail, if the package already exists # Note: Symbol packages get uploaded automatically with the main package + env: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} run: | for pkg in ${{ github.workspace }}/artifacts/*.nupkg; do - dotnet nuget push "$pkg" --source https://api.nuget.org/v3/index.json --api-key ${{ secrets.NUGET_API_KEY }} --skip-duplicate + dotnet nuget push "$pkg" --source https://api.nuget.org/v3/index.json --api-key "$NUGET_API_KEY" --skip-duplicate done diff --git a/.github/workflows/PublishResolveVersion.sh b/.github/workflows/PublishResolveVersion.sh new file mode 100644 index 00000000..87098a4b --- /dev/null +++ b/.github/workflows/PublishResolveVersion.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# Enable strict mode when running inside GitHub Actions runner +if [ "${GITHUB_ACTIONS:-false}" = "true" ]; then + set -euo pipefail +fi + +Major="${1:-}" +if [ -z "$Major" ]; then + echo "::error::No major version argument supplied. Usage: $0 (e.g. v3)" >&2 + exit 1 +fi +echo "Looking for tags that start with: $Major" + +# Fetch tags +git fetch --tags --quiet + +# Collect matching tags (newest first by creatordate) +mapfile -t MATCHING < <( + git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags \ + | grep -E "^${Major}(\.|$)" || true +) + +if [ ${#MATCHING[@]} -eq 0 ]; then + echo "::error::No tag found starting with '${Major}'. Showing latest tags:" + git for-each-ref --sort=-creatordate --format='%(refname:short)' refs/tags | head -n 10 + exit 1 +fi + +echo "Showing up to 10 of top ${#MATCHING[@]} matching tags (newest first):" +for tag in "${MATCHING[@]:0:10}"; do + echo " - $tag" +done + +Tag="${MATCHING[0]}" +Version="${Tag#v}" + +echo "Selected tag: $Tag -> version: $Version" + +# If running in GitHub Actions, write to the runner files +if [ -n "${GITHUB_OUTPUT-}" ]; then + printf 'TAG_NAME=%s\n' "$Tag" >> "$GITHUB_OUTPUT" + printf 'VERSION=%s\n' "$Version" >> "$GITHUB_OUTPUT" +fi + +if [ -n "${GITHUB_ENV-}" ]; then + printf 'TAG_NAME=%s\n' "$Tag" >> "$GITHUB_ENV" + printf 'VERSION=%s\n' "$Version" >> "$GITHUB_ENV" +fi + +# Always print results +printf 'TAG_NAME=%s\n' "$Tag" +printf 'VERSION=%s\n' "$Version"