Skip to content

v0.10.0 — first packages on NuGet #1

v0.10.0 — first packages on NuGet

v0.10.0 — first packages on NuGet #1

Workflow file for this run

# 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