This is the multi-page printable view of this section. Click here to print.
Build
1 - CI/CD
Agent-support checks
The site has an AFDocs configuration and npm script to generate a scorecard locally:
- Config: docsy.dev/agent-docs.config.yml
- Script:
_check:afdocsin docsy.dev/package.json
To generate a fresh scorecard, run each of these commands in separate terminals:
npm run serve
npm run check:afdocs:dev
The latter command saves the generated scorecard to
docs/content/agent-support/afdocs-scorecard.txt under docsy.dev/content/en,
which will be included in Scorecard examples on the next build.
Note that the scorecard generation is not run as a part of the full CI/CD pipeline. It needs to be run manually.
Read more: AFDocs config file format.
Formatting and lint checks
Prettier formats Docsy and the website files, and Markdownlint lints the Markdown. To run the checks, or to apply automatic fixes:
npm run check
npm run fix
CI runs these checks and the test suites.
Hugo shortcodes
Prettier formats a paired shortcode’s body as Markdown. When the body isn’t
Markdown, such as a tabpane’s code, wrap the shortcode:
<!-- prettier-ignore-start -->
{{< tabpane >}}
...
{{< /tabpane >}}
<!-- prettier-ignore-end -->
Workaround for i18n files
The translation files in the i18n directory are formatted using Prettier. But
Prettier removes the blank line before the # Feedback section heading. This
seems to be a known issue, for example see:
- Bug: Inconsistent newline formatting in YAML when changing scopes #15528
- Bug: New Line before comments at end of YAML files are removed #15720
We’ve worked around this bug, and avoided using prettier-ignore directives, by
formatting the preceding entry in the YAML file to be a block scalar, like this:
community_guideline: >-
Contribution Guidelines
This ensures that the blank line is preserved. Hopefully Prettier will be fixed and we’ll be able to remove this hack.
2 - Git repo info and branch model
Monorepo
The main Docsy repository is effectively a monorepo containing the Docsy:
- Theme in the
themedirectory - Website in the
docsy.devdirectory. The website uses the Docsy theme, of course, with extra styling.
The main Docsy example site is Goldydocs, located in the Docsy example site repository.
Local build
Site builds resolve the theme through the checkout’s parent directory
(--themesDir ../.. with theme: docsy/theme), so the checkout directory must
be named docsy. From a checkout named differently (a git worktree, for
example), either run npm scripts through the wt helper
(npm run wt -- serve), or set HUGO_THEME=DIR_NAME/theme, where
DIR_NAME is the checkout’s directory name.
With the prerequisites installed, install and serve the website from the checkout root:
npm run install:safe
npm run serve
Branch model
This repository’s branch model is as follows:
main: development branch for the next theme release and next site content.release: release and maintenance branch for the latest theme release.deploy/prodanddoc-rooted: publishing branches used by Netlify. These branches determine what is published (see the table below); they are not feature development branches.
The Goldydocs repo has the same model, except for doc-rooted which is not
used.
Published sites
Netlify publishes the following site variants. A variant’s version identity
(version and related params) comes from its config directory under
docsy.dev/config/:
| Site variant | Publishing branch | Version params |
|---|---|---|
| Latest release | deploy/prod | production/ |
| Next (dev) | main | _default/ |
| Doc-rooted (experimental) | doc-rooted | doc-rooted/ |
PR deploy previews build like the Next variant.
Tags
- Release tags (
vX.Y.Zandtheme/vX.Y.Z) mark official theme releases. - They never move: the
release-tag-integrityruleset blocks their update and deletion, with no bypass. - Only the designated releaser creates them, per the
release-tagsruleset.
Workflow
Overview
Theme and site work is done on
main.When ready to release:
- Release from
main(the usual case). - Patch on
release(whenmaincarries work that isn’t ready to release).
- Release from
Publish site updates: fast-forward
deploy/prodfromrelease.Netlify deploys from
deploy/prodanddoc-rooted.
Release from main
After
git fetch upstream, ifreleasehas commits thatmaindoesn’t (git log upstream/main..upstream/releaselists them, after a patch onrelease), restore the fast-forward path before the release-preparation PR merges.Once the release tag,
RELEASE_TAG(for example,v0.18.2), is pushed, fast-forwardreleaseto it:git fetch upstream --tags git switch -C release upstream/release git merge --ff-only RELEASE_TAG git push upstream release
Patch on release
Fix on main first whenever the fix applies there; a fix that doesn’t apply
there lands only on release. Then:
- Open a PR against
releasewith the fix (cherry-picked frommainwhen it landed there) and the release-preparation changes, and merge it. - Port the release-facing site updates (changelog, release blog post,
tdVersion.latest) onto a branch offmainand merge them by PR. A PR fromreleaseitself would carry the patch’s version stamps.
Branch sync and invariants
main: for its rules and the merge gates, see Merge requirements.
release:
- Follows
main: divergence lasts only from a patch onreleaseto the next release frommain. - Every official release tag is reachable from it.
- Stays at the latest release between releases: it is the base for patches.
- Never rewritten: no force pushes, no deletion (enforced by its ruleset).
- Receives content only through releases from
mainor patches onrelease. - Checks (including EasyCLA and workflow security analysis) run on PRs into
release; acting on them is the merging maintainer’s call. Merge with EasyCLA green, though: a miss onreleasecan’t be undone and blocks the next restore until the author signs.
deploy/prod: follows release as a pointer, never with commits of its own;
the published docs change only when release moves.
Why this model?
- Keeps theme releases predictable while
mainmoves quickly. - Keeps
releasea follower ofmain, so a patch never opens a second line of development. - Protects
releaseagainst rewriting without gating it: requiringmain’s PR-scoped gates there would refuse the fast-forward frommain, whose content already passed them. - Keeps
deploy/proda pointer, so publishing is a deliberate last step, separate from cutting the release.