Skip to content

TASK-005: Implement CI and Quality Gates

Objective

Establish the automated build-and-test gate for the repository: a GitHub Actions workflow, warnings-as-errors, central package management, a shared editorconfig, and coverage collection. This is the foundation every downstream phase depends on for reproducible measurement.

Scope

  • add .github/workflows/ci.yml for restore, build, test, and coverage upload on push and pull request
  • add Directory.Build.props at repo root enabling TreatWarningsAsErrors and consistent nullable settings
  • add Directory.Packages.props at repo root and strip version attributes from individual .csproj files
  • add .editorconfig at repo root codifying current formatting conventions
  • add coverage collection via coverlet.collector and upload as a workflow artifact
  • add a build-status badge reference to the root README (or equivalent) if one exists, or document its absence
  • document branch-protection expectations in the repository

Non-Scope

  • release pipelines, signing, MSIX or installer work
  • deployment or publishing steps
  • performance or benchmark gates
  • external coverage services
  • pre-commit hooks or git hooks
  • adding new static-analysis packages beyond the Roslyn defaults

AI Tool Guidance

This task is small enough to be handed to a single AI session. Recommended order:

  1. Introduce Directory.Build.props and Directory.Packages.props; migrate all project files; confirm dotnet build and dotnet test still pass locally.
  2. Fix any new warnings surfaced by warnings-as-errors — do not suppress them globally. If a warning is genuinely noise, suppress at the narrowest scope possible.
  3. Add .editorconfig last so formatting drift from step 1–2 is captured rather than fought.
  4. Add the CI workflow and confirm it runs green on a throwaway branch before merging.

Each step should produce a small, reviewable change. Do not bundle package migration and CI into one commit.

Acceptance Criteria Mapping

The implementation must satisfy all acceptance criteria from SLICE-005.

Copilot Agent Prompt

The prompt below is intended for GitHub Copilot Chat in agent mode with Claude Sonnet selected. It is self-contained: Copilot should read the spec and task files for authoritative detail, but the prompt names the concrete deliverables, package list, and pitfalls up front so it does not have to re-derive them.

You are implementing TASK-005 in this repository. It is the first slice of Phase 0
from the evolution roadmap: add CI and quality gates so every later slice can be
measured against a reproducible build.

## Authoritative references

Read these before making changes:
- docs/specs/SLICE-005-ci-and-quality-gates.md   (the requirements)
- docs/tasks/TASK-005-implement-ci-and-quality-gates.md   (the objective and AI guidance)
- docs/reviews/2026-04-22-evolution-roadmap.md   (why this slice exists)

The spec's Acceptance Criteria section is the definition of done. Do not drift from it.

## Project layout

.NET 10 WPF desktop app, six projects, no solution file yet:

  src/InspectionPrototype.App            (WPF host, net10.0-windows, UseWPF=true)
  src/InspectionPrototype.Application
  src/InspectionPrototype.Domain
  src/InspectionPrototype.Infrastructure
  src/InspectionPrototype.Presentation
  tests/InspectionPrototype.Tests        (xUnit, 216 tests must stay green)

## Deliverables

1. Directory.Build.props at repo root:
     - TreatWarningsAsErrors=true
     - Nullable=enable
     - LangVersion=latest
     - ManagePackageVersionsCentrally=true

2. Directory.Packages.props at repo root centralizing these versions (strip Version= from .csproj files).

   Bump the three Microsoft.Extensions.* packages from 9.0.4 to the latest stable 10.0.x to match the net10.0-windows target framework. Leave the non-runtime packages (CommunityToolkit.Mvvm, xunit, coverlet, Test.Sdk) at their current versions — bumping them is out of scope.

     - Microsoft.Extensions.Hosting                   10.0.0 (or latest stable 10.0.x — verify on nuget.org at execution time)
     - Microsoft.Extensions.Hosting.Abstractions      10.0.0 (match Hosting)
     - Microsoft.Extensions.Logging.Abstractions      10.0.0 (match Hosting)
     - CommunityToolkit.Mvvm                           8.4.0
     - coverlet.collector                              6.0.4
     - Microsoft.NET.Test.Sdk                         17.14.1
     - xunit                                           2.9.3
     - xunit.runner.visualstudio                       3.1.4

   All three Microsoft.Extensions.* packages must stay on the exact same patch version as each other. Do not mix 10.0.0 with 10.0.1 across them.

3. A solution file (.slnx preferred for .NET 10) at repo root that includes all 6 projects, so CI can run `dotnet build` / `dotnet test` against a single target.

4. .editorconfig at repo root capturing current conventions:
     - indent_style=space, indent_size=4 for C#, 2 for yaml/json/xml
     - end_of_line=crlf (Windows repo), insert_final_newline=true, trim_trailing_whitespace=true
     - C# file-scoped namespaces where already used, preserve existing style

5. .github/workflows/ci.yml:
     - triggers: push to master, pull_request
     - runs-on: windows-latest
     - steps: checkout, setup-dotnet@v4 with 10.0.x, restore, build --no-restore --configuration Release, test --no-build --configuration Release --collect:"XPlat Code Coverage" --results-directory ./coverage
     - uploads coverage directory as a workflow artifact
     - fails fast

6. Update the root README (create one if missing) with:
     - a CI status badge pointing at the new workflow
     - a one-paragraph note that PRs require green CI before merge (branch-protection is applied out-of-band but documented here)

## Constraints

- Do NOT suppress warnings globally to make the build pass. Fix each warning at its site. If a warning is genuinely noise, suppress at the narrowest scope (file or method) with a comment explaining why.
- Do NOT modify any runtime code beyond what warnings-as-errors forces. This slice changes build configuration, not behavior.
- Do NOT bundle the package-migration and the CI workflow into one commit. Use three commits, in this order:
    (a) Directory.Build.props + Directory.Packages.props + solution file + .csproj migration + warning fixes
    (b) .editorconfig
    (c) CI workflow + README/badge
- Do NOT add pre-commit hooks, husky, code-signing, release pipelines, or external coverage services. Out of scope.

## Verification before you report done

Run locally and confirm each passes:
  dotnet restore
  dotnet build --configuration Release          (zero warnings, zero errors)
  dotnet test --configuration Release           (216 tests pass)
  grep -r 'Version="' src tests                 (returns no matches in .csproj files)

Then confirm the CI yaml parses: `actionlint` if available, otherwise read it for obvious syntax errors.

## Report format when finished

- list of files created and files modified
- any warnings you fixed and the category (unused variable, nullable, etc.)
- any warning you could not fix and why (with the narrowest-possible suppression you applied)
- confirmation that all 216 tests still pass
- the three commit hashes in order

Operator notes

  • Use agent mode, not chat mode. This task touches ~15 files across the repo; chat mode applies changes one at a time, agent mode runs to completion.
  • Watch the warning-fix phase. TreatWarningsAsErrors will surface real issues (nullable, unused, possibly CA rules). If the agent suppresses instead of fixes, push back — the point of this slice is a clean build, not a papered-over one.
  • After the agent reports done, skim the three commits, run dotnet test once locally, and open a throwaway pull request to confirm the CI workflow is actually green on push.

Docs-first project memory for AI-assisted implementation.