v0.10.0 — first packages on NuGet #1
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
| # Publish XafLogicExplainer.Core (library), .Cli (dotnet tool) and .Mcp (dotnet tool + MCP server) | |
| # to NuGet.org. | |
| # | |
| # No API key is stored anywhere. This uses NuGet Trusted Publishing, which trades this workflow's | |
| # OIDC token for a short-lived key at run time. It needs a policy at | |
| # nuget.org -> Account -> Trusted Publishing: | |
| # | |
| # Package Owner: peopleworksservices · Repository Owner: peopleworks | |
| # Repository: XAFLogicExplainer · Workflow File: nuget.yml | |
| # | |
| # To ship a version: bump <Version> in Directory.Build.props and the two version fields in | |
| # src/XafLogicExplainer.Mcp/.mcp/server.json, merge, then publish a GitHub Release tagged | |
| # v<that version>. Tests must pass before anything is pushed. | |
| name: Publish NuGet | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| id-token: write # required to obtain the OIDC token for trusted publishing | |
| jobs: | |
| publish: | |
| # Only v<version> tags mean "publish to NuGet". Any other release tag would be read as a | |
| # package version, find nothing packed under that name, and fail — a red X on a release that | |
| # did nothing wrong. | |
| if: github.event_name == 'workflow_dispatch' || startsWith(github.ref_name, 'v') | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@v4 | |
| with: | |
| dotnet-version: "10.0.x" | |
| # A broken build must never reach NuGet — published versions cannot be deleted. | |
| # | |
| # The test project is named rather than the solution: the solution carries the Blazor | |
| # widget, whose DevExpress package reference cannot restore on a public runner. Building | |
| # the tests pulls in Core and Mcp, which is everything being published bar the CLI. | |
| - name: Test | |
| run: dotnet test tests/XafLogicExplainer.Tests -c Release --nologo | |
| - name: Pack | |
| run: | | |
| dotnet pack src/XafLogicExplainer.Core -c Release -o out | |
| dotnet pack src/XafLogicExplainer.Cli -c Release -o out | |
| dotnet pack src/XafLogicExplainer.Mcp -c Release -o out | |
| ls -1 out/ | |
| - name: Check the release tag matches what we built | |
| if: github.event_name == 'release' | |
| run: | | |
| want="${GITHUB_REF_NAME#v}" | |
| # Guards the classic footgun: tagging v0.11.0 while Directory.Build.props still says | |
| # 0.10.0. --skip-duplicate would swallow that silently and report success. | |
| if ! ls out/*."$want".nupkg >/dev/null 2>&1; then | |
| echo "::error::Release is tagged $GITHUB_REF_NAME, but nothing packed as version $want." | |
| echo "Bump <Version> in Directory.Build.props to $want, or retag the release." | |
| ls -1 out/ | |
| exit 1 | |
| fi | |
| # Symbols are a .NET Foundation eligibility criterion, and a gap here would only surface | |
| # months later when someone tries to step into the library. Every .nupkg must have its | |
| # .snupkg beside it — that adjacency is also what makes the push pick it up. | |
| for pkg in out/*."$want".nupkg; do | |
| if [ ! -f "${pkg%.nupkg}.snupkg" ]; then | |
| echo "::error::$pkg has no matching .snupkg — symbol publishing is broken." | |
| echo "Check IncludeSymbols/SymbolPackageFormat in Directory.Build.props." | |
| exit 1 | |
| fi | |
| done | |
| # The MCP manifest carries its own version twice and the MCP registry serves it to | |
| # clients. If it drifts, the registry advertises a version that does not exist. | |
| manifest="src/XafLogicExplainer.Mcp/.mcp/server.json" | |
| server_version=$(jq -r '.version' "$manifest") | |
| package_version=$(jq -r '.packages[0].version' "$manifest") | |
| if [ "$server_version" != "$want" ] || [ "$package_version" != "$want" ]; then | |
| echo "::error::$manifest says version=$server_version, packages[0].version=$package_version — expected $want." | |
| exit 1 | |
| fi | |
| echo "Tag $GITHUB_REF_NAME matches the packages and the MCP manifest." | |
| - name: NuGet login (trusted publishing) | |
| id: login | |
| uses: NuGet/login@v1 | |
| with: | |
| user: peopleworksservices | |
| # The glob deliberately names only *.nupkg: the NuGet client pushes the matching .snupkg to | |
| # the symbol server on its own whenever one sits beside the package. Adding *.snupkg here | |
| # would push each symbol package twice. | |
| - name: Push to NuGet | |
| run: | | |
| dotnet nuget push "out/*.nupkg" \ | |
| --api-key "${{ steps.login.outputs.NUGET_API_KEY }}" \ | |
| --source https://api.nuget.org/v3/index.json \ | |
| --skip-duplicate |