@inditextech/docouture-cli 0.1.0-SNAPSHOT.40.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/build/bin.js +321 -0
  2. package/build/commands/build.js +22 -0
  3. package/build/commands/completion.js +69 -0
  4. package/build/commands/dev.js +67 -0
  5. package/build/commands/doctor.js +156 -0
  6. package/build/commands/eject.js +71 -0
  7. package/build/commands/new.js +512 -0
  8. package/build/commands/publish.js +111 -0
  9. package/build/commands/teardown.js +66 -0
  10. package/build/commands/upgrade.js +156 -0
  11. package/build/commands/version.js +60 -0
  12. package/build/lib/agents-md.js +67 -0
  13. package/build/lib/antora-log.js +36 -0
  14. package/build/lib/antora-yml.js +47 -0
  15. package/build/lib/args.js +26 -0
  16. package/build/lib/cli-context.js +17 -0
  17. package/build/lib/cli-info.js +20 -0
  18. package/build/lib/config-resolver.js +23 -0
  19. package/build/lib/copy-template.js +162 -0
  20. package/build/lib/debug-log.js +21 -0
  21. package/build/lib/detect-package-manager.js +79 -0
  22. package/build/lib/dev-server.js +337 -0
  23. package/build/lib/doctor-checks.js +240 -0
  24. package/build/lib/global-flags.js +31 -0
  25. package/build/lib/kroki-compose.js +54 -0
  26. package/build/lib/playbook-yml.js +90 -0
  27. package/build/lib/repo-root.js +21 -0
  28. package/build/lib/run-script.js +50 -0
  29. package/build/lib/theme.js +51 -0
  30. package/build/templates/agent-support/.claude/skills/docs-internals/SKILL.md +53 -0
  31. package/build/templates/agent-support/.claude/skills/docs-internals/reference/antora-extensions.md +54 -0
  32. package/build/templates/agent-support/.claude/skills/docs-internals/reference/naming.md +41 -0
  33. package/build/templates/agent-support/.claude/skills/docs-internals/reference/page-patterns.md +238 -0
  34. package/build/templates/agent-support/.claude/skills/docs-versioning.versioned/SKILL.md +37 -0
  35. package/build/templates/agent-support/.claude/skills/docs-versioning.versioned/reference/releasing.md +106 -0
  36. package/build/templates/agent-support/.claude/skills/documenting-your-repo/SKILL.md +55 -0
  37. package/build/templates/agent-support/.claude/skills/documenting-your-repo/reference/content-sourcing.md +55 -0
  38. package/build/templates/agent-support/.claude/skills/documenting-your-repo/reference/maintenance-loop.md +68 -0
  39. package/build/templates/agent-support/.claude/skills/documenting-your-repo/reference/structure-planning.md +102 -0
  40. package/build/templates/agent-support/.claude/skills/writing-docs-pages/SKILL.md +112 -0
  41. package/build/templates/agent-support/.claude/skills/writing-docs-pages/reference/docouture-blocks.md +170 -0
  42. package/build/templates/agent-support/.claude/skills/writing-docs-pages/reference/language-basics.md +402 -0
  43. package/build/templates/agent-support/.opencode/skills/docs-internals/SKILL.md +53 -0
  44. package/build/templates/agent-support/.opencode/skills/docs-internals/reference/antora-extensions.md +54 -0
  45. package/build/templates/agent-support/.opencode/skills/docs-internals/reference/naming.md +41 -0
  46. package/build/templates/agent-support/.opencode/skills/docs-internals/reference/page-patterns.md +238 -0
  47. package/build/templates/agent-support/.opencode/skills/docs-versioning.versioned/SKILL.md +37 -0
  48. package/build/templates/agent-support/.opencode/skills/docs-versioning.versioned/reference/releasing.md +106 -0
  49. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/SKILL.md +55 -0
  50. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/reference/content-sourcing.md +55 -0
  51. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/reference/maintenance-loop.md +68 -0
  52. package/build/templates/agent-support/.opencode/skills/documenting-your-repo/reference/structure-planning.md +102 -0
  53. package/build/templates/agent-support/.opencode/skills/writing-docs-pages/SKILL.md +112 -0
  54. package/build/templates/agent-support/.opencode/skills/writing-docs-pages/reference/docouture-blocks.md +170 -0
  55. package/build/templates/agent-support/.opencode/skills/writing-docs-pages/reference/language-basics.md +402 -0
  56. package/build/templates/agent-support/AGENTS.md +72 -0
  57. package/build/templates/starter/antora-playbook.local.yml +99 -0
  58. package/build/templates/starter/antora-playbook.versioned.yml +167 -0
  59. package/build/templates/starter/antora-playbook.yml +189 -0
  60. package/build/templates/starter/gitignore +3 -0
  61. package/build/templates/starter/package.json +37 -0
  62. package/build/templates/starter/scripts/check-links.mjs +178 -0
  63. package/build/templates/starter/src/antora.yml +85 -0
  64. package/build/templates/starter/src/modules/ROOT/images/card-placeholder.png +0 -0
  65. package/build/templates/starter/src/modules/ROOT/images/feature-placeholder-dark.png +0 -0
  66. package/build/templates/starter/src/modules/ROOT/images/feature-placeholder.png +0 -0
  67. package/build/templates/starter/src/modules/ROOT/images/hero-placeholder.png +0 -0
  68. package/build/templates/starter/src/modules/ROOT/pages/index.adoc +124 -0
  69. package/build/templates/starter/src/modules/main/nav.adoc +19 -0
  70. package/build/templates/starter/src/modules/main/pages/app.adoc +5 -0
  71. package/build/templates/starter/src/modules/main/pages/architecture.adoc +6 -0
  72. package/build/templates/starter/src/modules/main/pages/changelog/index.adoc +9 -0
  73. package/build/templates/starter/src/modules/main/pages/components.adoc +701 -0
  74. package/build/templates/starter/src/modules/main/pages/contributing.adoc +6 -0
  75. package/build/templates/starter/src/modules/main/pages/getting-started.adoc +169 -0
  76. package/build/templates/starter/src/modules/main/pages/glossary.adoc +8 -0
  77. package/build/templates/starter/src/modules/main/pages/index.adoc +9 -0
  78. package/build/templates/starter/src/modules/main/pages/prerequisites.adoc +55 -0
  79. package/build/templates/starter/src/modules/main/pages/quickstart.adoc +21 -0
  80. package/build/templates/starter/src/modules/main/pages/release-notes/index.adoc +9 -0
  81. package/build/templates/starter/src/modules/main/pages/requirements.adoc +8 -0
  82. package/build/templates/starter/src/modules/main/pages/roadmap.adoc +4 -0
  83. package/build/templates/starter/src/modules/main/pages/structure.adoc +5 -0
  84. package/build/templates/starter/src/release-version.versioned +1 -0
  85. package/build/templates/starter/supplemental-ui/favicon.ico +0 -0
  86. package/build/templates/starter/supplemental-ui/product-logo-dark.png +0 -0
  87. package/build/templates/starter/supplemental-ui/product-logo.png +0 -0
  88. package/build/templates/workflows/docouture-kroki-cache-warm.yml +101 -0
  89. package/build/templates/workflows/docouture-pr-verify.yml +120 -0
  90. package/build/templates/workflows/docouture-publish-prerelease.yml +122 -0
  91. package/build/templates/workflows/docouture-publish.yml +138 -0
  92. package/build/templates/workflows/docouture-release-preview.yml +198 -0
  93. package/build/templates/workflows/docouture-release.yml +414 -0
  94. package/package.json +38 -0
