Skip to content

Plan: NuGet Publishing & CI/CD Pipeline for BenefitManager.Agent.Client#

Context#

BenefitManager.Agent.Client was already extracted as a separate project with full NuGet metadata, but had placeholder URLs, a hardcoded version, and no build pipeline. BenefitManager.Contracts (its dependency) lacked NuGet metadata entirely. No CI/CD workflow existed for building, versioning, or publishing. The goal: make both packages publishable to GitHub Packages with automatic semver from git tags, and produce releases with zipped executables.


Step 1: Add MinVer for automatic versioning#

File: Directory.Build.props

MinVer reads git tags (e.g. v1.0.0) and auto-generates version numbers: - On tag v1.2.0 → version 1.2.0 - 3 commits after tag → 1.2.1-alpha.0.3 - No tags → 0.0.0-alpha.0.N

<PropertyGroup>
  <MinVerTagPrefix>v</MinVerTagPrefix>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="MinVer" Version="6.0.0" PrivateAssets="All" />
</ItemGroup>
  • [x] MinVer added to Directory.Build.props
  • [x] Verified: dotnet pack produces 0.0.0-alpha.0.3 (no tags yet)

Step 2: Make BenefitManager.Contracts NuGet-packable#

File: src/BenefitManager.Contracts/BenefitManager.Contracts.csproj

Added NuGet metadata (PackageId, Authors, Description, License, Tags) and Microsoft.SourceLink.GitHub for debugger symbol resolution. Keeps net10.0 TFM override (cross-platform library).

  • [x] NuGet metadata added
  • [x] SourceLink + snupkg symbols configured

Step 3: Clean up Agent.Client.csproj#

File: src/BenefitManager.Agent.Client/BenefitManager.Agent.Client.csproj

  • [x] Removed <Version>1.0.0</Version> — MinVer handles versioning
  • [x] Removed <LangVersion>, <Nullable>, <ImplicitUsings> — inherited from Directory.Build.props
  • [x] Removed placeholder yourusername URLs and <PackageReleaseNotes> — SourceLink provides repo URL at pack time; release notes come from the GitHub Release body

Step 4: Add nuget.config#

New file: nuget.config (repo root)

Explicitly declares nuget.org as the package source for local development. CI adds the GitHub Packages source dynamically via dotnet nuget add source with GITHUB_TOKEN.

  • [x] nuget.config created

Step 5: Create CI/CD workflow#

New file: .github/workflows/build-and-release.yml

Two trigger paths — both run through the build job:

Push to main: build → test → pack NuGet (prerelease) → push to GitHub Packages

Tag v*: same as above, plus the release job: - dotnet publish Orchestrator + Agent as self-contained win-x64 single-file EXEs - Compress-Archive each publish output into a versioned zip - softprops/action-gh-release@v2 creates GitHub Release with auto-generated notes, zips, and .nupkg files attached

  • [x] Workflow created with build + release jobs
  • [x] fetch-depth: 0 on checkout so MinVer can read full tag history
  • [x] --skip-duplicate on NuGet push (safe re-runs on main)
  • [x] IsPackable=false on Orchestrator + Agent EXEs as safety guard

Step 6: Set IsPackable=false on non-library projects#

  • [x] src/BenefitManager.Orchestrator/BenefitManager.Orchestrator.csproj
  • [x] src/BenefitManager.Agent/BenefitManager.Agent.csproj
  • (Test projects already had IsPackable=false)

Files Changed#

Action File
Modify Directory.Build.props
Modify src/BenefitManager.Contracts/BenefitManager.Contracts.csproj
Modify src/BenefitManager.Agent.Client/BenefitManager.Agent.Client.csproj
Modify src/BenefitManager.Orchestrator/BenefitManager.Orchestrator.csproj
Modify src/BenefitManager.Agent/BenefitManager.Agent.csproj
New .github/workflows/build-and-release.yml
New nuget.config

Releasing a version#

git remote add origin https://github.com/ORG/benefits-mgmt.git
git tag v1.0.0
git push origin main --tags

This triggers: build → test → pack NuGet (1.0.0) → push to GitHub Packages → publish single-file EXEs → zip → create GitHub Release with all artifacts.