Skip to content
fullstackhero

Reference

CI/CD Pipeline

The GitHub Actions pipeline — build, the parallel test matrix, migrator + integration smoke, the coverage gate, and how container images and NuGet packages are published.

views 0 Last updated

The kit ships two GitHub Actions workflows in .github/workflows/:

  • ci.yml — build, test, and publish the application (API container + NuGet packages).
  • template-smoke.yml — guards the distribution path: scaffolding from the dotnet new template must always build.

ci.yml — build, test, publish

Triggers on pushes to main/develop, v* tags, and PRs to those branches (scoped to src/**), plus manual workflow_dispatch (with an optional version input). PR runs cancel in-progress duplicates.

JobDepends onRuns whenWhat it does
Buildalwaysdotnet build -c Release -warnaserror, scans for vulnerable packages, uploads build output as an artifact.
Test (matrix)Buildalways12 unit/architecture test projects in parallel (fail-fast: false), reusing the build artifact (--no-build).
DbMigrator Container SmokeBuildalwaysPublishes the fsh-db-migrator image (Dockerfile-less SDK publish) and runs apply --catalog-only against an ephemeral Postgres 17 — asserts it finishes successfully. Catches container-publish and DI-graph regressions.
Integration TestsBuildalwaysIntegration.Tests + Integration.Middleware.Tests via WebApplicationFactory + Testcontainers (Docker on the runner). Builds from source.
Coverage GateBuildalwaysWhole-solution coverage via ReportGenerator; fails if line coverage drops below 80% (a ratchet — raise MIN_LINE as coverage grows).
Publish Dev ContainersTest, Integrationpush to developPublishes the API image to GHCR tagged dev-<sha> and dev-latest.
Publish ReleaseTest, Integrationv* tag, or workflow_dispatch on mainPacks NuGet packages + the template, pushes to NuGet.org, and publishes the API image to GHCR tagged <version> and latest.

Releasing

A release publishes both NuGet packages (the BuildingBlocks, selected module Contracts, the fsh CLI, and the dotnet new template) and the API container image. Two ways to trigger it:

Terminal window
# Tag-driven (recommended): the tag name is the version
git tag v10.0.0 && git push origin v10.0.0

…or run the CI/CD Pipeline workflow manually from the Actions tab on main with a version input (e.g. 10.0.0-rc.1).

template-smoke.yml — distribution guard

Runs on changes to .template.config/**, templates/**, clients/**, or src/**. It proves a freshly scaffolded project actually builds:

  • Scaffold (Aspire + React) — packs the template, installs the .nupkg, runs dotnet new fsh ... --aspire true --frontend true, builds the backend (-warnaserror), builds both React apps (npm ci && npm run build), and runs the Architecture tests on the scaffolded output.
  • Scaffold (minimal) — scaffolds backend-only (--aspire false --frontend false) and builds it, guarding the //#if (frontend) / (!aspire) conditional gating in AppHost.cs and the solution.

How CI feeds deployment

The image CI publishes is what you deploy. Reference it by its immutable tag in your environment’s terraform.tfvars:

container_image_tag = "v10.0.0" # or a dev-<sha> tag from the develop branch

Then deploy — see Deploy to AWS with Terraform. For a fully automated path, run the one-command deploy from your own deploy workflow after the image is published.

Local parity

Every CI check has a local equivalent, so you can reproduce a red build before pushing:

Terminal window
dotnet build src/FSH.Starter.slnx -c Release -warnaserror # Build job
dotnet test src/FSH.Starter.slnx -c Release # Test + Integration (needs Docker)