@@ -0,0 +1,169 @@
1
+ = Getting started
2
+
3
+ If this site is meant to end up published on GitHub Pages, see
4
+ xref:main:prerequisites.adoc[Prerequisites] first — the repository needs to
5
+ be public, GitHub Pages needs to be pointed at `gh-pages`, and the
6
+ `docs/release` label needs to exist, none of which `docouture new` can set up on
7
+ your behalf.
8
+
9
+ == Start the local dev server
10
+
11
+ [tabs]
12
+ --
13
+ [tab,label="pnpm"]
14
+ ****
15
+ [,console]
16
+ ----
17
+ $ pnpm install
18
+ $ pnpm run dev
19
+ ----
20
+ ****
21
+
22
+ [tab,label="npm"]
23
+ ****
24
+ [,console]
25
+ ----
26
+ $ npm install
27
+ $ npm run dev
28
+ ----
29
+ ****
30
+ --
31
+
32
+ `docouture dev` (what either script above wraps) builds the site once, serves it
33
+ on http://localhost:5000, and rebuilds and reloads the browser on every
34
+ change under `docs/` or to `antora-playbook.local.yml` — pass `--port` to
35
+ use a different one. See xref:main:components.adoc[] for what the built-in
36
+ blocks (tabs, cards, accordion, …) actually look like while you write.
37
+
38
+ For a single, non-watching build instead — what CI itself runs — use
39
+ `docouture build`, a thin wrapper around `npm run build`/`pnpm run build`
40
+ (`antora --fetch antora-playbook.yml`). Either way, the generated site is
41
+ written to `build/site`.
42
+
43
+ == Add a page
44
+
45
+ Create an AsciiDoc file under `modules/<module>/pages/`, then add it to that
46
+ module's `nav.adoc` so it appears in the navigation:
47
+
48
+ [,asciidoc]
49
+ ----
50
+ * xref:my-new-page.adoc[My new page]
51
+ ----
52
+
53
+ A page that is not listed in the navigation is still published; it just
54
+ cannot be reached by browsing. This page itself is listed — see `main`'s own
55
+ `nav.adoc` — and is also linked directly from the landing's `Get started`
56
+ action (xref:ROOT:index.adoc[]'s `:page-action:` attribute) and its first
57
+ quicklink card.
58
+
59
+ == Release the docs
60
+
61
+ A release is cut by running `.github/workflows/docouture-release.yml`
62
+ (scaffolded by `docouture new`), not by hand-editing anything in this directory.
63
+ Two ways to trigger it:
64
+
65
+ * **Manually** — Actions tab → "docouture-release" → Run workflow. Works
66
+ immediately, nothing to set up first.
67
+ * **Automatically** — merge a pull request into `main` carrying the
68
+ `docs/release` label. Requires that label to already exist — see
69
+ xref:main:prerequisites.adoc[] — otherwise the merge is a silent no-op.
70
+
71
+ Under the hood this bumps the version recorded in `docs/antora.yml` and
72
+ moves the `stable` tag (or, in Versioned mode, cuts a new `vX.Y.Z` tag) —
73
+ see that workflow's own header comment for the full mechanism.
74
+
75
+ In *Versioned* mode, the target version for the *next* release is not typed
76
+ into a form — it comes from `docs/.release-version`, a plain-text file
77
+ `docouture new` already seeded (e.g. `0.1.0`). To release `1.0.0`:
78
+
79
+ . Edit `docs/.release-version` so it contains `1.0.0`
80
+ . Open a pull request with that change, labeled `docs/release`
81
+ . Merge it — `docouture-release.yml` reads the file, tags `v1.0.0`, and bumps
82
+ `docs/.release-version` forward to the next patch version afterwards so
83
+ the file is always ready for whatever comes next
84
+
85
+ (Or skip the PR: run `docouture-release.yml` manually via `workflow_dispatch` and
86
+ type the version into its `version` input.) *Standalone* mode has no such
87
+ file — every release always targets the same `stable` tag, so there is
88
+ nothing to set beforehand.
89
+
90
+ `docouture version <value>` is a different, narrower tool: it directly
91
+ rewrites `docs/antora.yml`'s `version:`/`prerelease:` fields in place and
92
+ leaves everything else in this directory untouched. It is what
93
+ `docouture-release.yml` itself uses internally, and it's useful for local,
94
+ throwaway testing of how a given version renders — but running it yourself
95
+ does not cut a release, on either mode, and in particular it never touches
96
+ `docs/.release-version`:
97
+
98
+ [,console]
99
+ ----
100
+ $ docouture version 1.0.0
101
+ $ docouture version 1.1.0-rc.0 --prerelease
102
+ ----
103
+
104
+ == Publish the docs
105
+
106
+ `docouture new` already scaffolded two workflows that build this site and run
107
+ `docouture publish gh-pages`:
108
+
109
+ * **`docouture-publish-prerelease.yml`** — runs automatically on every ordinary
110
+ push to `main` that touches actual docs content, no label needed. This is
111
+ what keeps the prerelease version up to date after a normal merge.
112
+ * **`docouture-publish.yml`** — not triggered by push itself; `docouture-release.yml`
113
+ calls it directly once a release is actually cut (see `== Release the
114
+ docs` above), and it stays available for a manual rebuild+republish of
115
+ whatever is currently on `main` via its own `workflow_dispatch`.
116
+
117
+ Two things are still required before either of these actually publishes
118
+ anything (see xref:main:prerequisites.adoc[] for the repository/GitHub-Pages
119
+ side of this):
120
+
121
+ . Add `@inditextech/docouture-publish-gh-pages` to this package's own
122
+ `devDependencies` — already present in the scaffolded `package.json` — and
123
+ install so it resolves.
124
+ . Set `site.url` in `antora-playbook.yml` to this site's public URL. For a
125
+ GitHub Pages project page, that is `https://<org>.github.io/<repo>` — the
126
+ repository name has to be baked in as a path segment, or generated asset
127
+ URLs come out wrong.
128
+
129
+ Optional: a custom domain is a `cname` string under this package's own
130
+ `"docouture": { "publish": { "gh-pages": { "cname": "docs.example.com" } } }` in
131
+ `package.json` (see the scaffolded stub there) — `docouture publish` writes it as
132
+ a `CNAME` file alongside the built site. Leave the block empty, as scaffolded,
133
+ for a plain `github.io` URL.
134
+
135
+ The empty block is not "no config" — `@inditextech/docouture-publish-gh-pages`
136
+ defaults `nojekyll` to `true` regardless, writing a `.nojekyll` file at the
137
+ published branch's root. Without it, GitHub Pages' own Jekyll processing
138
+ silently drops every `_`-prefixed path — exactly where the UI bundle's own
139
+ assets live (`/_/css/...`, `/_/js/...`) — and the published site loads
140
+ unstyled. Only worth touching if something else needs Jekyll processing on;
141
+ pass `"nojekyll": false` in that same block to opt back into it.
142
+
143
+ To publish once manually, from this directory:
144
+
145
+ [tabs]
146
+ --
147
+ [tab,label="pnpm"]
148
+ ****
149
+ [,console]
150
+ ----
151
+ $ pnpm run build
152
+ $ pnpm exec docouture publish gh-pages
153
+ ----
154
+ ****
155
+
156
+ [tab,label="npm"]
157
+ ****
158
+ [,console]
159
+ ----
160
+ $ npm run build
161
+ $ npx docouture publish gh-pages
162
+ ----
163
+ ****
164
+ --
165
+
166
+ `GITHUB_TOKEN` (set automatically in the Actions workflow) authenticates the
167
+ push; running this locally needs a token of your own with `repo` scope,
168
+ passed as the `GITHUB_TOKEN` environment variable.
169
+
@@ -0,0 +1,8 @@
1
+ = Glossary
2
+
3
+ Define project-specific terms here, one per section, so other pages can
4
+ link to a definition instead of re-explaining it inline.
5
+
6
+ == Example term
7
+
8
+ A short definition of the term goes here. Replace with real terminology.
@@ -0,0 +1,9 @@
1
+ = About
2
+
3
+ This is the `main` module — a placeholder content module scaffolded by
4
+ `docouture new`, structured the way a real documentation set typically is:
5
+ an overview, a getting-started path, a section for the thing being
6
+ documented, and additional reference material.
7
+
8
+ Replace this page with a real introduction to what __DOCOUTURE_TITLE__ is and
9
+ who it is for.
@@ -0,0 +1,55 @@
1
+ = Prerequisites
2
+
3
+ Before following xref:main:getting-started.adoc[Getting started] through to a
4
+ published site, three things need to be true about this repository and its
5
+ GitHub settings. None of them are things `docouture new` can do on your behalf —
6
+ they all require repository-admin access this CLI never has.
7
+
8
+ == The repository must be public
9
+
10
+ GitHub Pages serves a `gh-pages` branch to the public internet on a free
11
+ plan only for a public repository — a private one needs GitHub Enterprise
12
+ (GitHub Pages on a paid plan can be restricted to organisation members, but
13
+ is still not the "publish this to the world" flow `docouture-publish.yml`
14
+ assumes). If this repository is private and is meant to stay that way,
15
+ publishing to GitHub Pages is not the right target — use `docouture build` and
16
+ ship `build/site` some other way instead.
17
+
18
+ == Enable GitHub Pages, serving from `gh-pages`
19
+
20
+ Settings → Pages → **Build and deployment** → **Source**: "Deploy from a
21
+ branch" → **Branch**: `gh-pages` / `/ (root)`.
22
+
23
+ The `gh-pages` branch does not exist yet on a brand-new repository — it is
24
+ created the first time `docouture publish gh-pages` (or the scaffolded
25
+ `.github/workflows/docouture-publish.yml`, which calls it) actually runs. Publish
26
+ once first — either by pushing to `main` and letting that workflow run, or
27
+ manually per xref:main:getting-started.adoc[Getting started]'s own "Publish
28
+ the docs" section — then come back and point Pages at the branch it created.
29
+ Turning Pages on before that branch exists just leaves the picker with
30
+ nothing to select.
31
+
32
+ == Create the `docs/release` label
33
+
34
+ `.github/workflows/docouture-release.yml` (scaffolded by `docouture new`) can cut a
35
+ release two ways: `workflow_dispatch` (run it by hand from the Actions tab —
36
+ works immediately, nothing to set up), or automatically whenever a pull
37
+ request merges into `main` carrying a `docs/release` label.
38
+
39
+ That label is not created automatically — GitHub does not create labels
40
+ referenced by a workflow's `if:` condition, and `docouture new` does not call the
41
+ GitHub API on your behalf. Until the label exists, only the manual
42
+ `workflow_dispatch` path works; a PR merged with what would otherwise be the
43
+ intended label name is a silent no-op, not an error.
44
+
45
+ Create it once, from this repository:
46
+
47
+ [,console]
48
+ ----
49
+ $ gh label create docs/release --description "Merging this PR cuts a release" --color 0E8A16
50
+ ----
51
+
52
+ Or via the GitHub UI: repository → Issues or Pull requests → Labels → New
53
+ label, named exactly `docs/release`. `docouture doctor` warns (without failing)
54
+ if it does not find this label, when the `gh` CLI is available and
55
+ authenticated.
@@ -0,0 +1,21 @@
1
+ = Quickstart
2
+
3
+ Walk through the smallest path to a working result, as concrete steps.
4
+
5
+ == 1. Install
6
+
7
+ [,console]
8
+ ----
9
+ $ echo "replace with the real install command"
10
+ ----
11
+
12
+ == 2. Run
13
+
14
+ [,console]
15
+ ----
16
+ $ echo "replace with the real run command"
17
+ ----
18
+
19
+ == 3. Verify
20
+
21
+ Describe what success looks like here.
@@ -0,0 +1,9 @@
1
+ = Release notes
2
+
3
+ Summarize what changed for users in each release here, newest first — in
4
+ contrast to xref:main:changelog/index.adoc[Changelog], which is the
5
+ unabridged commit-level record.
6
+
7
+ == v0.1.0
8
+
9
+ Placeholder entry. Replace with the real first release's notes.
@@ -0,0 +1,8 @@
1
+ = Requirements
2
+
3
+ List the prerequisites someone needs before following the
4
+ xref:main:quickstart.adoc[Quickstart] — tooling, versions, accounts, or
5
+ access.
6
+
7
+ * Requirement one
8
+ * Requirement two
@@ -0,0 +1,4 @@
1
+ = Roadmap
2
+
3
+ Describe what is planned next here — in enough detail to set expectations,
4
+ without promising dates this page will have to walk back.
@@ -0,0 +1,5 @@
1
+ = Structure
2
+
3
+ Describe the project's own structure here — the layout of its repository,
4
+ packages, or modules, and where a contributor would look for a given piece
5
+ of functionality.
@@ -0,0 +1,101 @@
1
+ name: docouture-kroki-cache-warm
2
+
3
+ # GitHub Actions' cache is scoped to the branch/ref a run executes under, not
4
+ # just the key string — and a `pull_request`-triggered run (docouture-release.yml's
5
+ # main trigger) is ALWAYS scoped to that PR's own ephemeral merge ref
6
+ # (`refs/pull/<N>/merge`), by design, even when it targets `main` and even
7
+ # after it merges. See GitHub's own docs ("Restrictions for accessing a
8
+ # cache"): "Caches created by a pull_request run are already scoped to the
9
+ # merge ref ... and cannot be written to the default branch's scope." That
10
+ # means every release PR gets its own throwaway cache scope — release #12's
11
+ # warm Kroki image cache is invisible to release #13, #14, etc., even though
12
+ # the cache KEY (kroki-compose.yml's own hash) never changes between them.
13
+ #
14
+ # The one sanctioned way around this (same docs, "Cache access for low-trust
15
+ # workflow triggers"): "ensure there is a trusted workflow that keeps the
16
+ # cache updated, for example a CI build triggered by a push to the default
17
+ # branch." `push` is on GitHub's trusted-trigger allowlist, so a run
18
+ # triggered this way writes into the DEFAULT BRANCH's cache scope — and any
19
+ # other run in this repo (any PR, any ref, `pull_request: closed` included)
20
+ # automatically falls back to that scope on its own cache lookup, no
21
+ # `restore-keys` needed, since the key string is already identical
22
+ # everywhere. That's this workflow's only job: keep that default-branch-scoped
23
+ # entry warm, so docouture-pr-verify.yml/docouture-release.yml/docouture-publish.yml's own
24
+ # (unmodified) cache steps get a real hit instead of a cold pull on every run.
25
+ #
26
+ # Gated on `kroki-enabled` the same way those three are — no point warming a
27
+ # cache for images a disabled site's build will never touch.
28
+ on:
29
+ push:
30
+ branches: ['main*']
31
+
32
+ concurrency:
33
+ group: docouture-kroki-cache-warm
34
+ cancel-in-progress: true
35
+
36
+ jobs:
37
+ warm:
38
+ name: Warm Kroki image cache
39
+ runs-on: ubuntu-latest
40
+ timeout-minutes: 15
41
+ # `docouture new` scaffolds this site's package.json, antora-playbook.yml
42
+ # etc. under docs/ (not the repository root) — see the docs-site-package
43
+ # skill's reference/versioning-modes.md. Every step below runs from
44
+ # there; only .github/workflows itself has to live at the true repo
45
+ # root, since that is the one path GitHub Actions requires.
46
+ defaults:
47
+ run:
48
+ working-directory: docs
49
+ steps:
50
+ - name: Checkout
51
+ uses: actions/checkout@v4
52
+
53
+ # __DOCOUTURE_PM_SETUP_STEP__
54
+ - name: Setup Node
55
+ uses: actions/setup-node@v4
56
+ with:
57
+ # Reads engines.node from docs/package.json — no separate version
58
+ # file to keep in sync.
59
+ node-version-file: docs/package.json
60
+ cache: __DOCOUTURE_PM_CACHE__
61
+ # `defaults.run.working-directory: docs` above only applies to
62
+ # `run:` steps, not to this action's own inputs — without this,
63
+ # setup-node looks for a lockfile from the repo root and fails.
64
+ cache-dependency-path: docs/__DOCOUTURE_LOCKFILE__
65
+
66
+ - name: Install dependencies
67
+ run: __DOCOUTURE_INSTALL_CI__
68
+
69
+ # This is `main`'s own real antora-playbook.yml (this workflow only
70
+ # ever runs on a push to main, so there's no local/tag ambiguity to
71
+ # worry about the way docouture-release.yml's build step has) — see
72
+ # docouture-pr-verify.yml's own comment on the `kroki-enabled` attribute.
73
+ - name: Kroki / Detect enabled
74
+ id: kroki-check
75
+ run: |
76
+ if grep -qE "^\s*kroki-enabled:\s*['\"]?true['\"]?\s*(#.*)?$" antora-playbook.yml; then
77
+ echo "enabled=true" >> "$GITHUB_OUTPUT"
78
+ else
79
+ echo "enabled=false" >> "$GITHUB_OUTPUT"
80
+ fi
81
+
82
+ # Same cache key as docouture-pr-verify.yml/docouture-release.yml/
83
+ # docouture-publish.yml — the point of this job is only WHERE it's written
84
+ # from (a trusted `push` trigger, landing in the default branch's cache
85
+ # scope), never a different key. No load/consume step below: nothing
86
+ # else in this job needs the images locally, it only needs the cache
87
+ # entry to exist for those other workflows to fall back to.
88
+ - name: Kroki / Docker image cache
89
+ id: kroki-cache
90
+ if: steps.kroki-check.outputs.enabled == 'true'
91
+ uses: actions/cache@v4
92
+ with:
93
+ path: /tmp/kroki-images.tar
94
+ key: ${{ runner.os }}-kroki-images-${{ hashFiles('**/kroki-compose.yml') }}
95
+
96
+ - name: Kroki / Pull and save images
97
+ if: steps.kroki-check.outputs.enabled == 'true' && steps.kroki-cache.outputs.cache-hit != 'true'
98
+ run: |
99
+ compose_file="$(find . -name kroki-compose.yml 2>/dev/null | head -1)"
100
+ docker compose -f "$compose_file" pull
101
+ docker save -o /tmp/kroki-images.tar $(docker compose -f "$compose_file" config --images)
@@ -0,0 +1,120 @@
1
+ name: docouture-pr-verify
2
+
3
+ # Validates that the docs still build on a pull request. Deliberately builds
4
+ # only the PR's own HEAD — not whichever refs this site's versioning mode
5
+ # (see the docs-site-package skill's versioning-modes.md) publishes from:
6
+ #
7
+ # - Versioned (Full History): not the prerelease branch, not any `v*`
8
+ # release tag.
9
+ # - Standalone (Stable + Prerelease): not the prerelease branch, not the
10
+ # rolling `stable` tag.
11
+ #
12
+ # A PR checkout is on a detached HEAD or a feature branch — neither of those
13
+ # refs — so building the real `antora-playbook.yml` here would either fail
14
+ # (the refs it names are not reachable from a shallow, single-ref checkout)
15
+ # or silently validate the wrong content. `antora-playbook.local.yml` (see
16
+ # that file's own header) exists for exactly this: one content source,
17
+ # `branches: HEAD`, so this always validates whatever the PR actually
18
+ # changed — no `fetch-depth: 0` needed, since no other ref is ever read.
19
+ on:
20
+ pull_request: {}
21
+
22
+ concurrency:
23
+ group: docouture-pr-verify-${{ github.event.pull_request.number }}
24
+ cancel-in-progress: true
25
+
26
+ jobs:
27
+ verify:
28
+ name: Verify
29
+ runs-on: ubuntu-latest
30
+ timeout-minutes: 15
31
+ # `docouture new` scaffolds this site's package.json, antora-playbook.yml
32
+ # etc. under docs/ (not the repository root) — see the docs-site-package
33
+ # skill's reference/versioning-modes.md. Every step below runs from
34
+ # there; only .github/workflows itself has to live at the true repo
35
+ # root, since that is the one path GitHub Actions requires.
36
+ defaults:
37
+ run:
38
+ working-directory: docs
39
+ steps:
40
+ - name: Checkout
41
+ uses: actions/checkout@v4
42
+
43
+ # __DOCOUTURE_PM_SETUP_STEP__
44
+ - name: Setup Node
45
+ uses: actions/setup-node@v4
46
+ with:
47
+ # Reads engines.node from docs/package.json — no separate version
48
+ # file to keep in sync.
49
+ node-version-file: docs/package.json
50
+ cache: __DOCOUTURE_PM_CACHE__
51
+ # `defaults.run.working-directory: docs` above only applies to
52
+ # `run:` steps, not to this action's own inputs — without this,
53
+ # setup-node looks for a lockfile from the repo root and fails.
54
+ cache-dependency-path: docs/__DOCOUTURE_LOCKFILE__
55
+
56
+ - name: Install dependencies
57
+ run: __DOCOUTURE_INSTALL_CI__
58
+
59
+ # This build's antora-playbook.local.yml (the file Build actually reads
60
+ # below) may or may not have `kroki-enabled: true` — a site can turn it
61
+ # off (see that attribute's own comment). When it's off, the Build
62
+ # step's implicit Kroki startup never runs, so priming a Docker image
63
+ # store for it would just waste time on every single PR run; this step
64
+ # checks that up front and gates the three Kroki steps below on it.
65
+ - name: Kroki / Detect enabled
66
+ id: kroki-check
67
+ run: |
68
+ if grep -qE "^\s*kroki-enabled:\s*['\"]?true['\"]?\s*(#.*)?$" antora-playbook.local.yml; then
69
+ echo "enabled=true" >> "$GITHUB_OUTPUT"
70
+ else
71
+ echo "enabled=false" >> "$GITHUB_OUTPUT"
72
+ fi
73
+
74
+ # When enabled: the Build step below renders real diagrams through a
75
+ # local Kroki service that `@inditextech/docouture-antora-extensions`'
76
+ # `kroki-prewarm.js` starts itself (docker compose) the moment it finds
77
+ # nothing listening yet — no explicit setup needed for that. These two
78
+ # steps only prime the runner's Docker image store first, so that
79
+ # implicit startup finds everything already pulled instead of doing it
80
+ # cold on every run. Cache key is the compose file's own hash (images
81
+ # are pinned by digest, not `:latest` — see that file's own header), so
82
+ # it only invalidates when the actual pinned images change.
83
+ - name: Kroki / Docker image cache
84
+ id: kroki-cache
85
+ if: steps.kroki-check.outputs.enabled == 'true'
86
+ uses: actions/cache@v4
87
+ with:
88
+ path: /tmp/kroki-images.tar
89
+ key: ${{ runner.os }}-kroki-images-${{ hashFiles('**/kroki-compose.yml') }}
90
+
91
+ - name: Kroki / Load cached images
92
+ if: steps.kroki-check.outputs.enabled == 'true' && steps.kroki-cache.outputs.cache-hit == 'true'
93
+ run: docker load -i /tmp/kroki-images.tar
94
+
95
+ - name: Kroki / Pull and save images
96
+ if: steps.kroki-check.outputs.enabled == 'true' && steps.kroki-cache.outputs.cache-hit != 'true'
97
+ run: |
98
+ # docs/kroki-compose.yml if this site has ejected it (see that
99
+ # file's own header), else the bundled default under node_modules.
100
+ compose_file="$(find . -name kroki-compose.yml 2>/dev/null | head -1)"
101
+ docker compose -f "$compose_file" pull
102
+ docker save -o /tmp/kroki-images.tar $(docker compose -f "$compose_file" config --images)
103
+
104
+ - name: Build
105
+ run: npx antora --fetch antora-playbook.local.yml
106
+
107
+ # Antora's own `runtime.log.failure_level: warn` (see
108
+ # antora-playbook.yml's own comment) already fails the Build step above
109
+ # on a broken cross-reference — but that only covers refs Antora
110
+ # itself resolves. Raw http(s) links in content are invisible to it, so
111
+ # `check-links` (package.json's own script, see scripts/check-links.mjs)
112
+ # crawls the built HTML separately to catch those before they reach a
113
+ # PR reviewer. It only fails on a broken EXTERNAL link — a broken local
114
+ # one is printed as a warning, never a failure, since this job builds
115
+ # with antora-playbook.local.yml (a single, HEAD-only source) and
116
+ # content generated from config (the module switcher, the footer) can
117
+ # legitimately point at another version/component this reduced build
118
+ # doesn't have. See that script's own header comment.
119
+ - name: Check links
120
+ run: __DOCOUTURE_PM__ run check-links
@@ -0,0 +1,122 @@
1
+ name: docouture-publish-prerelease
2
+
3
+ # Rebuilds and republishes the prerelease (main-branch) docs automatically on
4
+ # every ordinary push to main* that actually touches content — no
5
+ # docs/release label needed, unlike docouture-release.yml. This exists
6
+ # specifically so ordinary content merges show up without anyone having to
7
+ # fall back to docouture-publish.yml's own workflow_dispatch every time.
8
+ #
9
+ # A plain `on: push: branches: [main*]` used to live directly on
10
+ # docouture-publish.yml and was removed for two reasons — see that file's own
11
+ # header comment. Both are avoided here by construction rather than by
12
+ # reintroducing the same trigger in the same place:
13
+ #
14
+ # 1. An unrelated commit shouldn't kick off a rebuild with nothing new to
15
+ # publish. `check-changes-in-paths` (below) gates on real content paths
16
+ # only. In particular this deliberately excludes docs/.release-version:
17
+ # that file is the ONLY thing docouture-release.yml's own "Bump release
18
+ # descriptor" step pushes straight to main directly (see that
19
+ # workflow's own comment on that step) — a bot commit that is not new
20
+ # docs content and would otherwise fire this workflow for nothing.
21
+ #
22
+ # 2. Firing twice for one release — once from a docs/release-labeled
23
+ # merge's own content, and again from docouture-release.yml's chained
24
+ # docouture-publish.yml call once the tag is actually cut — is not a race
25
+ # (the two are sequential, not simultaneous: this workflow's own push
26
+ # event fires at merge time, before docouture-release.yml's job even
27
+ # starts), just a redundant rebuild. `check-release-label` (below)
28
+ # closes that gap directly: if the commit that triggered this push came
29
+ # from a merged pull request carrying the docs/release label,
30
+ # docouture-release.yml is already about to publish the definitive
31
+ # post-release build itself, so this workflow skips rather than
32
+ # duplicate it.
33
+ on:
34
+ push:
35
+ branches: ['main*']
36
+
37
+ permissions:
38
+ contents: read
39
+ pull-requests: read
40
+
41
+ concurrency:
42
+ group: docouture-publish-prerelease
43
+ cancel-in-progress: true
44
+
45
+ jobs:
46
+ check-changes-in-paths:
47
+ name: Check for changes in corresponding paths
48
+ runs-on: ubuntu-latest
49
+ outputs:
50
+ detected: ${{ steps.changes.outputs.paths }}
51
+ steps:
52
+ # dorny/paths-filter diffs github.event.before -> github.sha via local
53
+ # git history on a push trigger (unlike a pull_request trigger, where
54
+ # it can resolve the base from the GitHub API alone) — needs an actual
55
+ # checkout first, or there is no .git to diff against at all
56
+ # (`git` exits 128, "not a git repository"/"bad revision"). fetch-depth
57
+ # 0 rather than a shallow default: a batched push can carry more
58
+ # commits than a shallow clone's history would contain, and `before`
59
+ # must be reachable locally for the diff to succeed.
60
+ - name: Checkout
61
+ uses: actions/checkout@v4
62
+ with:
63
+ fetch-depth: 0
64
+
65
+ - name: Check for changed files in specific paths
66
+ id: changes
67
+ uses: dorny/paths-filter@ebc4d7e9ebcb0b1eb21480bb8f43113e996ac77a # v3
68
+ with:
69
+ filters: |
70
+ paths:
71
+ - 'docs/src/**'
72
+ - 'docs/antora-playbook*.yml'
73
+ - 'docs/supplemental-ui/**'
74
+ # docs/.release-version is deliberately NOT listed — see this
75
+ # file's own header comment, point 1.
76
+
77
+ check-release-label:
78
+ name: Check for docs/release label on the triggering pull request
79
+ needs: check-changes-in-paths
80
+ if: needs.check-changes-in-paths.outputs.detected == 'true'
81
+ runs-on: ubuntu-latest
82
+ outputs:
83
+ skip: ${{ steps.check.outputs.skip }}
84
+ env:
85
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
86
+ steps:
87
+ # Resolves the merged pull request (if any) that produced this push's
88
+ # HEAD commit, regardless of merge strategy (merge commit, squash, or
89
+ # rebase) — GitHub tracks this association itself rather than this
90
+ # step having to guess from the SHA, see
91
+ # https://docs.github.com/en/rest/commits/commits#list-pull-requests-associated-with-a-commit.
92
+ # A direct push to main with no associated pull request (e.g. an admin
93
+ # pushing straight to main) simply resolves no labels and is never
94
+ # skipped here.
95
+ - name: Check for docs/release label
96
+ id: check
97
+ run: |
98
+ labels=$(gh api "repos/${{ github.repository }}/commits/${{ github.sha }}/pulls" \
99
+ --jq '.[0].labels[].name' 2>/dev/null || echo "")
100
+
101
+ if echo "$labels" | grep -qx 'docs/release'; then
102
+ echo "skip=true" >> "$GITHUB_OUTPUT"
103
+ echo "This push came from a docs/release-labeled merge — docouture-release.yml will publish the definitive build itself, skipping here."
104
+ else
105
+ echo "skip=false" >> "$GITHUB_OUTPUT"
106
+ fi
107
+
108
+ publish:
109
+ name: Publish
110
+ needs: [check-changes-in-paths, check-release-label]
111
+ if: needs.check-changes-in-paths.outputs.detected == 'true' && needs.check-release-label.outputs.skip != 'true'
112
+ # docouture-publish.yml's own `publish` job requests `contents: write` (only
113
+ # ever used by @inditextech/docouture-publish-gh-pages, pushing to the
114
+ # `gh-pages` branch) — a reusable workflow can never be granted more than
115
+ # its caller job holds, so without this the call is rejected outright as
116
+ # a permissions escalation rather than merely losing write access at
117
+ # runtime. The two gate jobs above stay read-only; only this job, which
118
+ # actually calls through, needs the elevated grant.
119
+ permissions:
120
+ contents: write
121
+ uses: ./.github/workflows/docouture-publish.yml
122
+ secrets: inherit