docs(standards): rebuild lib + wiki HTML for versioning/changelog and drone pages

This commit is contained in:
2026-10-15 14:21:50 +05:30
parent 8cc9631fe7
commit df03f41771
27 changed files with 3550 additions and 4 deletions

View File

@@ -549,6 +549,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -540,6 +540,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -531,6 +531,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -558,6 +558,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -567,6 +567,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -558,6 +558,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -531,6 +531,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -540,6 +540,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -14,7 +14,7 @@
<link rel="prev" href="../08_human_in_loop/"> <link rel="prev" href="../08_human_in_loop/">
<link rel="next" href="../12_genericity_matrix/"> <link rel="next" href="../10_drone_pipelines/">
<link rel="icon" href="../assets/images/favicon.png"> <link rel="icon" href="../assets/images/favicon.png">
@@ -558,6 +558,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -0,0 +1,935 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="The rules and library registry of the standardized application blueprint.">
<link rel="prev" href="../09_infra_adaptors/">
<link rel="next" href="../11_versioning_and_changelog/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.23">
<title>Drone Pipelines - Aetos Standards — Reference</title>
<link rel="stylesheet" href="../assets/stylesheets/main.84d31ad4.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#drone-pipelines" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="Aetos Standards — Reference" class="md-header__button md-logo" aria-label="Aetos Standards — Reference" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Aetos Standards — Reference
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Drone Pipelines
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan" aria-hidden="true" type="radio" name="__palette" id="__palette_0">
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="Aetos Standards — Reference" class="md-nav__button md-logo" aria-label="Aetos Standards — Reference" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
Aetos Standards — Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../01_build_recipe/" class="md-nav__link">
<span class="md-ellipsis">
Build Recipe
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../02_layering_rules/" class="md-nav__link">
<span class="md-ellipsis">
Layering Rules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../03_composition_root/" class="md-nav__link">
<span class="md-ellipsis">
Composition Root
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../04_spec_first_routing/" class="md-nav__link">
<span class="md-ellipsis">
Spec-First Routing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../05_crud_template/" class="md-nav__link">
<span class="md-ellipsis">
CRUD Template
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../06_pipeline_scaffold/" class="md-nav__link">
<span class="md-ellipsis">
Pipeline Scaffold
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../07_worker_and_progress/" class="md-nav__link">
<span class="md-ellipsis">
Worker & Progress
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../08_human_in_loop/" class="md-nav__link">
<span class="md-ellipsis">
Human-in-the-Loop
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../09_infra_adaptors/" class="md-nav__link">
<span class="md-ellipsis">
Infra Adapters
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Drone Pipelines
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#summary" class="md-nav__link">
<span class="md-ellipsis">
Summary
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#type-a-pypi-package-python-libyaml" class="md-nav__link">
<span class="md-ellipsis">
Type A — PyPI package (python-lib.yaml)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#type-b-docker-deployment-service-dockeryaml" class="md-nav__link">
<span class="md-ellipsis">
Type B — Docker deployment (service-docker.yaml)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#what-not-to-do" class="md-nav__link">
<span class="md-ellipsis">
What not to do
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#related" class="md-nav__link">
<span class="md-ellipsis">
Related
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link">
<span class="md-ellipsis">
Genericity Matrix
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../14_auth_integration/" class="md-nav__link">
<span class="md-ellipsis">
Auth Integration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../13_library_registry/" class="md-nav__link">
<span class="md-ellipsis">
Library Registry
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#summary" class="md-nav__link">
<span class="md-ellipsis">
Summary
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#type-a-pypi-package-python-libyaml" class="md-nav__link">
<span class="md-ellipsis">
Type A — PyPI package (python-lib.yaml)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#type-b-docker-deployment-service-dockeryaml" class="md-nav__link">
<span class="md-ellipsis">
Type B — Docker deployment (service-docker.yaml)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#what-not-to-do" class="md-nav__link">
<span class="md-ellipsis">
What not to do
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#related" class="md-nav__link">
<span class="md-ellipsis">
Related
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="drone-pipelines">Drone Pipelines</h1>
<h2 id="summary">Summary</h2>
<p>Every Aetos repository ships a Drone CI definition at <code>.drone.yml</code>. There is
exactly <strong>one standard per repository</strong>, and there are <strong>two types of file</strong>,
chosen by what the repository produces:</p>
<table>
<thead>
<tr>
<th>Type</th>
<th>File</th>
<th>Produces</th>
<th>Repos</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>A — PyPI package</strong></td>
<td><code>templates/drone/python-lib.yaml</code></td>
<td>A wheel + sdist on the private index</td>
<td><code>dagpipe</code>, <code>doc-forge</code>, <code>hexa</code>, <code>mail-intake</code>, <code>mongo-ops</code>, <code>omniread</code>, <code>openapi-first</code>, <code>py-jwt</code></td>
</tr>
<tr>
<td><strong>B — Docker deployment</strong></td>
<td><code>templates/drone/service-docker.yaml</code></td>
<td>An image pushed to the registry and run as a container</td>
<td><code>auth-server</code>, <code>docs</code>, <code>mcp</code></td>
</tr>
</tbody>
</table>
<p>Both templates run on <code>platform: linux / arm64</code> with the workspace at
<code>/drone/src</code>. Copy the matching template to <code>&lt;repo&gt;/.drone.yml</code>; the Type A file
needs no edits, the Type B file needs its placeholders filled in (below).</p>
<blockquote>
<p>Conventions: <code>.drone.yml</code> (not <code>.yaml</code>), one file per repo, secrets injected
with <code>from_secret</code> — never commit credentials.</p>
</blockquote>
<hr />
<h2 id="type-a-pypi-package-python-libyaml">Type A — PyPI package (<code>python-lib.yaml</code>)</h2>
<p>For internal libraries. The file contains <strong>two pipelines</strong>:</p>
<ol>
<li><strong><code>build-and-publish-pypi</code></strong> — triggered on <code>tag</code>:</li>
<li><code>check-version</code> — <strong>guard</strong>: fail unless <code>$DRONE_TAG</code> equals the version in
<code>pyproject.toml</code>; then read <code>name</code> / <code>version</code> and query
<code>$PIP_REPO_URL/simple/&lt;package&gt;/</code>; if that version already exists, exit
<code>78</code> and skip the whole build (see <a href="../11_versioning_and_changelog/">11 – Versioning &amp; Changelog</a>).</li>
<li><code>quality-gate</code> — install the package with its <code>[dev]</code> extras from the
private index, then <code>black --check</code>, <code>ruff check</code>, <code>mypy</code>, <code>pydoclint</code>,
<code>pytest</code>.</li>
<li><code>build-package</code> — <code>python -m build</code> into <code>dist/</code>.</li>
<li><code>upload-to-private-pypi</code> — <code>twine upload</code> to <code>$PIP_REPO_URL</code>.</li>
<li><strong><code>backfill-pypi-from-tags</code></strong> — triggered on <code>custom</code>:</li>
<li><code>fetch-tags</code> — <code>git fetch --tags --force</code>.</li>
<li><code>build-and-upload-missing</code> — walk every tag in version order, skip the ones
already on the index, <code>git checkout</code> the rest, verify <code>tag == pyproject
version</code> at that commit, build, and upload. This is the disaster-recovery /
replay path.</li>
</ol>
<p>Secrets: <code>PIP_REPO_URL</code>, <code>PIP_USERNAME</code>, <code>PIP_PASSWORD</code>.</p>
<ul>
<li><strong>Ship as-is.</strong> Package name and version come from <code>pyproject.toml</code>, so the
same file is reused verbatim across every library.</li>
</ul>
<hr />
<h2 id="type-b-docker-deployment-service-dockeryaml">Type B — Docker deployment (<code>service-docker.yaml</code>)</h2>
<p>For services and sites that ship a container image. The file contains <strong>two
pipelines</strong>, each mirroring a repo family:</p>
<ol>
<li><strong><code>build-and-deploy-service</code></strong> — triggered on <code>tag</code> (a long-running
API/worker service, e.g. <code>auth-server</code>):</li>
<li><code>fetch-tags</code> — resolve the latest tag into <code>LATEST_TAG.txt</code>; fail if there
are no tags.</li>
<li><code>check-version</code> — <strong>guard</strong>: fail unless <code>$DRONE_TAG</code> equals the repo-root
<code>VERSION</code> file (see <a href="../11_versioning_and_changelog/">11 – Versioning &amp; Changelog</a>).</li>
<li><code>check-remote-image</code> — if <code>aetos/&lt;app&gt;:&lt;tag&gt;</code> already exists locally, exit
<code>78</code> and skip the build.</li>
<li><code>quality-gate</code> — install from <code>requirements.txt</code> and run
<code>black</code> / <code>ruff</code> / <code>mypy</code> / <code>pytest</code>.</li>
<li><code>build-image</code> — <code>docker build</code> with the private-index build args, tagged
<code>aetos/&lt;app&gt;:&lt;tag&gt;</code> and <code>:latest</code>.</li>
<li><code>push-image</code> — login, re-tag with <code>$REGISTRY_HOST</code>, push both tags.</li>
<li><code>stop-old</code> — <code>docker rm -f &lt;app&gt;</code>.</li>
<li><code>run-container</code> — <code>docker run -d --name &lt;app&gt; -p &lt;host&gt;:&lt;container&gt;
--restart always</code> with the service's <code>-e</code> environment.</li>
<li><strong><code>build-and-deploy-site</code></strong> — triggered on <code>push</code> (a static/HTTP site, e.g.
<code>docs</code>, <code>mcp</code>): <code>build-image</code> → <code>push-image</code> → <code>stop-old</code> → <code>run-container</code>,
with no tag resolution, no quality gate, and no version guard (it ships
<code>:latest</code> only).</li>
</ol>
<p>Secrets: <code>PIP_REPO_URL</code>, <code>PIP_USERNAME</code>, <code>PIP_PASSWORD</code> (service build args),
<code>REGISTRY_HOST</code>, <code>REGISTRY_USER</code>, <code>REGISTRY_PASS</code>, plus the service runtime env
(for example <code>MONGO_*</code>, <code>JWT_SECRET</code>).</p>
<p>Placeholders to fill in per repo:</p>
<table>
<thead>
<tr>
<th>Placeholder</th>
<th>Meaning</th>
<th>Example</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>&lt;app&gt;</code></td>
<td>service image / container name</td>
<td><code>auth-server</code></td>
</tr>
<tr>
<td><code>aetos/&lt;app&gt;</code></td>
<td>image repository on the registry</td>
<td><code>aetos/auth-server</code></td>
</tr>
<tr>
<td><code>&lt;host-port&gt;</code> / <code>&lt;container-port&gt;</code></td>
<td>published : in-image port</td>
<td><code>9003:8000</code></td>
</tr>
<tr>
<td><code>&lt;site&gt;</code></td>
<td>site image / container name</td>
<td><code>docs</code></td>
</tr>
<tr>
<td><code>&lt;ENV_VAR&gt;</code></td>
<td>runtime environment variable</td>
<td><code>MONGO_HOST</code></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="what-not-to-do">What not to do</h2>
<ul>
<li>Do not hand-roll a third shape. A repo is either Type A or Type B, never both.</li>
<li>Do not inline secrets; always use <code>from_secret</code>.</li>
<li>Do not drop the <code>check-version</code> / <code>check-remote-image</code> skip — it guards the
index and the running container against duplicate publishes.</li>
<li>Do not drop the tag↔version guard. A package needs its <code>pyproject.toml</code>
version to equal the tag; a service needs a root <code>VERSION</code> file that equals
the tag. See <a href="../11_versioning_and_changelog/">11 – Versioning &amp; Changelog</a>.</li>
<li>Do not rename the pipelines; tooling and runbooks key off
<code>build-and-publish-pypi</code>, <code>build-and-deploy-service</code>, and
<code>build-and-deploy-site</code>.</li>
</ul>
<hr />
<h2 id="related">Related</h2>
<ul>
<li><a href="../01_build_recipe/">01 – Build Recipe</a> · <a href="../09_infra_adaptors/">09 – Infra Adapters</a> · <a href="../11_versioning_and_changelog/">11 – Versioning &amp; Changelog</a> · <a href="../13_library_registry/">13 – Library Registry</a></li>
</ul>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": ["navigation.sections", "navigation.expand", "navigation.top", "navigation.instant", "navigation.tracking", "navigation.indexes", "content.code.copy", "content.code.annotate", "content.tabs.link", "content.action.edit", "search.highlight", "search.share", "search.suggest"], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
</body>
</html>

