diff --git a/.github/skills/ef-migration/SKILL.md b/.github/skills/ef-migration/SKILL.md new file mode 100644 index 0000000..6a327bc --- /dev/null +++ b/.github/skills/ef-migration/SKILL.md @@ -0,0 +1,56 @@ +--- +name: ef-migration +description: 'Add, remove, or apply Entity Framework Core migrations against a project under src/. Use when: creating a new migration, reverting the last migration, generating a migration bundle, applying migrations to a database.' +argument-hint: 'Describe the schema change (e.g., "add audit columns to Orders") and the target DbContext if multiple exist' +--- + +# EF Core Migration + +## Prerequisites + +- The EF project (containing the `DbContext`) is referenced by — or is itself — a runnable startup project. +- Requires `dotnet ef`: `dotnet tool restore` (if a manifest exists) or `dotnet tool install -g dotnet-ef`. + +## Conventions + +- **Migration name**: `PascalCase`, imperative, third person, ≤ 60 chars (e.g., `AddsOrderAuditColumns`, not `audit_changes` or `Migration1`). +- **Output folder**: default `Migrations/` inside the EF project. Do not relocate. +- **One DbContext per command** — pass `--context` whenever the project has more than one. +- **Never edit a migration after it has been applied to a shared environment.** Add a corrective migration instead. +- **Commit migrations together with the model change** that produced them. + +## Procedure + +The **EF project** contains the `DbContext`; the **startup project** is the runnable project EF executes against (usually a web/worker referencing the EF project). + +1. **Add the migration:** + ```bash + dotnet ef migrations add \ + --project src/ \ + --startup-project src/ \ + --context + ``` +2. **Inspect** the generated `*.cs` and `*.Designer.cs` files for unintended changes (unrelated columns, dropped indices). +3. **If wrong, remove before committing:** + ```bash + dotnet ef migrations remove --project src/ --startup-project src/ + ``` + +For a deployable migration binary, use the [docker-build](../docker-build/SKILL.md) skill's `migrations` target. + +## Generating an SQL Script + +```bash +dotnet ef migrations script \ + --project src/ \ + --startup-project src/ \ + --idempotent \ + --output artifacts/migrations.sql +``` + +Use `--idempotent` whenever the script may run against a database in an unknown state. + +## Troubleshooting + +- **"Unable to create a 'DbContext'…"** — pass `--startup-project` explicitly; auto-detection picks the wrong project in multi-project solutions. +- **Multiple DbContexts found** — pass `--context `. diff --git a/.github/skills/new-adr/MADR.md b/.github/skills/new-adr/MADR.md new file mode 100644 index 0000000..d05e64b --- /dev/null +++ b/.github/skills/new-adr/MADR.md @@ -0,0 +1,70 @@ +--- +status: proposed +date: YYYY-MM-DD +decision-makers: [names or roles] +# consulted: [subject-matter experts with two-way communication] +# informed: [stakeholders kept up-to-date with one-way communication] +--- +# NNNN. {short title, representative of solved problem and found solution} + +## Context and Problem Statement + +{Describe the context and problem statement in two to three sentences, or as a short illustrative story. Articulate the problem as a question if helpful, and link to issues, PRs, or discussions.} + +## Decision Drivers + +- {decision driver 1, e.g., a force, facing concern, quality attribute} +- {decision driver 2} +- … + +## Considered Options + +- {title of option 1} +- {title of option 2} +- {title of option 3} +- … + +## Decision Outcome + +Chosen option: **"{title of option X}"**, because {justification — e.g., the only option meeting a k.o. criterion, resolves driver {driver}, or comes out best in the comparison below}. + +### Consequences + +- Good, because {positive consequence}. +- Bad, because {negative consequence / accepted trade-off}. +- Follow-up: {action item, if any}. + + +### Confirmation + +{How will compliance with this ADR be confirmed? E.g., a design/code review, an ArchUnit test, a CI check, or a follow-up audit.} + + +## Pros and Cons of the Options + +### Comparison + +| Driver | {Option 1} | {Option 2} | {Option 3} | +| ---------- | ---------- | ---------- | ---------- | +| {driver 1} | Yes | Maybe | No | +| {driver 2} | No | Yes | Yes | + +### {title of option 1} + +{example | description | pointer to more information} + +- Good, because {argument}. +- Neutral, because {argument}. +- Bad, because {argument}. + +### {title of option 2} + +{example | description | pointer to more information} + +- Good, because {argument}. +- Bad, because {argument}. + + +## More Information + +{Additional evidence/confidence for the decision, team agreement notes, when/how to revisit, links to related ADRs and resources.} diff --git a/.github/skills/new-adr/SKILL.md b/.github/skills/new-adr/SKILL.md new file mode 100644 index 0000000..7bd6e3e --- /dev/null +++ b/.github/skills/new-adr/SKILL.md @@ -0,0 +1,97 @@ +--- +name: new-adr +description: 'Create a new Architectural Decision Record (ADR) capturing a justified design choice that addresses an architecturally significant functional or non-functional requirement. Use when: creating a new ADR, documenting an architectural choice, recording a design decision, superseding a previous decision, capturing rationale for a framework/library/pattern selection.' +argument-hint: 'Brief description of the decision (e.g., "adopt Minimal APIs over MVC controllers")' +--- +# New Architectural Decision Record + +You are assisting the user in producing a well-structured, comprehensive ADR. Ask clarifying questions, offer suggestions and examples, and ensure the record follows the standard format with all required sections filled. + +Reference: . + +## When to Use + +- A design choice has a **measurable effect on architecture or quality attributes** (security, performance, scalability, maintainability, cost, DX). +- The decision is **non-obvious**, has **trade-offs**, or **supersedes** prior guidance. +- A reviewer or future maintainer would reasonably ask *"why did we do it this way?"*. + +**Not an ADR**: cosmetic refactors, bug fixes, style preferences, or decisions with no viable alternatives. Use a commit message or code comment instead. + +## Location & Filename + +- **Folder**: `docs/adr/` +- **Filename**: `NNNN-kebab-title.md` (zero-padded, four digits, sequential; e.g., `0001-use-minimal-apis.md`). +- **Index** (optional): `docs/adr/README.md` listing all ADRs with status. + +Determine the next `NNNN` by scanning existing files and incrementing the highest number. Never reuse numbers, even for retracted ADRs. + +## Required Sections + +Every ADR must include these MADR sections, in order: + +1. **Context and Problem Statement** — the situation, goals, and constraints that frame the decision; pose the problem as a question when helpful. +2. **Decision Drivers** — bullet list of forces, concerns, and quality attributes that matter. +3. **Considered Options** — bullet list of viable alternatives. +4. **Decision Outcome** — the chosen option, justification, nested **Consequences** (good/bad/follow-up), and optional **Confirmation** subsection. + +MADR-optional sections (include when they add value): + +- **Pros and Cons of the Options** — per-option Good/Neutral/Bad bullets. Prefix with the comparison table below when more than two options compete. +- **More Information** — links, revisit notes, related ADRs. + +### Comparison Table (project addition) + +When using **Pros and Cons of the Options**, lead with a Yes/No/Maybe matrix scoring each option against each driver. This is a project convention on top of MADR, not part of the spec, but it forces explicit comparison and exposes weak options. + +```markdown +| Driver | Option A | Option B | Option C | +| ---------- | -------- | -------- | -------- | +| {driver 1} | Yes | Maybe | No | +| {driver 2} | No | Yes | Yes | +``` + +## Status Lifecycle + +`proposed` → `accepted` → (`deprecated` | `superseded by ADR-NNNN`) · `rejected` is terminal from `proposed`. + +- New ADRs start as `proposed` unless the user confirms acceptance. +- When superseding, **update the old ADR's status** to `superseded by ADR-NNNN` and add a back-link. Never rewrite history of an accepted ADR. +- `date` reflects the last status change. + +## MADR Template + +This skill follows the [MADR 4.0](https://adr.github.io/madr/) (Markdown Any Decision Records) format with one project addition (see *Comparison Table* above). Copy [MADR.md](MADR.md) to `docs/adr/NNNN-kebab-title.md` and fill in the placeholders. The folder `docs/adr/` is a project convention; MADR's own recommendation is `docs/decisions/`. + +## Procedure + +1. **Confirm significance.** Check against the "When to Use" criteria. If it doesn't qualify, suggest a lighter alternative (code comment, PR description, CHANGELOG entry) and stop. +2. **Assign a number.** List `docs/adr/` and pick the next `NNNN`. +3. **Interview the user — one section at a time.** Ask focused questions for the current section, offer suggestions/examples where useful, then move on. Do not dump every question at once. +4. **Show progress** after each section using a status table with these markers: + - ✔️ completed + - 🟡 in progress + - ➖ not started + + ```markdown + | Section | Status | + | ----------------------------- | ------ | + | Context and Problem Statement | ✔️ | + | Decision Drivers | 🟡 | + | Considered Options | ➖ | + | Decision Outcome | ➖ | + | Consequences | ➖ | + | Pros and Cons (optional) | ➖ | + ``` + +5. **Draft the ADR** as sections are filled. Keep the title short and decision-oriented (`"Use X for Y"` or `"Adopt X over Y"`). Status = `proposed` unless the user confirms acceptance. +6. **Handle supersession.** If this ADR replaces another, update the predecessor's frontmatter `status` to `superseded by ADR-NNNN` and add a cross-link in its body. +7. **Update index.** If `docs/adr/README.md` exists, append the new entry with status; otherwise offer to create one. +8. **Save & confirm.** Write the file to `docs/adr/NNNN-kebab-title.md`, validate frontmatter YAML and filename, and confirm the saved path back to the user. + +## Quality Bar + +- **Title states the decision**, not the topic. ✅ `Use Minimal APIs for new endpoints` · ❌ `API style`. +- **Options are real alternatives** that were genuinely considered — not strawmen. +- **Consequences include the downsides** we accept. An ADR with only positives is incomplete. +- **Links > prose** for context already documented elsewhere (issues, RFCs, benchmarks). +- **Immutable once accepted.** Further changes happen via a new ADR that supersedes. diff --git a/.github/skills/new-release/SKILL.md b/.github/skills/new-release/SKILL.md new file mode 100644 index 0000000..b63a6bd --- /dev/null +++ b/.github/skills/new-release/SKILL.md @@ -0,0 +1,38 @@ +--- +name: new-release +description: 'Cut a new release: tag the appropriate commit, generate the changelog, and produce build artifacts. Use when: releasing a new version, tagging a release, publishing NuGet packages, preparing release artifacts.' +argument-hint: 'Branch or commit to release from (default: current main) and the kind of release (stable, prerelease, hotfix)' +--- + +# New Release + +Versioning is **GitVersion-driven** (`GitVersion.yml`). Do not hand-pick versions — let GitVersion compute them from branch and tag history. + +## Versioning + +| Branch | Label | Resulting version | +| --- | --- | --- | +| `main` | — | `MAJOR.MINOR.PATCH` (stable) | +| `develop` / `dev` / `development` | `beta` | `MAJOR.MINOR.PATCH-beta.N` | +| `release/*`, `hotfix/*`, `feature/*` | branch name | `…-.N` | + +- Tags use the prefix `v` (regex `[vV]?` also accepts `V` or none). +- Only changes under `src/`, `Directory.Packages.props`, or `GitVersion.yml` increment the version. +- Increments are suppressed for already-merged branches and already-tagged commits. + +## Procedure + +1. **Sync.** `git fetch --all --tags && git status` — confirm clean. +2. **Compute.** `dotnet build -getProperty:Version` — verify the value matches expectations. +3. **Pack.** `dotnet pack -c Release` (or use the [docker-build](../docker-build/SKILL.md) `pack` target). Artifacts land in `artifacts/nuget/`. +4. **Tag.** `git tag -a v -m "Release v" && git push origin v`. +5. **Publish** packages to the configured feed. +6. **Create the GitHub release** linked to the tag, using the generated changelog as notes. + +For hotfixes: branch from the latest stable tag (`git switch -c hotfix/ v`), follow the procedure, then back-merge into `main` and `develop`. + +## Guardrails + +- **Tags are immutable** once pushed; never move or delete them. +- **Never skip a `PATCH`** — ship a fix forward. +- **Do not edit `GitVersion.yml` to force a version.** Address the underlying cause (missing tag, branch base, path filter, commit messages).