Files
docs/standards/mcp/modules/versioning_and_changelog.json
Vishesh 'ironeagle' Bangotra 8cc9631fe7 feat(standards): add versioning + changelog standard, release templates, and Drone version guard
Add lib page 11 (SemVer contract, pre-1.0 rule, tag==version invariant, Keep a Changelog), the releasing wiki runbook, and canonical release templates (CHANGELOG.md, VERSION). Vendor them into the MCP bundle as templates/release + release.json and expose registry://release with list/get tools. Add a changelog component to the app template. Enforce the tag<->version contract in both Drone shapes: Type A check-version and the backfill loop verify pyproject version; Type B adds a VERSION guard step.
2026-10-15 01:24:25 +05:30

8 lines
4.2 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"module": "versioning_and_changelog",
"content": {
"path": "versioning_and_changelog",
"docstring": "# Versioning & Changelog\n\n## Summary\n\nEvery Aetos artifact — library, service, or site — is versioned with\n[Semantic Versioning](https://semver.org/spec/v2.0.0.html) and documents its\nreleases in a [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) file.\nThe **version file is the source of truth**, the **git tag must equal it**, and\na Drone guard enforces that equality before anything is published. Releases are\ncut manually; a tag is what triggers the pipeline.\n\nThis page pairs with [10 – Drone Pipelines](10_drone_pipelines.md): the version\nand tag contract is exactly what those two CI shapes consume.\n\n---\n\n## The version contract\n\n| Artifact | Source of truth | Notes |\n|----------|-----------------|-------|\n| Library (PyPI package) | `version` in `pyproject.toml` | `check-version` also reads it to skip duplicates |\n| Service / site (Docker) | `VERSION` file at the repo root | one line, `x.y.z` |\n\nRules:\n\n1. **One version per repository.** No per-module versions.\n2. **Tag = version.** The git tag is bare SemVer (`0.0.6`), no `v` prefix, and\n it MUST match the version file byte-for-byte. The Drone guard fails the\n build otherwise — this is what stops a tag from silently publishing nothing.\n3. **A release is a tag.** Bump the version file, promote the changelog, commit,\n tag, push. Everything else is automated by Drone.\n4. **Never reuse a tag.** If a release is wrong, cut a new patch version.\n\n### Pre-1.0 (0.y.z)\n\nWhile a package is `0.y.z`, **`0.y` is treated as the major line**:\n\n- breaking change → `0.(y+1).0`\n- new feature → `0.y.(z+1)`\n- bug fix → `0.y.(z+1)`\n\nOnce a package reaches `1.0.0`, normal SemVer applies. Do not ship `1.0.0`\nuntil the public API is considered stable.\n\n---\n\n## The changelog\n\n`CHANGELOG.md` at the repo root, in Keep a Changelog form. It always has exactly\none open `[Unreleased]` section with the change categories that apply:\n\n```markdown\n## [Unreleased]\n\n### Added\n### Changed\n### Deprecated\n### Removed\n### Fixed\n### Security\n```\n\nOn release you **promote** it — never delete history:\n\n```markdown\n## [0.0.6] - 2026-03-07\n\n### Added\n- ...\n```\n\nand add a link reference at the bottom:\n\n```markdown\n[Unreleased]: https://git.aetoskia.com/aetos/<repo>/compare/0.0.6...HEAD\n[0.0.6]: https://git.aetoskia.com/aetos/<repo>/compare/0.0.5...0.0.6\n```\n\nConventions:\n\n- Write entries for humans: one line each, imperative, referencing the user\n impact, not the commit hash.\n- Categories: **Added**, **Changed**, **Deprecated**, **Removed**, **Fixed**,\n **Security**. Omit empty categories.\n- Security fixes get their own entry even if the change is otherwise a bug fix.\n- The `[Unreleased]` heading is never renamed; copy its content into the new\n version heading and clear it.\n\n---\n\n## Release checklist\n\n1. Confirm the quality gate is green on `main`.\n2. Move every `[Unreleased]` entry under the new version heading with today's\n date (`## [x.y.z] - YYYY-MM-DD`); restore an empty `[Unreleased]` on top.\n3. Add the two compare-link references at the bottom of the changelog.\n4. Set the version file: `pyproject.toml` (`version = \"x.y.z\"`) or `VERSION`.\n5. Commit: `chore(release): x.y.z`.\n6. Tag: `git tag x.y.z` and push the tag (`git push origin x.y.z`).\n7. Watch Drone: Type A publishes the wheel/sdist, Type B builds and deploys the\n image. Both first assert `tag == version`.\n8. Do not reuse the tag if the run fails — fix and cut `x.y.(z+1)`.\n\n---\n\n## Why the guard matters\n\nThe version file and the tag are two facts that must agree; nothing in git\nenforces that by itself. A mismatch is not a theoretical risk — a package can be\ntagged `0.0.2` while its `pyproject.toml` still says `0.0.1`, and the publish\nstep (which compares the **file** against the index) then skips the build\nentirely, so `0.0.2` never reaches the index while looking like a release. The\nDrone guard turns that silent no-op into a hard failure.\n\n---\n\n## Related\n\n- [10 – Drone Pipelines](10_drone_pipelines.md) · [01 – Build Recipe](01_build_recipe.md) · [13 – Library Registry](13_library_registry.md)\n",
"objects": {}
}
}