Skip to content

Latest commit

 

History

History
257 lines (200 loc) · 11.4 KB

File metadata and controls

257 lines (200 loc) · 11.4 KB

Contributing to the Cozystack Documentation

This repository builds cozystack.io with Hugo and the Docsy theme. It hosts the official Cozystack documentation across all supported versions. This guide explains where to put your change, how the versioned layout works, and how a release moves docs around.

If you just want to run the site locally:

npm install
make serve    # http://localhost:1313/docs

See README.md for tool setup.

The versioning model at a glance

Docs are versioned per Cozystack minor release. Each minor version has its own self-contained directory under content/en/docs/, and each is served under its own URL prefix (/docs/v1.2/, /docs/v1.1/, …). This lets users on an older release keep reading accurate docs for that release, while newer users see current material.

content/en/docs/
├── _index.md          ← version-agnostic landing page (/docs/)
├── next/              ← trunk for upcoming/unreleased docs (/docs/next/)
├── v1.2/              ← current stable
├── v1.1/
├── v1.0/
└── v0/                ← legacy (all 0.x)

A few rules follow from this layout:

  • Each version directory is independent. Editing v1.2/applications/tenant.md does not affect v1.1/.
  • There is no automatic backport between versions. If a fix needs to apply to multiple versions, it must be copied to each.
  • Autogenerated pages (see below) must not be edited in place — edit the upstream source and re-sync.

Why next/ (the trunk)?

Docs describing a feature that has not yet shipped cannot sit in any released version directory:

  • They must not leak into /docs/v1.2/ — that's the current production docs, and v1.2 does not have the feature.
  • They must not pre-register as /docs/v1.3/ — we don't know yet whether the next release will actually be v1.3, or when it will ship.

content/en/docs/next/ solves this: it's a permanent, version-agnostic trunk where upcoming-release docs accumulate. When a release is cut, the contents of next/ are promoted to the concrete version directory (v1.3/, v2.0/, …) and the internal links are rewritten.

Properties of next/:

  • Always present in the repo; never deleted.
  • Hidden in production: excluded from GitHub Pages builds by config/production/hugo.yaml, and hidden from the version-switcher dropdown via hidden: true in hugo.yaml.
  • Visible in local dev and Netlify deploy previews, so reviewers can see upcoming-release docs on a PR preview before they ship.
  • Uses /docs/next/... paths internally; these are rewritten to /docs/vX.Y/... at release time by hack/release_next.sh.
  • The landing page (next/_index.md) carries a draft banner warning the reader that the content is unreleased.

Where should my change go?

Use this decision table before you start editing:

Your change is… Edit here
A doc for a feature that ships in a future release content/en/docs/next/
A bug fix or addition for the current release content/en/docs/<latest_version_id>/ (v1.2)
A fix that also applies to an older supported version Copy the change into each relevant vX.Y/
Cross-version content (the landing page, overview) content/en/docs/_index.md
A blog post content/en/blog/
A layout, shortcode, or site-wide asset change layouts/, assets/, static/

Treat v0/ as legacy: it receives fixes only for correctness of historic references. Do not add new content there.

Autogenerated content — do not edit in place

Some pages under each version are synced from the upstream cozystack/cozystack repo. These include most of applications/, virtualization/, networking/, kubernetes/, and operations/services/. They carry a footer:

Autogenerated content. Don't edit this file directly; edit sources instead.

If you need to change one of these pages:

  • Change the prose (body) → edit the upstream README in cozystack/cozystack under packages/apps/<app>/README.md (or the matching packages/extra/<svc>/), then re-run the corresponding sync target: make update-apps, make update-vms, make update-networking, make update-k8s, or make update-services. By default, update-* targets the trunk (next/). Pass RELEASE_TAG=vX.Y.Z to route to a released version for patch updates.
  • Change only front matter (title, weight, aliases) for a specific version → edit the stub under content/en/docs/<version>/<section>/_include/<app>.md. The update-* targets merge these stubs with the upstream README, so front matter edits survive the next sync. make template-* scaffolds new stubs.

Everything else on the site is hand-authored and edited directly.

The release flow

Patch release (v1.2.5)

v1.2 already exists and is registered as a released version. The release workflow (upstream cozystack/cozystack tags.yaml) calls:

make update-all RELEASE_TAG=v1.2.5

RELEASE_TAG routing detects that content/en/docs/v1.2/ exists and is non-hidden, so DOC_VERSION resolves to v1.2 and the update happens in place in that directory. next/ is not touched.

New minor or major release (v1.3.0)

The trunk gets promoted to a new version directory. The upstream workflow calls:

