Docouture

Releasing a documentation

A release is cut by running .github/workflows/docouture-release.yml (scaffolded by docouture new), not by hand-editing anything under docs/. Two triggers actually do anything on a fresh site:

  • Manually — Actions tab → "docouture-release" → Run workflow. Works immediately.

  • Automatically — merge a pull request into the release branch (main on a trunk-based site — see Branching model for a git-flow one) carrying the docs/release label. That label isn’t created automatically — see Prerequisites — so until it exists, only the manual trigger works; a merge without it is a silent no-op, not an error.

A third trigger — a published GitHub Release — is scaffolded alongside these but stays dormant on a fresh site: it only fires once the repo separately labels PRs release-type/*/skip-release and publishes its own Releases, a convention this scaffolding doesn’t set up. It exists so that, if a repo’s own code releases and docs releases can land in the same merged PR, the docs release waits for the code release to actually publish instead of firing twice for one merge — adopting that convention later is then a label/workflow change elsewhere, not a rewrite of this file.

Under the hood: docouture version <value> patches docs/src/antora.yml on a one-off commit built on the release branch’s current tip, git tag docs/v<value> is created there, and the tag is pushed — the release branch itself is never advanced.

Before any of that: docs/.release-version (or the workflow_dispatch version input, in versioned mode) is validated against full SemVer 2.0.0 — a leading v, a bare 1.2, or any other malformed value fails the workflow immediately with a clear error, instead of tagging first and only failing later inside the version-bump step. docouture-release-preview.yml runs the same check earlier, as a PR comment, before the merge that would have triggered it. It runs only on pull requests opened from a branch of the repository itself: a fork’s pull request gets a read-only token that cannot post the comment, so the preview is skipped there.

Standalone mode

Every release retargets the same docs/stable tag — force-moved, not appended to. Nothing to set beforehand; the workflow’s default input is fine.

Versioned mode

The target version comes from docs/.release-version, not a form field, when triggered by a labelled PR merge:

  1. Edit docs/.release-version to the target version (e.g. 1.0.0)

  2. Open a PR with that change, labelled docs/release

  3. Merge it — the workflow tags docs/v1.0.0, then bumps the file forward to the next patch version so it’s always ready for whatever comes next

(Or skip the PR: run the workflow manually via workflow_dispatch and type the version directly — its form field is what a versioned-mode release actually requires there, unlike standalone’s, where the default is fine.)

Under git-flow: the sync pull request

The forward-bump is committed on the release branch only. On a git-flow site the workflow’s sync-prerelease job then opens a pull request from automated/sync-docs-release-<version>-to-<prerelease> into the prerelease branch, so docs/.release-version (and anything else the release branch gained) reaches it — merge that PR. The prerelease branch name comes from docs/package.json’s `docouture.prereleaseBranch; if it is missing the release fails before tagging, with a message pointing at docouture upgrade, which adds it.

  • The job is skipped on trunk-based sites, on a republish, when the prerelease branch already contains the release branch, and when that branch doesn’t exist.

  • A failure there turns the run red and comments on the merged docs/release PR, but the docs are still published — publish doesn’t wait on its result.

  • The GitHub App that docouture-release.yml already uses needs pull-requests: write (and workflows: write, since the release branch can carry workflow-file changes) in addition to contents: write. Existing git-flow sites run docouture upgrade once to get the new job and the package.json field.

docouture version vs. a real release

docouture version <value> is the narrower tool the workflow itself calls internally — it only rewrites docs/src/antora.yml’s `version:/prerelease: fields in place. Useful for local, throwaway testing of how a version renders; it does not cut a release on either mode, and never touches docs/.release-version:

$ docouture version 1.0.0
$ docouture version 1.1.0-rc.0 --prerelease

Every release tag is force-recreated

Republishing an already-released version (fixing a docs typo caught after the tag went out) is a deliberate, ordinary act — no separate flag needed. The one difference: the docs/.release-version forward-bump step is skipped on a republish, since that file’s current value was typically already the next planned target.