Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Do not duplicate language-specific rules here.

Feature -> develop PRs squash-merge - the PR title becomes the single commit on develop. Develop -> main PRs merge-commit - main's history shows one merge commit per release with develop's tip as the second parent. Titles are descriptive and have no versioning effect - versioning is handled by [Nerdbank.GitVersioning](https://github.com/dotnet/Nerdbank.GitVersioning) reading [version.json](../version.json) and git history, not by parsing commit messages.

`develop` leads `main` by a minor. After a `develop -> main` release lands and main's publish completes, bump the minor in [version.json](../version.json) on `develop` via an isolated `bump-version-X.Y` PR, so develop's prereleases sort above main's last stable. A `develop -> main` promotion that carries only maintenance (not a release) holds main's version instead - `git checkout main -- version.json` on the promotion branch. See [AGENTS.md "Release Model"](../AGENTS.md#release-model).

Branch protection enforces the merge method on both bases (develop allows only squash, main allows only merge). When running `gh pr merge` against either base, pick the matching flag (`--squash` for develop, `--merge` for main); a mismatch fails with "Merge method ... is not allowed on this repository". The merge-bot workflow (`.github/workflows/merge-bot-pull-request.yml`) does this dispatch automatically for Dependabot and codegen PRs via a `case` on `base.ref` - keep that pattern when adding new auto-merge jobs.

### Format
Expand Down
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ The template uses a **two-phase model by default**: PRs build fast, publishing i
- *Source-only / no build* (validate + tag + release): you need none of the package/image leaf tasks - only your validation in `test-pull-request.yml`, one `release-asset-*` leaf task for the artifact you attach (or zero, if the release is just a tag), and the verbatim `get-version` + `github-release` + `date-badge` orchestration.
- `get-version-task.yml` installs the .NET SDK only because NBGV needs the runtime to compute the version/tag - heavyweight but expected even for a non-.NET downstream; acceptable as-is.
- **No-op republish guarantee.** A weekly/dispatch publish where NBGV `SemVer2` is **unchanged** (no new commit since the last publish) re-pushes **nothing** to GitHub Releases (the `github-release` job's `release-exists` check skips the create step), NuGet (`dotnet nuget push --skip-duplicate`), or PyPI (`gh-action-pypi-publish` `skip-existing: true`) - all three key on the version string. **Docker always re-pushes** by design: it picks up upstream base-image refreshes (e.g. `ubuntu:rolling`) that aren't visible in the repo. Boundary: `version.json` has **no `pathFilters`**, so *any* commit - including a CI/workflow-only or docs-only change - advances the NBGV git height and therefore `SemVer2`, and the next publish *does* create a fresh release for it even when the shipped binary is byte-identical. This is accepted NBGV behavior; `pathFilters` are intentionally not added.
- **Versioning is semantic and maintainer-controlled.** The `version` (major.minor) in [`version.json`](./version.json) is the version floor; NBGV appends the git height (the SemVer patch position) for the build version. `main` (the public release ref) builds a stable `X.Y.<height>`; `develop` builds a prerelease `X.Y.<height>-g<sha>`. The maintainer edits `version.json`; dependency bumps, CI/workflow fixes, doc edits, and template re-syncs leave it untouched.
- **`develop` leads `main` by a minor.** After a `develop -> main` release lands and main's publish completes, bump the minor in `version.json` on `develop` in an isolated `bump-version-X.Y` PR (squash to develop). This keeps every develop prerelease numerically above main's last stable: at a shared `X.Y`, develop's prerelease `X.Y.<height>-g<sha>` sorts *below* main's stable `X.Y.<height>` in `--version`, `HISTORY.md`, and consumer update prompts, and the lead avoids that.
- **A maintenance `develop -> main` promotion holds main's version.** Catch-up work - dependency bumps, CI/doc fixes, template re-syncs - reaches `main` without releasing develop's leading minor: run `git checkout main -- version.json` on the promotion branch before opening the PR, so `main`'s stable advances only its NBGV height (the patch position), not its minor, and `develop` keeps its lead. A release promotion instead carries develop's version to `main`, and `develop` then bumps again to restore the lead.

## Pull Request Title and Commit Message Conventions

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ See [AGENTS.md "Branching Model"](./AGENTS.md#branching-model) for the authorita
- Feature -> `develop`: **squash-merge** (develop ruleset enforces this; develop is kept linear).
- `develop` -> `main`: **merge-commit** (preserves develop's commit list as a real second-parent reference on main; main ruleset enforces this).
- **`develop` is forward-only.** No `main -> develop` back-merges. The develop squash-only ruleset physically blocks merge commits.
- **A `develop -> main` release requires a develop version bump right after.** Once the merge lands and main's publish completes, raise the `version` minor in [`version.json`](./version.json) on `develop` via an isolated `bump-version-X.Y` PR, so develop's prereleases stay numerically above main's last stable. A `develop -> main` promotion that carries only maintenance (not a release) holds main's version instead (`git checkout main -- version.json` on the promotion branch). See [AGENTS.md "Release Model"](./AGENTS.md#release-model).
- **Bots open parallel PRs against both branches.** [`.github/dependabot.yml`](./.github/dependabot.yml) duplicates each ecosystem entry per branch, and [`.github/workflows/run-codegen-pull-request-task.yml`](./.github/workflows/run-codegen-pull-request-task.yml) runs as a matrix (branch names `codegen-main` and `codegen-develop`). Each branch absorbs its own bot PRs independently - neither falls behind, no back-merges needed.
- **Review-then-merge loop.** Every PR is reviewed by GitHub Copilot. The agent pushes, re-requests a review on the new head (via the `requestReviews` GraphQL mutation), addresses and resolves each finding, repeats until green, and then **waits for the maintainer's explicit permission to merge** - it does not self-merge. See [AGENTS.md "PR Review Etiquette"](./AGENTS.md#pr-review-etiquette) and the [Copilot Review Runbook](./.github/copilot-instructions.md#github-copilot-review-runbook) for the mechanics.

Expand Down