make release-next RELEASE_TAG=v1.3.0
make update-all  RELEASE_TAG=v1.3.0
  • make release-next RELEASE_TAG=v1.3.0 invokes hack/release_next.sh, which:

    1. Validates that next/ is non-empty and v1.3/ doesn't already exist.
    2. Copies content/en/docs/next/content/en/docs/v1.3/ (cp -a).
    3. Rewrites /docs/next//docs/v1.3/ across every .md in the new directory.
    4. Updates v1.3/_index.md: sets the title to Cozystack v1.3 Documentation and strips the draft banner.
    5. Calls hack/register_version.sh --release v1.3, which registers v1.3 in hugo.yaml, sets latest_version_id: "v1.3", and normalizes _index.md weights across all non-hidden versions (new latest → 10, then 20, 30, 40, …) so sidebar ordering stays deterministic.
    6. Leaves next/ untouched — it stays in place for the next release cycle.
  • make update-all RELEASE_TAG=v1.3.0 then pulls fresh upstream READMEs pinned to the exact tag into the new v1.3/ directory.

Pre-release audit

hack/release_next.sh rewrites /docs/next/ URL paths, but version references in prose are promoted verbatim. Before cutting a new minor, do a sweep over content/en/docs/next/ for any Cozystack v<prev>, @v<prev>.0, pinned-image versions, or "since Cozystack v" phrasing that would be factually wrong once the trunk becomes the new version. Search patterns that typically catch the stragglers:

grep -rn 'Cozystack v[0-9]' content/en/docs/next/
grep -rn '@v[0-9]'           content/en/docs/next/
grep -rn 'talos:v[0-9]'      content/en/docs/next/

Resetting the trunk after release

release-next copies next/vX.Y/; it does not move. The trunk therefore still holds the now-released content and must be reset before any further work targeting the next cycle:

make init-next

init-next wipes content/en/docs/next/ and re-initializes it from the new latest version. Run this as the final step of every release — skipping it leaves the trunk in a stale state where edits look like they're for an upcoming release but are actually landing on top of already-released content.

Routing table

Scenario Target directory
make update-all (no tag) next/
make update-all RELEASE_TAG=v1.1.8 (v1.1 exists) v1.1/
make update-all RELEASE_TAG=v1.3.0-rc1 (v1.3 doesn't yet) next/
make update-all RELEASE_TAG=v1.3.0 (v1.3 doesn't yet) next/
make release-next RELEASE_TAG=v1.3.0 copies next/v1.3/
make update-all RELEASE_TAG=v1.3.1 (v1.3 now exists) v1.3/

Use make show-target [RELEASE_TAG=…] to print the resolved DOC_VERSION and BRANCH without running anything.

Command reference

# Local development
npm install
make serve                             # dev server at http://localhost:1313/docs

# Production-shape build (reproduces what GitHub Pages serves)
./hack/download_openapi.sh && HUGO_ENV=production hugo --gc --minify

# Pull upstream content (targets next/ by default; pass RELEASE_TAG to route)
make update-all                        # trunk from upstream main
make update-all RELEASE_TAG=v1.2.5     # routes to v1.2/ (patch release)
make update-apps                       # application docs only
make update-vms | update-networking | update-k8s | update-services
make update-oss-health                 # OSS health metrics (requires Python 3.12+)

# Scaffolding (stubs for new apps/services)
make template-apps                     # also template-vms / template-networking / …

# Version lifecycle
make release-next RELEASE_TAG=v1.3.0   # promote next/ → v1.3/
make init-next                         # (re)create next/ from latest released version
make init-version DOC_VERSION=v1.3     # low-level init of any version dir

# Debugging
make show-target RELEASE_TAG=v1.3.0    # prints resolved DOC_VERSION / BRANCH

Required tools: Hugo extended 0.160.1, Go 1.23+, Node 20+, yq v4+ (for the version lifecycle targets and Makefile routing).

Where the architecture is implemented

If you need to understand or change the versioning machinery itself:

  • hugo.yaml — site-wide config; params.versions[] is the list of registered versions (including next with hidden: true), and params.latest_version_id is the current stable.
  • config/production/hugo.yaml — production-only overrides; excludes docs/next/** from GitHub Pages builds. Netlify deploy previews set HUGO_ENV=preview so they skip this override.
  • MakefileRELEASE_TAG routing, lifecycle targets.
  • hack/release_next.sh — trunk → version promotion.
  • hack/register_version.sh — manages hugo.yaml version entries and normalizes _index.md weights.
  • hack/init_version.sh — initializes any version directory, with special handling for next/ (title, draft banner).
  • hack/update_apps.sh, hack/fill_templates.sh — content sync from cozystack/cozystack.
  • hack/download_openapi.sh — fetches openapi.json per version at build time (v1.1+; v0 and v1.0 ship their api.json in-tree).
  • layouts/docs/docs-landing.html — the /docs/ landing template; builds the version table from params.versions[], filtering out hidden entries.
  • layouts/partials/version-switcher.html — top-navbar version dropdown; filters out hidden entries.
  • layouts/404.html — client-side fallback redirect for /docs/v1/… short paths.