release: promote 0.1.4-alpha to stable 0.1.4 #6
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: Publish NuGet | |
| on: | |
| push: | |
| # Fire on ALL tag pushes so the format guard (below) catches mistakes | |
| # like `v0.1.0-alpha` loudly instead of silently no-op-ing. | |
| tags: | |
| - '*' | |
| permissions: | |
| contents: write | |
| id-token: write # Required for NuGet trusted publishing (OIDC token exchange). | |
| jobs: | |
| publish-nuget: | |
| name: publish-nuget | |
| runs-on: ubuntu-latest | |
| environment: nuget # Must match the environment named in the nuget.org Trusted Publisher policy. | |
| steps: | |
| - name: "Assert tag is a bare version number" | |
| shell: bash | |
| run: | | |
| # ShellSyntaxTree convention: tags are SemVer version numbers WITHOUT | |
| # a leading 'v'. E.g., `0.1.0-alpha`, NOT `v0.1.0-alpha`. The tag is | |
| # the package version verbatim. | |
| TAG="${GITHUB_REF_NAME}" | |
| if [[ "$TAG" == v* ]]; then | |
| echo "::error::Tag '$TAG' starts with 'v'. ShellSyntaxTree tags must be bare SemVer version numbers (e.g., '0.1.0-alpha', not 'v0.1.0-alpha'). Delete this tag and retag without the leading 'v'." | |
| exit 1 | |
| fi | |
| if ! [[ "$TAG" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9._-]+)?$ ]]; then | |
| echo "::error::Tag '$TAG' is not a valid SemVer version. Expected '<major>.<minor>.<patch>' or '<major>.<minor>.<patch>-<prerelease>' (e.g., '1.0.0' or '0.2.0-beta.1')." | |
| exit 1 | |
| fi | |
| echo "PACKAGE_VERSION=${TAG}" >> "$GITHUB_ENV" | |
| echo "Tag '$TAG' is a valid bare version. Publishing package version: ${TAG}" | |
| - name: "Checkout" | |
| uses: actions/checkout@v6.0.2 | |
| with: | |
| lfs: true | |
| fetch-depth: 0 | |
| - name: "Install .NET SDK" | |
| uses: actions/setup-dotnet@v5.1.0 | |
| with: | |
| global-json-file: "./global.json" | |
| - name: "Restore .NET tools" | |
| run: dotnet tool restore | |
| - name: "dotnet pack" | |
| run: dotnet pack /p:PackageVersion=${{ env.PACKAGE_VERSION }} -c Release -o ./output | |
| - name: "NuGet login (OIDC)" | |
| # Exchanges the workflow's OIDC token for a short-lived NuGet API key | |
| # under the Trusted Publisher policy configured on nuget.org. | |
| # Requires: | |
| # - permissions.id-token: write at the workflow level (above) | |
| # - environment: nuget on this job (matches the policy) | |
| # - NUGET_USER repo secret = the package owner's nuget.org username | |
| # See https://learn.microsoft.com/en-us/nuget/nuget-org/trusted-publishing | |
| uses: NuGet/login@v1 | |
| id: nuget-login | |
| with: | |
| user: ${{ secrets.NUGET_USER }} | |
| - name: "dotnet nuget push" | |
| run: | | |
| dotnet nuget push "output/*.nupkg" \ | |
| --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} \ | |
| --source https://api.nuget.org/v3/index.json \ | |
| --skip-duplicate | |
| dotnet nuget push "output/*.snupkg" \ | |
| --api-key ${{ steps.nuget-login.outputs.NUGET_API_KEY }} \ | |
| --source https://api.nuget.org/v3/index.json \ | |
| --skip-duplicate | |
| - name: "Extract latest release notes" | |
| shell: pwsh | |
| run: | | |
| # RELEASE_NOTES.md uses `#### X.Y.Z[-suffix] <date> ####` per-section | |
| # headings. Capture only the BODY of the first section (no heading) | |
| # so the GitHub release page doesn't duplicate the version string in | |
| # both the title and the first line of the body, and so a stale | |
| # hand-typed date in the heading doesn't fight the published date | |
| # GitHub renders automatically. | |
| if (-not (Test-Path RELEASE_NOTES.md)) { | |
| "No release notes available." | Set-Content RELEASE_NOTES_LATEST.md | |
| exit 0 | |
| } | |
| $content = Get-Content RELEASE_NOTES.md -Raw | |
| if ($content -match '(?s)####[^\r\n]*\r?\n+(.+?)(?=\r?\n####|\z)') { | |
| $Matches[1].Trim() | Set-Content RELEASE_NOTES_LATEST.md | |
| } else { | |
| $content | Set-Content RELEASE_NOTES_LATEST.md | |
| } | |
| - name: "Create GitHub release" | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| name: "ShellSyntaxTree ${{ github.ref_name }}" | |
| tag_name: ${{ github.ref_name }} | |
| body_path: RELEASE_NOTES_LATEST.md | |
| files: | | |
| output/*.nupkg | |
| output/*.snupkg | |
| draft: false | |
| prerelease: ${{ contains(github.ref_name, '-') }} | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} |