feat(standards): MR-based tag strategy + repository inventory (registry://repos)
Versioning standard now documents the MR flow: bump pyproject.toml/VERSION and promote CHANGELOG in the MR (referencing the version/tag, not a commit id), merge/squash, then tag the resulting commit. Adds the agent-assisted tagging procedure (wait for the go-ahead, find the version-bump commit, tag only it, ask the user to push) to both the reference page and the releasing wiki runbook. Adds the repo inventory (src/repos.json -> mcp/repos.json), the registry://repos resource + list_repos tool, the 15_repository_inventory lib page, and two MCP prompts: compliance (remediate repos) and release (agent tagging).
This commit is contained in:
@@ -27,8 +27,9 @@ Rules:
|
||||
2. **Tag = version.** The git tag is bare SemVer (`0.0.6`), no `v` prefix, and
|
||||
it MUST match the version file byte-for-byte. The Drone guard fails the
|
||||
build otherwise — this is what stops a tag from silently publishing nothing.
|
||||
3. **A release is a tag.** Bump the version file, promote the changelog, commit,
|
||||
tag, push. Everything else is automated by Drone.
|
||||
3. **A release is a tag, created after the change is merged.** The version bump
|
||||
and the changelog promotion travel inside the merge request (MR); the tag is
|
||||
added on the merged commit and pushed. See [Tagging strategy](#tagging-strategy-mr-based).
|
||||
4. **Never reuse a tag.** If a release is wrong, cut a new patch version.
|
||||
|
||||
### Pre-1.0 (0.y.z)
|
||||
@@ -88,17 +89,54 @@ Conventions:
|
||||
|
||||
---
|
||||
|
||||
## Tagging strategy (MR-based)
|
||||
|
||||
The release version is known while the change is still a merge request, so the
|
||||
bump travels with the change and only the tag is added afterwards:
|
||||
|
||||
1. **In the MR** — set the intended release version: `version` in
|
||||
`pyproject.toml` (or the `VERSION` file) to `x.y.z`, and promote the
|
||||
changelog (below). Changelog entries and link references name the
|
||||
**version/tag**, never a commit id.
|
||||
2. **Merge or squash** the MR into `main`.
|
||||
3. **Create the tag** `x.y.z` on the resulting commit (the merge/squash commit).
|
||||
4. **Push the tag** (`git push origin x.y.z`) — Drone builds the release.
|
||||
|
||||
Because the version bump is inside the tagged commit, the guard's
|
||||
`tag == version` check can only fail if the wrong commit was tagged.
|
||||
|
||||
### Agent-assisted tagging
|
||||
|
||||
The agent neither authors nor merges the MR, and never tags before the merge.
|
||||
After the user confirms the MR is merged/squashed and says to proceed:
|
||||
|
||||
1. **Wait** for that explicit go-ahead.
|
||||
2. Find the commit that introduced the version bump:
|
||||
- packages:
|
||||
`git log -S 'version = "x.y.z"' -n 1 --format='%H %s' -- pyproject.toml`
|
||||
- services:
|
||||
`git log -S 'x.y.z' -n 1 --format='%H %s' -- VERSION`
|
||||
3. Confirm that commit's version file equals `x.y.z`, then tag **only** that
|
||||
commit, lightweight and bare: `git tag x.y.z <sha>`.
|
||||
4. **Do not push.** Ask the user to push the tag: `git push origin x.y.z`.
|
||||
|
||||
---
|
||||
|
||||
## Release checklist
|
||||
|
||||
1. Confirm the quality gate is green on `main`.
|
||||
2. Move every `[Unreleased]` entry under the new version heading with today's
|
||||
date (`## [x.y.z] - YYYY-MM-DD`); restore an empty `[Unreleased]` on top.
|
||||
3. Add the two compare-link references at the bottom of the changelog.
|
||||
4. Set the version file: `pyproject.toml` (`version = "x.y.z"`) or `VERSION`.
|
||||
5. Commit: `chore(release): x.y.z`.
|
||||
6. Tag: `git tag x.y.z` and push the tag (`git push origin x.y.z`).
|
||||
7. Watch Drone: Type A publishes the wheel/sdist, Type B builds and deploys the
|
||||
image. Both first assert `tag == version`.
|
||||
1. Confirm the quality gate is green and `main` is up to date.
|
||||
2. In the MR: move every `[Unreleased]` entry under the new version heading with
|
||||
the target date (`## [x.y.z] - YYYY-MM-DD`); restore an empty `[Unreleased]`
|
||||
on top.
|
||||
3. In the MR: add the two compare-link references at the bottom of the
|
||||
changelog, naming the version/tag (never a commit id).
|
||||
4. In the MR: set the version file — `pyproject.toml` (`version = "x.y.z"`) or
|
||||
`VERSION` — to the intended release version.
|
||||
5. Merge or squash the MR into `main`.
|
||||
6. Create the tag on the resulting commit: lightweight `git tag x.y.z`.
|
||||
7. Push the tag (`git push origin x.y.z`). Watch Drone: Type A publishes the
|
||||
wheel/sdist, Type B builds and deploys the image; both first assert
|
||||
`tag == version`.
|
||||
8. Do not reuse the tag if the run fails — fix and cut `x.y.(z+1)`.
|
||||
|
||||
---
|
||||
@@ -116,4 +154,4 @@ Drone guard turns that silent no-op into a hard failure.
|
||||
|
||||
## Related
|
||||
|
||||
- [10 – Drone Pipelines](10_drone_pipelines.md) · [01 – Build Recipe](01_build_recipe.md) · [13 – Library Registry](13_library_registry.md)
|
||||
- [10 – Drone Pipelines](10_drone_pipelines.md) · [15 – Repository Inventory](15_repository_inventory.md) · [01 – Build Recipe](01_build_recipe.md) · [13 – Library Registry](13_library_registry.md)
|
||||
|
||||
74
standards/src/lib/15_repository_inventory.md
Normal file
74
standards/src/lib/15_repository_inventory.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# Repository Inventory
|
||||
|
||||
## Summary
|
||||
|
||||
The canonical list of Aetos repositories covered by the CI and versioning
|
||||
standards, with the artifact each one produces, its version source, and its
|
||||
Drone shape. Every entry maps to the contract in
|
||||
[11 – Versioning & Changelog](11_versioning_and_changelog.md) and the two CI
|
||||
files in [10 – Drone Pipelines](10_drone_pipelines.md).
|
||||
|
||||
The same data is published machine-readably as the `registry://repos` MCP
|
||||
resource (and the `list_repos` tool), sourced from `standards/src/repos.json`.
|
||||
Paths are relative to the `aetos/` workspace root.
|
||||
|
||||
---
|
||||
|
||||
## Packages (Type A)
|
||||
|
||||
A wheel + sdist published to the private index. Version source is
|
||||
`pyproject.toml`; Drone file is `python-lib.yaml` (tag-triggered).
|
||||
|
||||
| Repo | Path | Docs | MCP server |
|
||||
|------|------|------|------------|
|
||||
| `dagpipe` | `dagpipe` | lib, wiki | `dagpipe:8006` |
|
||||
| `doc-forge` | `doc-forge` | lib, wiki | `docforge:8001` |
|
||||
| `hexa` | `hexa` | lib, wiki | `hexa:8008` |
|
||||
| `mail-intake` | `mail-intake` | lib, wiki | `mail_intake:8002` |
|
||||
| `mongo-ops` | `mongo-ops` | lib, wiki | `mongo_ops:8007` |
|
||||
| `omniread` | `omniread` | lib, wiki | `omniread:8003` |
|
||||
| `openapi-first` | `openapi-first` | lib, wiki | `openapi_first:8004` |
|
||||
| `py-jwt` | `py-jwt` | lib, wiki | `jwtlib:8005` |
|
||||
|
||||
---
|
||||
|
||||
## Services & sites (Type B)
|
||||
|
||||
A container image pushed to the registry and run on the Docker host. Version
|
||||
source is the `VERSION` file; Drone file is `service-docker.yaml`.
|
||||
|
||||
| Repo | Type | Path | Trigger | Docs |
|
||||
|------|------|------|---------|------|
|
||||
| `auth-server` | service | `auth-server` | tag | api, lib, wiki |
|
||||
| `docs` | site | `docs` | push | — |
|
||||
| `mcp` | site | `mcp` | push | — |
|
||||
|
||||
The **service** variant is tag-triggered and enforces `tag == VERSION`. The
|
||||
**site** variant is push-triggered, ships `:latest`, and has no tag guard.
|
||||
|
||||
---
|
||||
|
||||
## Required files per repo
|
||||
|
||||
| Type | Version source | Changelog | Drone |
|
||||
|------|----------------|-----------|-------|
|
||||
| package | `pyproject.toml` | `CHANGELOG.md` | `python-lib.yaml` |
|
||||
| service / site | `VERSION` | `CHANGELOG.md` | `service-docker.yaml` |
|
||||
|
||||
Every covered repository must be able to satisfy `tag == version`:
|
||||
the version file (never a commit id) is bumped in the release MR, the MR is
|
||||
merged, and the tag is created on the merged commit.
|
||||
|
||||
---
|
||||
|
||||
## Reading this at runtime
|
||||
|
||||
- Resource: `registry://repos`
|
||||
- Tool: `list_repos()`
|
||||
- Humans: this page (mirror of `standards/src/repos.json`).
|
||||
|
||||
---
|
||||
|
||||
## Related
|
||||
|
||||
- [10 – Drone Pipelines](10_drone_pipelines.md) · [11 – Versioning & Changelog](11_versioning_and_changelog.md) · [13 – Library Registry](13_library_registry.md)
|
||||
@@ -17,6 +17,8 @@ patterns, and the internal library catalog that agents consult while coding.
|
||||
- **Drone Pipelines** — the two CI shapes: a PyPI package or a Docker deployment.
|
||||
- **Versioning & Changelog** — SemVer, the tag↔version contract, and the release
|
||||
changelog.
|
||||
- **Repository Inventory** — every covered repo, its type, version source, and
|
||||
Drone shape.
|
||||
- **Genericity Matrix** — what is library-backed, template-provided, or authored.
|
||||
- **Auth Integration** — consuming the shared auth-server service (spec-driven,
|
||||
no auth code).
|
||||
|
||||
Reference in New Issue
Block a user