View File

@@ -0,0 +1,959 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="The rules and library registry of the standardized application blueprint.">
<link rel="prev" href="../10_drone_pipelines/">
<link rel="next" href="../12_genericity_matrix/">
<link rel="icon" href="../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.23">
<title>Versioning & Changelog - Aetos Standards — Reference</title>
<link rel="stylesheet" href="../assets/stylesheets/main.84d31ad4.min.css">
<link rel="stylesheet" href="../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<script>__md_scope=new URL("..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#versioning-changelog" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header md-header--shadow" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href=".." title="Aetos Standards — Reference" class="md-header__button md-logo" aria-label="Aetos Standards — Reference" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Aetos Standards — Reference
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan" aria-hidden="true" type="radio" name="__palette" id="__palette_0">
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href=".." title="Aetos Standards — Reference" class="md-nav__button md-logo" aria-label="Aetos Standards — Reference" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
Aetos Standards — Reference
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href=".." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../01_build_recipe/" class="md-nav__link">
<span class="md-ellipsis">
Build Recipe
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../02_layering_rules/" class="md-nav__link">
<span class="md-ellipsis">
Layering Rules
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../03_composition_root/" class="md-nav__link">
<span class="md-ellipsis">
Composition Root
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../04_spec_first_routing/" class="md-nav__link">
<span class="md-ellipsis">
Spec-First Routing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../05_crud_template/" class="md-nav__link">
<span class="md-ellipsis">
CRUD Template
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../06_pipeline_scaffold/" class="md-nav__link">
<span class="md-ellipsis">
Pipeline Scaffold
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../07_worker_and_progress/" class="md-nav__link">
<span class="md-ellipsis">
Worker & Progress
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../08_human_in_loop/" class="md-nav__link">
<span class="md-ellipsis">
Human-in-the-Loop
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../09_infra_adaptors/" class="md-nav__link">
<span class="md-ellipsis">
Infra Adapters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Versioning & Changelog
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#summary" class="md-nav__link">
<span class="md-ellipsis">
Summary
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-version-contract" class="md-nav__link">
<span class="md-ellipsis">
The version contract
</span>
</a>
<nav class="md-nav" aria-label="The version contract">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#pre-10-0yz" class="md-nav__link">
<span class="md-ellipsis">
Pre-1.0 (0.y.z)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#the-changelog" class="md-nav__link">
<span class="md-ellipsis">
The changelog
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#release-checklist" class="md-nav__link">
<span class="md-ellipsis">
Release checklist
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#why-the-guard-matters" class="md-nav__link">
<span class="md-ellipsis">
Why the guard matters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#related" class="md-nav__link">
<span class="md-ellipsis">
Related
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link">
<span class="md-ellipsis">
Genericity Matrix
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../14_auth_integration/" class="md-nav__link">
<span class="md-ellipsis">
Auth Integration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../13_library_registry/" class="md-nav__link">
<span class="md-ellipsis">
Library Registry
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#summary" class="md-nav__link">
<span class="md-ellipsis">
Summary
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#the-version-contract" class="md-nav__link">
<span class="md-ellipsis">
The version contract
</span>
</a>
<nav class="md-nav" aria-label="The version contract">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#pre-10-0yz" class="md-nav__link">
<span class="md-ellipsis">
Pre-1.0 (0.y.z)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#the-changelog" class="md-nav__link">
<span class="md-ellipsis">
The changelog
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#release-checklist" class="md-nav__link">
<span class="md-ellipsis">
Release checklist
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#why-the-guard-matters" class="md-nav__link">
<span class="md-ellipsis">
Why the guard matters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#related" class="md-nav__link">
<span class="md-ellipsis">
Related
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="versioning-changelog">Versioning &amp; Changelog</h1>
<h2 id="summary">Summary</h2>
<p>Every Aetos artifact — library, service, or site — is versioned with
<a href="https://semver.org/spec/v2.0.0.html">Semantic Versioning</a> and documents its
releases in a <a href="https://keepachangelog.com/en/1.1.0/">Keep a Changelog</a> file.
The <strong>version file is the source of truth</strong>, the <strong>git tag must equal it</strong>, and
a Drone guard enforces that equality before anything is published. Releases are
cut manually; a tag is what triggers the pipeline.</p>
<p>This page pairs with <a href="../10_drone_pipelines/">10 – Drone Pipelines</a>: the version
and tag contract is exactly what those two CI shapes consume.</p>
<hr />
<h2 id="the-version-contract">The version contract</h2>
<table>
<thead>
<tr>
<th>Artifact</th>
<th>Source of truth</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td>Library (PyPI package)</td>
<td><code>version</code> in <code>pyproject.toml</code></td>
<td><code>check-version</code> also reads it to skip duplicates</td>
</tr>
<tr>
<td>Service / site (Docker)</td>
<td><code>VERSION</code> file at the repo root</td>
<td>one line, <code>x.y.z</code></td>
</tr>
</tbody>
</table>
<p>Rules:</p>
<ol>
<li><strong>One version per repository.</strong> No per-module versions.</li>
<li><strong>Tag = version.</strong> The git tag is bare SemVer (<code>0.0.6</code>), no <code>v</code> 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.</li>
<li><strong>A release is a tag.</strong> Bump the version file, promote the changelog, commit,
tag, push. Everything else is automated by Drone.</li>
<li><strong>Never reuse a tag.</strong> If a release is wrong, cut a new patch version.</li>
</ol>
<h3 id="pre-10-0yz">Pre-1.0 (0.y.z)</h3>
<p>While a package is <code>0.y.z</code>, <strong><code>0.y</code> is treated as the major line</strong>:</p>
<ul>
<li>breaking change → <code>0.(y+1).0</code></li>
<li>new feature → <code>0.y.(z+1)</code></li>
<li>bug fix → <code>0.y.(z+1)</code></li>
</ul>
<p>Once a package reaches <code>1.0.0</code>, normal SemVer applies. Do not ship <code>1.0.0</code>
until the public API is considered stable.</p>
<hr />
<h2 id="the-changelog">The changelog</h2>
<p><code>CHANGELOG.md</code> at the repo root, in Keep a Changelog form. It always has exactly
one open <code>[Unreleased]</code> section with the change categories that apply:</p>
<div class="language-markdown highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span>
<span class="normal"><a href="#__codelineno-0-2">2</a></span>
<span class="normal"><a href="#__codelineno-0-3">3</a></span>
<span class="normal"><a href="#__codelineno-0-4">4</a></span>
<span class="normal"><a href="#__codelineno-0-5">5</a></span>
<span class="normal"><a href="#__codelineno-0-6">6</a></span>
<span class="normal"><a href="#__codelineno-0-7">7</a></span>
<span class="normal"><a href="#__codelineno-0-8">8</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a><span class="gu">## [Unreleased]</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a>
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3"></a><span class="gu">### Added</span>
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4"></a><span class="gu">### Changed</span>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5"></a><span class="gu">### Deprecated</span>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6"></a><span class="gu">### Removed</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7"></a><span class="gu">### Fixed</span>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8"></a><span class="gu">### Security</span>
</span></code></pre></div></td></tr></table></div>
<p>On release you <strong>promote</strong> it — never delete history:</p>
<div class="language-markdown highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-1-1">1</a></span>
<span class="normal"><a href="#__codelineno-1-2">2</a></span>
<span class="normal"><a href="#__codelineno-1-3">3</a></span>
<span class="normal"><a href="#__codelineno-1-4">4</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1"></a><span class="gu">## [0.0.6] - 2026-03-07</span>
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2"></a>
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3"></a><span class="gu">### Added</span>
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4"></a><span class="k">-</span><span class="w"> </span>...
</span></code></pre></div></td></tr></table></div>
<p>and add a link reference at the bottom:</p>
<div class="language-markdown highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-2-1">1</a></span>
<span class="normal"><a href="#__codelineno-2-2">2</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1"></a>[<span class="nl">Unreleased</span>]: <span class="na">https://git.aetoskia.com/aetos/&lt;repo&gt;/compare/0.0.6...HEAD</span>
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2"></a>[<span class="nl">0.0.6</span>]: <span class="na">https://git.aetoskia.com/aetos/&lt;repo&gt;/compare/0.0.5...0.0.6</span>
</span></code></pre></div></td></tr></table></div>
<p>Conventions:</p>
<ul>
<li>Write entries for humans: one line each, imperative, referencing the user
impact, not the commit hash.</li>
<li>Categories: <strong>Added</strong>, <strong>Changed</strong>, <strong>Deprecated</strong>, <strong>Removed</strong>, <strong>Fixed</strong>,
<strong>Security</strong>. Omit empty categories.</li>
<li>Security fixes get their own entry even if the change is otherwise a bug fix.</li>
<li>The <code>[Unreleased]</code> heading is never renamed; copy its content into the new
version heading and clear it.</li>
</ul>
<hr />
<h2 id="release-checklist">Release checklist</h2>
<ol>
<li>Confirm the quality gate is green on <code>main</code>.</li>
<li>Move every <code>[Unreleased]</code> entry under the new version heading with today's
date (<code>## [x.y.z] - YYYY-MM-DD</code>); restore an empty <code>[Unreleased]</code> on top.</li>
<li>Add the two compare-link references at the bottom of the changelog.</li>
<li>Set the version file: <code>pyproject.toml</code> (<code>version = "x.y.z"</code>) or <code>VERSION</code>.</li>
<li>Commit: <code>chore(release): x.y.z</code>.</li>
<li>Tag: <code>git tag x.y.z</code> and push the tag (<code>git push origin x.y.z</code>).</li>
<li>Watch Drone: Type A publishes the wheel/sdist, Type B builds and deploys the
image. Both first assert <code>tag == version</code>.</li>
<li>Do not reuse the tag if the run fails — fix and cut <code>x.y.(z+1)</code>.</li>
</ol>
<hr />
<h2 id="why-the-guard-matters">Why the guard matters</h2>
<p>The version file and the tag are two facts that must agree; nothing in git
enforces that by itself. A mismatch is not a theoretical risk — a package can be
tagged <code>0.0.2</code> while its <code>pyproject.toml</code> still says <code>0.0.1</code>, and the publish
step (which compares the <strong>file</strong> against the index) then skips the build
entirely, so <code>0.0.2</code> never reaches the index while looking like a release. The
Drone guard turns that silent no-op into a hard failure.</p>
<hr />
<h2 id="related">Related</h2>
<ul>
<li><a href="../10_drone_pipelines/">10 – Drone Pipelines</a> · <a href="../01_build_recipe/">01 – Build Recipe</a> · <a href="../13_library_registry/">13 – Library Registry</a></li>
</ul>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "..", "features": ["navigation.sections", "navigation.expand", "navigation.top", "navigation.instant", "navigation.tracking", "navigation.indexes", "content.code.copy", "content.code.annotate", "content.tabs.link", "content.action.edit", "search.highlight", "search.share", "search.suggest"], "search": "../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../assets/javascripts/bundle.f55a23d4.min.js"></script>
</body>
</html>

View File

@@ -11,7 +11,7 @@
<link rel="prev" href="../09_infra_adaptors/"> <link rel="prev" href="../11_versioning_and_changelog/">
<link rel="next" href="../14_auth_integration/"> <link rel="next" href="../14_auth_integration/">
@@ -442,6 +442,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>

View File

@@ -442,6 +442,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -444,6 +444,50 @@
<li class="md-nav__item">
<a href="../10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="../12_genericity_matrix/" class="md-nav__link"> <a href="../12_genericity_matrix/" class="md-nav__link">

View File

@@ -435,6 +435,50 @@
<li class="md-nav__item">
<a href="/10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="/11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="/12_genericity_matrix/" class="md-nav__link"> <a href="/12_genericity_matrix/" class="md-nav__link">

View File

@@ -452,6 +452,50 @@
<li class="md-nav__item">
<a href="10_drone_pipelines/" class="md-nav__link">
<span class="md-ellipsis">
Drone Pipelines
</span>
</a>
</li>
<li class="md-nav__item">
<a href="11_versioning_and_changelog/" class="md-nav__link">
<span class="md-ellipsis">
Versioning & Changelog
</span>
</a>
</li>
<li class="md-nav__item"> <li class="md-nav__item">
<a href="12_genericity_matrix/" class="md-nav__link"> <a href="12_genericity_matrix/" class="md-nav__link">
@@ -561,6 +605,9 @@ patterns, and the internal library catalog that agents consult while coding.</p>
<li><strong>Worker &amp; Progress</strong> — queued work, progress reporting, and visibility.</li> <li><strong>Worker &amp; Progress</strong> — queued work, progress reporting, and visibility.</li>
<li><strong>Human-in-the-Loop</strong> — guardrails and approvals inside automations.</li> <li><strong>Human-in-the-Loop</strong> — guardrails and approvals inside automations.</li>
<li><strong>Infra Adapters</strong> — how infrastructure connects without leaking into domain.</li> <li><strong>Infra Adapters</strong> — how infrastructure connects without leaking into domain.</li>
<li><strong>Drone Pipelines</strong> — the two CI shapes: a PyPI package or a Docker deployment.</li>
<li><strong>Versioning &amp; Changelog</strong> — SemVer, the tag↔version contract, and the release
changelog.</li>
<li><strong>Genericity Matrix</strong> — what is library-backed, template-provided, or authored.</li> <li><strong>Genericity Matrix</strong> — what is library-backed, template-provided, or authored.</li>
<li><strong>Auth Integration</strong> — consuming the shared auth-server service (spec-driven, <li><strong>Auth Integration</strong> — consuming the shared auth-server service (spec-driven,
no auth code).</li> no auth code).</li>

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@@ -291,6 +291,25 @@
<li class="md-tabs__item">
<a href="../04_development/02_releasing/" class="md-tabs__link">
Releasing & Versioning
</a>
</li>
</ul> </ul>
</div> </div>
</nav> </nav>
@@ -523,6 +542,28 @@
<li class="md-nav__item">
<a href="../04_development/02_releasing/" class="md-nav__link">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</a>
</li>
</ul> </ul>
</nav> </nav>
</div> </div>

View File

@@ -291,6 +291,25 @@
<li class="md-tabs__item">
<a href="../04_development/02_releasing/" class="md-tabs__link">
Releasing & Versioning
</a>
</li>
</ul> </ul>
</div> </div>
</nav> </nav>
@@ -598,6 +617,28 @@
<li class="md-nav__item">
<a href="../04_development/02_releasing/" class="md-nav__link">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</a>
</li>
</ul> </ul>
</nav> </nav>
</div> </div>

View File

@@ -291,6 +291,25 @@
<li class="md-tabs__item">
<a href="../04_development/02_releasing/" class="md-tabs__link">
Releasing & Versioning
</a>
</li>
</ul> </ul>
</div> </div>
</nav> </nav>
@@ -514,6 +533,28 @@
<li class="md-nav__item">
<a href="../04_development/02_releasing/" class="md-nav__link">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</a>
</li>
</ul> </ul>
</nav> </nav>
</div> </div>

View File

@@ -14,6 +14,8 @@
<link rel="prev" href="../../03_start_an_app/"> <link rel="prev" href="../../03_start_an_app/">
<link rel="next" href="../02_releasing/">
<link rel="icon" href="../../assets/images/favicon.png"> <link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.23"> <meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.23">
@@ -289,6 +291,25 @@
<li class="md-tabs__item">
<a href="../02_releasing/" class="md-tabs__link">
Releasing & Versioning
</a>
</li>
</ul> </ul>
</div> </div>
</nav> </nav>
@@ -539,6 +560,28 @@
<li class="md-nav__item">
<a href="../02_releasing/" class="md-nav__link">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</a>
</li>
</ul> </ul>
</nav> </nav>
</div> </div>

View File

@@ -0,0 +1,785 @@
<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="The philosophy and prompts behind the standardized application blueprint.">
<link rel="prev" href="../01_testing/">
<link rel="icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.23">
<title>Releasing & Versioning - Aetos Standards — Wiki</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.84d31ad4.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#releasing-versioning" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
</div>
<header class="md-header" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Aetos Standards — Wiki" class="md-header__button md-logo" aria-label="Aetos Standards — Wiki" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Aetos Standards — Wiki
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="cyan" aria-hidden="true" type="radio" name="__palette" id="__palette_0">
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item">
<a href="../../01_overview/" class="md-tabs__link">
Overview
</a>
</li>
<li class="md-tabs__item">
<a href="../../02_components/" class="md-tabs__link">
App Components
</a>
</li>
<li class="md-tabs__item">
<a href="../../03_start_an_app/" class="md-tabs__link">
Start an App
</a>
</li>
<li class="md-tabs__item">
<a href="../01_testing/" class="md-tabs__link">
Testing & Quality
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="./" class="md-tabs__link">
Releasing & Versioning
</a>
</li>
</ul>
</div>
</nav>
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted md-nav--integrated" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Aetos Standards — Wiki" class="md-nav__button md-logo" aria-label="Aetos Standards — Wiki" data-md-component="logo">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 8a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3m0 3.54C9.64 9.35 6.5 8 3 8v11c3.5 0 6.64 1.35 9 3.54 2.36-2.19 5.5-3.54 9-3.54V8c-3.5 0-6.64 1.35-9 3.54"/></svg>
</a>
Aetos Standards — Wiki
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../01_overview/" class="md-nav__link">
<span class="md-ellipsis">
Overview
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../02_components/" class="md-nav__link">
<span class="md-ellipsis">
App Components
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../03_start_an_app/" class="md-nav__link">
<span class="md-ellipsis">
Start an App
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../01_testing/" class="md-nav__link">
<span class="md-ellipsis">
Testing & Quality
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Releasing & Versioning
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</a>
<nav class="md-nav md-nav--secondary" aria-label="Table of contents">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
Table of contents
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#before-you-start" class="md-nav__link">
<span class="md-ellipsis">
🧾 Before you start
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#pick-the-next-version" class="md-nav__link">
<span class="md-ellipsis">
🚦 Pick the next version
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#promote-the-changelog" class="md-nav__link">
<span class="md-ellipsis">
✍️ Promote the changelog
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#bump-the-version-file" class="md-nav__link">
<span class="md-ellipsis">
🔢 Bump the version file
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#what-drone-does" class="md-nav__link">
<span class="md-ellipsis">
🤖 What Drone does
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#backfill-recovery" class="md-nav__link">
<span class="md-ellipsis">
🛟 Backfill / recovery
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#if-a-release-is-wrong" class="md-nav__link">
<span class="md-ellipsis">
🔁 If a release is wrong
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#related" class="md-nav__link">
<span class="md-ellipsis">
Related
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<h1 id="releasing-versioning">Releasing &amp; Versioning</h1>
<p>How to cut a release of any Aetos repository. The rule lives in the reference
page <a href="../lib/11_versioning_and_changelog/">Versioning &amp; Changelog</a>; this is the
runbook you follow.</p>
<p>Every repository is one of two Drone shapes — a <strong>PyPI package</strong> or a <strong>Docker
deployment</strong> (<a href="../lib/10_drone_pipelines/">Drone Pipelines</a>). Both are
released the same way: bump the version file, promote the changelog, tag.</p>
<hr />
<h2 id="before-you-start">🧾 Before you start</h2>
<ul>
<li><code>main</code> is green (the Drone quality gate passed on the last run).</li>
<li>You know whether this is a <strong>breaking</strong>, <strong>feature</strong>, or <strong>fix</strong> release.</li>
<li>The version file exists:</li>
<li>package → <code>version</code> in <code>pyproject.toml</code></li>
<li>service / site → <code>VERSION</code> at the repo root</li>
</ul>
<hr />
<h2 id="pick-the-next-version">🚦 Pick the next version</h2>
<p>The version file and the tag must be identical. For <code>0.y.z</code>, <code>0.y</code> is the major
line (see the reference page); once at <code>1.0.0</code>, normal SemVer applies.</p>
<table>
<thead>
<tr>
<th>Change</th>
<th><code>0.y.z</code> →</th>
<th><code>1.0.0+</code> →</th>
</tr>
</thead>
<tbody>
<tr>
<td>Breaking</td>
<td><code>0.(y+1).0</code></td>
<td><code>(x+1).0.0</code></td>
</tr>
<tr>
<td>Feature</td>
<td><code>0.y.(z+1)</code></td>
<td><code>x.(y+1).0</code></td>
</tr>
<tr>
<td>Fix</td>
<td><code>0.y.(z+1)</code></td>
<td><code>x.y.(z+1)</code></td>
</tr>
</tbody>
</table>
<hr />
<h2 id="promote-the-changelog">✍️ Promote the changelog</h2>
<p>In <code>CHANGELOG.md</code>:</p>
<ol>
<li>Rename the content under <code>[Unreleased]</code> into a new
<code>## [x.y.z] - YYYY-MM-DD</code> heading (keep the sections that apply).</li>
<li>Leave a fresh, empty <code>## [Unreleased]</code> on top.</li>
<li>Add the compare links at the bottom:</li>
</ol>
<div class="language-markdown highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-0-1">1</a></span>
<span class="normal"><a href="#__codelineno-0-2">2</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1"></a>[<span class="nl">Unreleased</span>]: <span class="na">https://git.aetoskia.com/aetos/&lt;repo&gt;/compare/x.y.z...HEAD</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2"></a>[<span class="nl">x.y.z</span>]: <span class="na">https://git.aetoskia.com/aetos/&lt;repo&gt;/compare/x.y.(z-1)...x.y.z</span>
</span></code></pre></div></td></tr></table></div>
<hr />
<h2 id="bump-the-version-file">🔢 Bump the version file</h2>
<ul>
<li><strong>Package:</strong> edit <code>version = "x.y.z"</code> in <code>pyproject.toml</code>.</li>
<li><strong>Service / site:</strong> edit the <code>VERSION</code> file.</li>
</ul>
<p>Then commit and tag:</p>
<div class="language-bash highlight"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span></span><span class="normal"><a href="#__codelineno-1-1">1</a></span>
<span class="normal"><a href="#__codelineno-1-2">2</a></span>
<span class="normal"><a href="#__codelineno-1-3">3</a></span>
<span class="normal"><a href="#__codelineno-1-4">4</a></span>
<span class="normal"><a href="#__codelineno-1-5">5</a></span></pre></div></td><td class="code"><div><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1"></a>git<span class="w"> </span>add<span class="w"> </span>CHANGELOG.md<span class="w"> </span>pyproject.toml<span class="w"> </span><span class="c1"># or VERSION</span>
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2"></a>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">&quot;chore(release): x.y.z&quot;</span>
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3"></a>git<span class="w"> </span>tag<span class="w"> </span>x.y.z
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4"></a>git<span class="w"> </span>push<span class="w"> </span>origin<span class="w"> </span>HEAD
</span><span id="__span-1-5"><a id="__codelineno-1-5" name="__codelineno-1-5"></a>git<span class="w"> </span>push<span class="w"> </span>origin<span class="w"> </span>x.y.z
</span></code></pre></div></td></tr></table></div>
<hr />
<h2 id="what-drone-does">🤖 What Drone does</h2>
<ul>
<li><strong>Type A (package):</strong> asserts <code>tag == pyproject version</code>, then skips if that
version already exists on the index, runs the quality gate, builds, and
uploads the wheel + sdist.</li>
<li><strong>Type B (service):</strong> asserts <code>tag == VERSION</code>, resolves the tag, skips if the
image already exists, runs the quality gate, builds, pushes, and restarts the
container.</li>
<li><strong>Type B (site):</strong> triggered on push, ships <code>:latest</code> and has no tag guard.</li>
</ul>
<p>If the guard fails, nothing is published — fix the version file, amend the
commit, and move the tag <strong>only</strong> if it was never pushed.</p>
<hr />
<h2 id="backfill-recovery">🛟 Backfill / recovery</h2>
<p>If an older tag never published (a past version-file mismatch, an index
outage):</p>
<ul>
<li><strong>Package:</strong> run the <code>backfill-pypi-from-tags</code> pipeline (custom event). It
checks out every tag, verifies <code>tag == pyproject version</code> at that commit,
and uploads the ones missing from the index. Already-fixed history is never
rewritten.</li>
<li><strong>Service:</strong> rebuild the image for the missing tag with a fresh commit and a
new patch version; do not move a published tag.</li>
</ul>
<hr />
<h2 id="if-a-release-is-wrong">🔁 If a release is wrong</h2>
<ul>
<li>Never reuse or force-move a pushed tag.</li>
<li>Fix forward: bump to the next patch, promote the changelog, tag again.</li>
</ul>
<hr />
<h2 id="related">Related</h2>
<ul>
<li><a href="../01_testing/">Testing &amp; Quality Gates</a> · <a href="../lib/11_versioning_and_changelog/">Versioning &amp; Changelog</a> · <a href="../lib/10_drone_pipelines/">Drone Pipelines</a></li>
</ul>
</article>
</div>
<script>var tabs=__md_get("__tabs");if(Array.isArray(tabs))e:for(var set of document.querySelectorAll(".tabbed-set")){var labels=set.querySelector(".tabbed-labels");for(var tab of tabs)for(var label of labels.getElementsByTagName("label"))if(label.innerText.trim()===tab){var input=document.getElementById(label.htmlFor);input.checked=!0;continue e}}</script>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
Made with
<a href="https://squidfunk.github.io/mkdocs-material/" target="_blank" rel="noopener">
Material for MkDocs
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"base": "../..", "features": ["navigation.sections", "navigation.expand", "navigation.top", "navigation.instant", "navigation.tracking", "navigation.indexes", "navigation.tabs", "toc.integrate", "header.autohide", "content.code.copy", "content.code.annotate", "content.tabs.link", "content.action.edit", "search.highlight", "search.share", "search.suggest"], "search": "../../assets/javascripts/workers/search.973d3a69.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.f55a23d4.min.js"></script>
<script src="https://unpkg.com/mermaid@10.9.1/dist/mermaid.min.js"></script>
</body>
</html>

View File

@@ -280,6 +280,25 @@
<li class="md-tabs__item">
<a href="/04_development/02_releasing/" class="md-tabs__link">
Releasing & Versioning
</a>
</li>
</ul> </ul>
</div> </div>
</nav> </nav>
@@ -425,6 +444,28 @@
<li class="md-nav__item">
<a href="/04_development/02_releasing/" class="md-nav__link">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</a>
</li>
</ul> </ul>
</nav> </nav>
</div> </div>

View File

@@ -289,6 +289,25 @@
<li class="md-tabs__item">
<a href="04_development/02_releasing/" class="md-tabs__link">
Releasing & Versioning
</a>
</li>
</ul> </ul>
</div> </div>
</nav> </nav>
@@ -503,6 +522,28 @@
<li class="md-nav__item">
<a href="04_development/02_releasing/" class="md-nav__link">
<span class="md-ellipsis">
Releasing & Versioning
</span>
</a>
</li>
</ul> </ul>
</nav> </nav>
</div> </div>

File diff suppressed because one or more lines are too long

Binary file not shown.