# Documentation versioning How the docs of each product (gitaiflow, astwire, …) are versioned, and how to release a new version. For the version of the docs *site* itself, see [RELEASING.md](./RELEASING.md). **Audience:** anyone who edits a product's docs or cuts a release. --- ## 1. The model One docs tree, always the latest. Older versions are either **filtered views** of that tree (from each doc's header) or **built from a git ref** (a tag or a branch). Nothing is copied per version. | Kind | Built from | Use it when | | --- | --- | --- | | **Filtered view** (default) | The latest docs, narrowed by each doc's `since` / `removed` | A release only adds or removes pages. Same text in every version. | | **Frozen snapshot** | A git **tag** of this repo (`/v`) | An end-of-life version whose text must stay exactly as it was. | | **Maintenance branch** | A git **branch** (e.g. `release/1.4`) | A supported older version that still gets doc fixes. | Start with filtered views. Move a version to a tag or branch only when its wording has to differ from the latest. --- ## 2. Declare the versions (`projects//project.json`) ```json "versions": [ { "id": "1.1.3", "status": "current" }, { "id": "1.1.1", "status": "supported" }, { "id": "1.0.0", "status": "eol", "ref": "gitaiflow/v1.0.0" } ] ``` | Field | Meaning | | --- | --- | | `id` | A release: an exact version (`1.1.3`) or a release line (`1.1`). Use one style per project. Lifecycle fields are compared at the precision of the id: with line ids, `since: 1.1.3` counts as part of `1.1`. | | `status` | `current` (what the normal URLs show; the first entry if none says so), `supported`, or `eol`. | | `label` | Optional display name. Default: the id, plus "(latest)" on the current one. | | `ref` | Optional git tag **or** branch to build this version from. Default: the tag `/v` if it exists. `tag` is the older spelling of the same thing. | List versions newest first. One entry shows the version as a plain label with no dropdown; no `versions` list means no version UI at all. --- ## 3. Mark every doc with the version it appeared in ```yaml --- since: 1.1.3 # added in this version (required in a versioned project) changed: 1.1.4 # last meaningful change (optional) deprecated: 1.2.0 # optional removed: 1.3.0 # optional --- ``` - A doc belongs to version `V` when `since <= V` and `V < removed`. - Choosing an older version in the dropdown hides docs that didn't exist yet (sidebar, search, previous/next). A page outside the chosen version says so. - "Added in X" is shown only on docs newer than the project's oldest listed version, so it marks what's new rather than every page. - A doc removed in the current version stays routable (old links keep working) but disappears from navigation, search and the sitemap; it's only visible in older versions. - **Don't delete a doc that a supported version still documents. Set `removed: ` instead.** Deleting it makes it vanish from the older version too. - Release notes (`releases/vX.Y.Z.md`) use the version they describe as `since`. `npm run new:doc` fills `since` with the project's current version. `npm run docs:check` reports a missing `since`, or one newer than the current version. --- ## 4. Release a new version of a product Do this **before** editing docs for the new version, on a clean `main`: ```bash npm run docs:release -- gitaiflow 1.2.0 --notes # dry run: shows the plan npm run docs:release -- gitaiflow 1.2.0 --notes --write git push origin gitaiflow/v1.1.3 # push the tag it made ``` `docs:release` does the mechanical part: 1. **Freezes the version being replaced**: tags the docs as they are now (`gitaiflow/v1.1.3`). Skipped when that version is built from a `ref`, or with `--no-tag`. 2. **Updates `project.json`**: `1.2.0` becomes `current`, `1.1.3` becomes `supported`. `--eol 1.1.1` marks an older version end-of-life. 3. **With `--notes`**, writes `releases/v1.2.0.md` from the release-notes template, with `since: 1.2.0`. It refuses when `projects/` has uncommitted changes (the tag would not match the docs), never moves an existing tag, and rejects a version that isn't newer or uses a different style (`1.2` vs `1.2.0`). Then: 1. Commit (`docs(gitaiflow): release 1.2.0`). 2. Edit the docs for 1.2.0. New docs: `npm run new:doc` (`since` defaults to 1.2.0). Docs that go away: `removed: 1.2.0`. 3. Merge to `main`. The site rebuilds. To tag the current version without releasing anything (for example to freeze 1.1.3 today): `npm run docs:release -- gitaiflow --freeze --write`. ### Which ref for which version The common industry approach (Read the Docs, Antora): | Version status | Build it from | | --- | --- | | `current` | `main` (the normal docs) | | `supported` | A filtered view while text is shared; a **maintenance branch** (`"ref": "release/1.1"`) once its wording diverges and still gets fixes | | `eol` | A **tag**: frozen, never changes | To start a maintenance branch: `git branch release/1.1 gitaiflow/v1.1.3 && git push origin release/1.1`, then add `"ref": "release/1.1"` to that entry. --- ## 5. Frozen versions in the build Each version with a usable ref is exported with `git archive` and built like normal content under `/projects//v//…`. - Links between pages of a version stay inside that version. - Pages of an older version are canonical to the same page in the latest docs, or `noindex` when there isn't one, and are left out of `sitemap.xml`. - A version with no ref is a filtered view, silently. A version whose entry names a `ref` that can't be found falls back to a filtered view and **warns**. - Broken links inside an old ref are warnings, never build failures. ### CI requirements Dates and older versions need git history, tags and branches: - GitLab: set `GIT_DEPTH: 0` (full clone). The build also tries `git fetch --unshallow --tags`, `git fetch --tags` and, for a branch ref, `git fetch origin ` on its own. - Skip those automatic fetches with `DOCS_NO_UNSHALLOW=1` and `DOCS_NO_FETCH_TAGS=1`. ### Warnings `npm run build` and `npm run check-content` print one grouped list of warnings, including explicit refs that fell back to filtered views. See [RELEASING.md](./RELEASING.md) section 6.