@inditextech/docouture-cli 0.1.0-SNAPSHOT.68.1 → 0.1.0-SNAPSHOT.74.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.
- package/build/bin.js +54 -4
- package/build/commands/branch-model.js +211 -0
- package/build/commands/completion.js +1 -0
- package/build/commands/doctor.js +11 -1
- package/build/commands/new.js +137 -8
- package/build/commands/upgrade.js +20 -0
- package/build/lib/branch-detect.js +87 -0
- package/build/lib/copy-template.js +4 -0
- package/build/lib/dev-server.js +17 -3
- package/build/lib/doctor-checks.js +40 -0
- package/build/lib/playbook-yml.js +51 -0
- package/build/templates/starter/antora-playbook.local.yml +12 -10
- package/build/templates/starter/antora-playbook.versioned.yml +10 -9
- package/build/templates/starter/antora-playbook.yml +10 -8
- package/build/templates/starter/package.json +2 -1
- package/build/templates/starter/src/antora.yml +2 -2
- package/build/templates/starter/src/modules/main/pages/components.adoc +2 -2
- package/build/templates/workflows/docouture-kroki-cache-warm.yml +31 -17
- package/build/templates/workflows/docouture-publish-prerelease.yml +22 -17
- package/build/templates/workflows/docouture-publish.yml +1 -1
- package/build/templates/workflows/docouture-release-preview.yml +3 -2
- package/build/templates/workflows/docouture-release.yml +70 -57
- package/package.json +1 -1
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Branch-name derivation for git-flow support (GH #175) — deliberately not
|
|
3
|
+
// persisted anywhere as its own config, the same way `docouture-release.yml`'s
|
|
4
|
+
// "Detect mode" step derives standalone-vs-versioned live from
|
|
5
|
+
// antora-playbook.yml's own `tags:` line rather than reading it back from a
|
|
6
|
+
// stored value. Here the two branch *roles* are re-derived live from the
|
|
7
|
+
// two files that actually carry them:
|
|
8
|
+
//
|
|
9
|
+
// - prerelease branch: antora-playbook.yml's content.sources[0].branches
|
|
10
|
+
// (see lib/playbook-yml.ts's readBranches)
|
|
11
|
+
// - release branch: docouture-release.yml's checkout `ref:` (the same
|
|
12
|
+
// literal value it also pushes bump commits to, see that workflow's own
|
|
13
|
+
// "Checkout"/"Bump release descriptor" steps)
|
|
14
|
+
//
|
|
15
|
+
// `docs/package.json`'s `docouture.branching` field ('trunk-based' |
|
|
16
|
+
// 'git-flow') is a cheap, redundant-by-design fast-path signal on top of
|
|
17
|
+
// this — never the source of truth for the names themselves, only for
|
|
18
|
+
// `docouture doctor`'s advisory check to compare this derivation against.
|
|
19
|
+
import { readFile } from 'node:fs/promises';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { readBranches } from './playbook-yml.js';
|
|
22
|
+
/**
|
|
23
|
+
* `docouture-release.yml`'s checkout target — the one literal `ref:` key this
|
|
24
|
+
* template file has (its "Checkout" step). Same regex-over-text idiom as
|
|
25
|
+
* playbook-yml.ts, not a real YAML parse: this file is only ever read here,
|
|
26
|
+
* matching how upgrade.ts already treats docs/antora.yml.
|
|
27
|
+
*/
|
|
28
|
+
export function readReleaseBranchFromWorkflow(workflowContent) {
|
|
29
|
+
const match = /^\s*ref:\s*(\S+?)\s*$/m.exec(workflowContent);
|
|
30
|
+
if (!match?.[1])
|
|
31
|
+
return null;
|
|
32
|
+
return match[1].replace(/^['"]|['"]$/g, '');
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Reads both branch roles back from whatever is actually on disk right now
|
|
36
|
+
* — `antora-playbook.yml` under the site root, `docouture-release.yml` under
|
|
37
|
+
* the repository's `.github/workflows/`. Either side resolves to `null` if
|
|
38
|
+
* its file is missing or the expected line isn't found (a site scaffolded
|
|
39
|
+
* before this feature existed still resolves fine here, since both files'
|
|
40
|
+
* shapes predate GH #175 unchanged — this is not a "legacy fallback", it is
|
|
41
|
+
* the only path).
|
|
42
|
+
*/
|
|
43
|
+
export async function detectBranches(siteRoot, repoRoot) {
|
|
44
|
+
const playbookFile = join(siteRoot, 'antora-playbook.yml');
|
|
45
|
+
const releaseWorkflowFile = join(repoRoot, '.github', 'workflows', 'docouture-release.yml');
|
|
46
|
+
let prerelease = null;
|
|
47
|
+
try {
|
|
48
|
+
const content = await readFile(playbookFile, 'utf8');
|
|
49
|
+
prerelease = readBranches(content)?.[0] ?? null;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// No antora-playbook.yml at siteRoot — prerelease stays null.
|
|
53
|
+
}
|
|
54
|
+
let release = null;
|
|
55
|
+
try {
|
|
56
|
+
const content = await readFile(releaseWorkflowFile, 'utf8');
|
|
57
|
+
release = readReleaseBranchFromWorkflow(content);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// No docouture-release.yml under .github/workflows/ — release stays null.
|
|
61
|
+
}
|
|
62
|
+
return { prerelease, release };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Trunk-based is definitionally the degenerate case where both roles are
|
|
66
|
+
* the same branch (see the issue's own design note) — so this is a plain
|
|
67
|
+
* equality check, not a third independently-stored value. Returns `null`
|
|
68
|
+
* when either side couldn't be read, so callers can distinguish "genuinely
|
|
69
|
+
* ambiguous/unreadable" from a real answer.
|
|
70
|
+
*/
|
|
71
|
+
export function inferBranching(branches) {
|
|
72
|
+
if (!branches.prerelease || !branches.release)
|
|
73
|
+
return null;
|
|
74
|
+
return branches.prerelease === branches.release ? 'trunk-based' : 'git-flow';
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* docouture-kroki-cache-warm.yml's `on.push.branches` array content — see
|
|
78
|
+
* TemplateValues.cacheWarmBranchesYaml's own comment on why this workflow
|
|
79
|
+
* triggers on both roles unconditionally rather than just one. Collapses to
|
|
80
|
+
* a single glob when both roles are the same branch (trunk-based) instead
|
|
81
|
+
* of a literal, pointless duplicate.
|
|
82
|
+
*/
|
|
83
|
+
export function cacheWarmBranchesYaml(prereleaseBranch, releaseBranch) {
|
|
84
|
+
const branches = prereleaseBranch === releaseBranch ? [releaseBranch] : [releaseBranch, prereleaseBranch];
|
|
85
|
+
return branches.map((branch) => `'${branch}*'`).join(', ');
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=branch-detect.js.map
|
|
@@ -27,6 +27,10 @@ const PLACEHOLDERS = {
|
|
|
27
27
|
// TemplateValues.repoIgnoreGlob's own comment for why the whole-segment
|
|
28
28
|
// trick doesn't survive here.
|
|
29
29
|
__DOCOUTURE_REPO_IGNORE_GLOB__: 'repoIgnoreGlob',
|
|
30
|
+
__DOCOUTURE_PRERELEASE_BRANCH__: 'prereleaseBranch',
|
|
31
|
+
__DOCOUTURE_RELEASE_BRANCH__: 'releaseBranch',
|
|
32
|
+
__DOCOUTURE_BRANCHING__: 'branching',
|
|
33
|
+
__DOCOUTURE_CACHE_WARM_BRANCHES__: 'cacheWarmBranchesYaml',
|
|
30
34
|
};
|
|
31
35
|
// `<!-- prettier-ignore -->` directives exist only to stop prettier mangling a
|
|
32
36
|
// placeholder token in the template source (e.g. `__DOCOUTURE_TITLE__` inside a
|
package/build/lib/dev-server.js
CHANGED
|
@@ -291,11 +291,25 @@ export async function startDevServer(options) {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
294
|
+
// Always build once up front, even when a prior `build/site` already
|
|
295
|
+
// exists on disk (a previous `docouture build`/`dev` session, or one this
|
|
296
|
+
// process's own file watcher hasn't caught up to yet) — serving stale
|
|
297
|
+
// output silently, with no visible sign anything is out of date, was a
|
|
298
|
+
// real footgun: a `docouture dev` started after content changed on disk
|
|
299
|
+
// since the last build would show the OLD site until the next watched
|
|
300
|
+
// change fired, which can look indistinguishable from "my edit didn't
|
|
301
|
+
// take" if that first edit is what's being tested. Only when there's
|
|
302
|
+
// truly nothing to fall back to (no prior `build/site` at all) does a
|
|
303
|
+
// failed initial build actually throw; if stale output already exists,
|
|
304
|
+
// this degrades exactly like a failed watch-triggered rebuild does
|
|
305
|
+
// below — log it and keep serving what's there.
|
|
306
|
+
const hadExistingBuild = existsSync(root);
|
|
307
|
+
log(hadExistingBuild ? 'building the site' : 'no build output yet, building the site');
|
|
308
|
+
if (!(await runBuild())) {
|
|
309
|
+
if (!hadExistingBuild) {
|
|
297
310
|
throw new Error('initial build failed');
|
|
298
311
|
}
|
|
312
|
+
logError('initial rebuild failed, serving the previous build');
|
|
299
313
|
}
|
|
300
314
|
await new Promise((resolvePromise, reject) => {
|
|
301
315
|
server.once('error', reject);
|
|
@@ -227,4 +227,44 @@ export function checkAgentFilesPresent(repoRoot) {
|
|
|
227
227
|
};
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
|
+
/**
|
|
231
|
+
* Whether `docs/package.json`'s declared `docouture.branching` still agrees
|
|
232
|
+
* with what antora-playbook.yml/docouture-release.yml actually say — the
|
|
233
|
+
* same "names must agree" idiom as checkNamesAgree above, just for a single
|
|
234
|
+
* pair instead of four. Advisory only, same reasoning as
|
|
235
|
+
* checkReleaseLabelExists: a site predating GH #175 (no declared value yet)
|
|
236
|
+
* or one where the derivation itself failed (malformed/hand-edited
|
|
237
|
+
* templates) is reported as `ok: true` rather than a failure — only an
|
|
238
|
+
* actual, confident disagreement between the two is `ok: false`.
|
|
239
|
+
*/
|
|
240
|
+
export function checkBranchingAgrees(input) {
|
|
241
|
+
const label = 'branching model';
|
|
242
|
+
if (!input.declaredBranching) {
|
|
243
|
+
return {
|
|
244
|
+
ok: true,
|
|
245
|
+
label,
|
|
246
|
+
message: 'no docouture.branching declared in docs/package.json — skipping',
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
if (!input.actualBranching) {
|
|
250
|
+
return {
|
|
251
|
+
ok: true,
|
|
252
|
+
label,
|
|
253
|
+
message: 'could not derive the current branch names from antora-playbook.yml/docouture-release.yml — skipping',
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
if (input.declaredBranching === input.actualBranching) {
|
|
257
|
+
return {
|
|
258
|
+
ok: true,
|
|
259
|
+
label,
|
|
260
|
+
message: `docouture.branching '${input.declaredBranching}' matches what antora-playbook.yml/docouture-release.yml actually say`,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
ok: false,
|
|
265
|
+
label,
|
|
266
|
+
message: `docouture.branching '${input.declaredBranching}' != actual '${input.actualBranching}' (derived from antora-playbook.yml/docouture-release.yml)`,
|
|
267
|
+
detail: "run 'docouture branch-model <trunk-based|git-flow>' to re-sync everything, or fix docs/package.json's docouture.branching by hand if it's simply stale",
|
|
268
|
+
};
|
|
269
|
+
}
|
|
230
270
|
//# sourceMappingURL=doctor-checks.js.map
|
|
@@ -87,4 +87,55 @@ export function readSourceUrl(content) {
|
|
|
87
87
|
export function readOutputDir(content) {
|
|
88
88
|
return firstField(topLevelBlock(content, 'output'), 'dir');
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* `content.sources[0].branches` — an inline YAML array (e.g. `[main]`), not
|
|
92
|
+
* a scalar, so this reads it as one and splits it, unlike every other
|
|
93
|
+
* reader above. Used by lib/branch-detect.ts to derive the *prerelease*
|
|
94
|
+
* branch role (GH #175) — see that module's own comment on why this is
|
|
95
|
+
* derived live rather than stored anywhere.
|
|
96
|
+
*/
|
|
97
|
+
export function readBranches(content) {
|
|
98
|
+
const raw = firstField(topLevelBlock(content, 'content'), 'branches');
|
|
99
|
+
if (!raw)
|
|
100
|
+
return null;
|
|
101
|
+
const inner = raw.trim().replace(/^\[/, '').replace(/\]$/, '');
|
|
102
|
+
const values = inner
|
|
103
|
+
.split(',')
|
|
104
|
+
.map((value) => value.trim().replace(/^['"]|['"]$/g, ''))
|
|
105
|
+
.filter(Boolean);
|
|
106
|
+
return values.length > 0 ? values : null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Rewrites `content.sources[0].branches`'s inline array to a single new
|
|
110
|
+
* branch name — the one write this module performs, used by `docouture
|
|
111
|
+
* branch-model` (GH #175) to update an existing site's playbook without a
|
|
112
|
+
* full re-scaffold. Mirrors topLevelBlock's own line-classification (blank/
|
|
113
|
+
* comment lines skipped, a non-indented line either continues or ends the
|
|
114
|
+
* block) so the same top-level-key scoping applies here as everywhere else
|
|
115
|
+
* in this file; returns `content` unchanged if no `branches:` line is found
|
|
116
|
+
* within `content:`'s block.
|
|
117
|
+
*/
|
|
118
|
+
export function writeBranches(content, branch) {
|
|
119
|
+
const lines = content.split('\n');
|
|
120
|
+
let inBlock = false;
|
|
121
|
+
for (let i = 0; i < lines.length; i++) {
|
|
122
|
+
const line = lines[i];
|
|
123
|
+
if (/^\s*(?:#.*)?$/.test(line))
|
|
124
|
+
continue;
|
|
125
|
+
if (/^\S/.test(line)) {
|
|
126
|
+
if (inBlock)
|
|
127
|
+
break;
|
|
128
|
+
inBlock = /^content:/.test(line);
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
if (inBlock) {
|
|
132
|
+
const match = /^(\s*(?:-\s*)?branches:\s*)\[[^\]]*\](.*)$/.exec(line);
|
|
133
|
+
if (match) {
|
|
134
|
+
lines[i] = `${match[1]}[${branch}]${match[2]}`;
|
|
135
|
+
return lines.join('\n');
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return content;
|
|
140
|
+
}
|
|
90
141
|
//# sourceMappingURL=playbook-yml.js.map
|
|
@@ -10,20 +10,22 @@
|
|
|
10
10
|
# Once this site adopts one of the two documented versioning modes (see the
|
|
11
11
|
# docouture docs-site-package skill's reference/versioning-modes.md), the real
|
|
12
12
|
# `antora-playbook.yml` aggregates content from more than just whatever is
|
|
13
|
-
# checked out right now — versioned matches `branches: [
|
|
14
|
-
# `tags: ['docs/v*']`, standalone matches `branches: [
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
13
|
+
# checked out right now — versioned matches `branches: [<prerelease branch>]` +
|
|
14
|
+
# `tags: ['docs/v*']`, standalone matches `branches: [<prerelease branch>]` +
|
|
15
|
+
# `tags: ['docs/stable']` (see the guides-branching-model guide for what
|
|
16
|
+
# "prerelease branch" means — `main` for a trunk-based site, `develop` for a
|
|
17
|
+
# git-flow one). A PR build (or a local build on a feature branch) is on a
|
|
18
|
+
# detached HEAD or a branch that is neither of those, so the prerelease
|
|
19
|
+
# branch and the version tag(s) are not resolved in that checkout — the real
|
|
20
|
+
# playbook either fails or silently builds fewer versions than it should.
|
|
19
21
|
#
|
|
20
22
|
# This playbook points content aggregation at HEAD (the current worktree)
|
|
21
23
|
# instead, so `docouture dev` (see src/lib/dev-server.ts) and
|
|
22
24
|
# `docouture-pr-verify.yml` (see .github/workflows/) validate the current docs
|
|
23
|
-
# content without needing
|
|
24
|
-
# changes shape when a site switches versioning mode
|
|
25
|
-
# there is always exactly one thing to
|
|
26
|
-
# checked out.
|
|
25
|
+
# content without needing the prerelease branch or any release ref. It
|
|
26
|
+
# intentionally never changes shape when a site switches versioning mode or
|
|
27
|
+
# branching model, or adds a release: there is always exactly one thing to
|
|
28
|
+
# validate, whatever is currently checked out.
|
|
27
29
|
#
|
|
28
30
|
# Publishing (`docouture-publish.yml`) uses the real `antora-playbook.yml`.
|
|
29
31
|
#
|
|
@@ -55,15 +55,16 @@ content:
|
|
|
55
55
|
# playbook's comment: the starter template's own nested `src/` lands
|
|
56
56
|
# one level below this repository's `docs/`.
|
|
57
57
|
start_path: docs/src
|
|
58
|
-
# Versioned (Full History):
|
|
59
|
-
# version — docs/antora.yml on this branch says
|
|
60
|
-
# `prerelease: true`, the same as the
|
|
61
|
-
# descriptor is identical for both
|
|
62
|
-
#
|
|
63
|
-
# docs/
|
|
64
|
-
#
|
|
65
|
-
#
|
|
66
|
-
|
|
58
|
+
# Versioned (Full History): __DOCOUTURE_PRERELEASE_BRANCH__ aggregates
|
|
59
|
+
# as the prerelease version — docs/antora.yml on this branch says
|
|
60
|
+
# `version: prerelease`, `prerelease: true`, the same as the
|
|
61
|
+
# standalone mode's shape (this descriptor is identical for both
|
|
62
|
+
# modes on this branch — see docs/antora.yml's own comment).
|
|
63
|
+
# `tags: ['docs/v*']` matches every release tag (docs/v1.2.0,
|
|
64
|
+
# docs/v2.0.0, ...) docouture-release.yml cuts, each an immutable version
|
|
65
|
+
# with its own copy of docs/antora.yml — the version dropdown grows by
|
|
66
|
+
# one every release and nothing here ever needs editing again.
|
|
67
|
+
branches: [__DOCOUTURE_PRERELEASE_BRANCH__]
|
|
67
68
|
tags: ['docs/v*']
|
|
68
69
|
|
|
69
70
|
ui:
|
|
@@ -58,14 +58,16 @@ content:
|
|
|
58
58
|
# copied under this repository's `docs/`, so the descriptor ends up at
|
|
59
59
|
# `docs/src/antora.yml`.
|
|
60
60
|
start_path: docs/src
|
|
61
|
-
# Standalone:
|
|
62
|
-
# docs/antora.yml on this branch permanently says
|
|
63
|
-
# `prerelease: true`. `docs/stable` is a rolling
|
|
64
|
-
# force-moves to a fresh one-off commit
|
|
65
|
-
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
|
|
61
|
+
# Standalone: __DOCOUTURE_PRERELEASE_BRANCH__ aggregates as the prerelease
|
|
62
|
+
# version — docs/antora.yml on this branch permanently says
|
|
63
|
+
# `version: prerelease`, `prerelease: true`. `docs/stable` is a rolling
|
|
64
|
+
# tag that docouture-release.yml force-moves to a fresh one-off commit
|
|
65
|
+
# on every release, cut from the (independently-named) release branch
|
|
66
|
+
# — see docouture-release.yml's own header and the
|
|
67
|
+
# guides-branching-model guide. Until the first release, `docs/stable`
|
|
68
|
+
# does not exist yet and this site builds with just the one
|
|
69
|
+
# (prerelease) version — that is expected, not an error.
|
|
70
|
+
branches: [__DOCOUTURE_PRERELEASE_BRANCH__]
|
|
69
71
|
tags: ['docs/stable']
|
|
70
72
|
|
|
71
73
|
ui:
|
|
@@ -20,10 +20,11 @@
|
|
|
20
20
|
"@inditextech/docouture-asciidoc-extensions": "__DOCOUTURE_CLI_VERSION__",
|
|
21
21
|
"@inditextech/docouture-antora-extensions": "__DOCOUTURE_CLI_VERSION__",
|
|
22
22
|
"@inditextech/docouture-publish-gh-pages": "__DOCOUTURE_CLI_VERSION__",
|
|
23
|
-
"antora": "3.
|
|
23
|
+
"antora": "3.2.0",
|
|
24
24
|
"linkinator": "8.0.4"
|
|
25
25
|
},
|
|
26
26
|
"docouture": {
|
|
27
|
+
"branching": "__DOCOUTURE_BRANCHING__",
|
|
27
28
|
"publish": {
|
|
28
29
|
"gh-pages": {}
|
|
29
30
|
},
|
|
@@ -49,13 +49,13 @@ nav:
|
|
|
49
49
|
# silently camelCased by Antora's content aggregator, which breaks any module
|
|
50
50
|
# slug containing a hyphen.
|
|
51
51
|
#
|
|
52
|
-
# `icon` is
|
|
52
|
+
# `icon` is a bare icon name from the UI bundle's own vendored sprite
|
|
53
53
|
# (packages/ui-bundle/src/img/icons.yml) — an icon name is not free-form.
|
|
54
54
|
nav_modules:
|
|
55
55
|
- module: main
|
|
56
56
|
title: Documentation
|
|
57
57
|
description: Placeholder documentation module — replace with your own content.
|
|
58
|
-
icon:
|
|
58
|
+
icon: grid-3x3
|
|
59
59
|
|
|
60
60
|
# Which module's navigation the generated 404 page's side menu shows, read
|
|
61
61
|
# by @inditextech/docouture-antora-extensions. With a single module there is
|
|
@@ -328,7 +328,7 @@ Add a page, build the site, publish it.
|
|
|
328
328
|
.xref:main:quickstart.adoc[Quickstart]
|
|
329
329
|
The smallest path to a working result, as concrete steps.
|
|
330
330
|
|
|
331
|
-
[card,icon="
|
|
331
|
+
[card,icon="grid-3x3"]
|
|
332
332
|
.xref:main:architecture.adoc[Architecture]
|
|
333
333
|
This one carries a header icon instead of a subheader.
|
|
334
334
|
====
|
|
@@ -469,7 +469,7 @@ diagram source, as literal text, same as the fenced listing shows it above.
|
|
|
469
469
|
|
|
470
470
|
==== Styling
|
|
471
471
|
|
|
472
|
-
Mermaid diagrams are themed to match
|
|
472
|
+
Mermaid diagrams are themed to match this site automatically — square
|
|
473
473
|
corners, black-on-white (light mode; inverted for dark), body typography — via a
|
|
474
474
|
`%%{init: {...}}%%` directive this extension prepends to the diagram's own source
|
|
475
475
|
before it ever reaches Kroki, not via CSS. Write your own `%%{init...}%%` as the
|
|
@@ -2,14 +2,15 @@ name: docouture-kroki-cache-warm
|
|
|
2
2
|
|
|
3
3
|
# GitHub Actions' cache is scoped to the branch/ref a run executes under, not
|
|
4
4
|
# just the key string — and a `pull_request`-triggered run (docouture-release.yml's
|
|
5
|
-
#
|
|
6
|
-
# (`refs/pull/<N>/merge`), by design, even when it targets
|
|
7
|
-
# after it merges. See GitHub's own docs ("Restrictions for
|
|
8
|
-
# cache"): "Caches created by a pull_request run are already
|
|
9
|
-
# merge ref ... and cannot be written to the default branch's
|
|
10
|
-
# means every release PR gets its own throwaway cache scope —
|
|
11
|
-
# warm Kroki image cache is invisible to release #13, #14,
|
|
12
|
-
# the cache KEY (kroki-compose.yml's own hash) never
|
|
5
|
+
# release-branch trigger) is ALWAYS scoped to that PR's own ephemeral merge
|
|
6
|
+
# ref (`refs/pull/<N>/merge`), by design, even when it targets the release
|
|
7
|
+
# branch and even after it merges. See GitHub's own docs ("Restrictions for
|
|
8
|
+
# accessing a cache"): "Caches created by a pull_request run are already
|
|
9
|
+
# scoped to the merge ref ... and cannot be written to the default branch's
|
|
10
|
+
# scope." That means every release PR gets its own throwaway cache scope —
|
|
11
|
+
# release #12's warm Kroki image cache is invisible to release #13, #14,
|
|
12
|
+
# etc., even though the cache KEY (kroki-compose.yml's own hash) never
|
|
13
|
+
# changes between them.
|
|
13
14
|
#
|
|
14
15
|
# The one sanctioned way around this (same docs, "Cache access for low-trust
|
|
15
16
|
# workflow triggers"): "ensure there is a trusted workflow that keeps the
|
|
@@ -23,18 +24,30 @@ name: docouture-kroki-cache-warm
|
|
|
23
24
|
# entry warm, so docouture-pr-verify.yml/docouture-release.yml/docouture-publish.yml's own
|
|
24
25
|
# (unmodified) cache steps get a real hit instead of a cold pull on every run.
|
|
25
26
|
#
|
|
27
|
+
# Triggers on push to BOTH the prerelease and release branches,
|
|
28
|
+
# unconditionally (a trunk-based site collapses this to one entry — see
|
|
29
|
+
# TemplateValues.cacheWarmBranchesYaml in copy-template.ts) — this workflow
|
|
30
|
+
# has no reliable way to know at scaffold time which of the two a git-flow
|
|
31
|
+
# repo actually has configured as its GitHub default branch (the one whose
|
|
32
|
+
# cache scope this whole mechanism depends on), so it warms both rather than
|
|
33
|
+
# guessing wrong and silently losing the optimization. Whichever one really
|
|
34
|
+
# is the configured default gets its cache entry written either way; the
|
|
35
|
+
# other branch's push still produces a normal base-branch-scoped cache,
|
|
36
|
+
# benefiting PRs targeting it specifically, so nothing is wasted.
|
|
37
|
+
#
|
|
26
38
|
# Gated on `kroki-enabled` the same way those three are — no point warming a
|
|
27
39
|
# cache for images a disabled site's build will never touch.
|
|
28
40
|
on:
|
|
29
41
|
push:
|
|
30
|
-
branches: [
|
|
42
|
+
branches: [__DOCOUTURE_CACHE_WARM_BRANCHES__]
|
|
31
43
|
|
|
32
|
-
# Least-privilege default: this job only checks out
|
|
33
|
-
#
|
|
34
|
-
# token-independent cache API, not
|
|
35
|
-
#
|
|
36
|
-
# explicitly rather than left to
|
|
37
|
-
# organization's default token permissions
|
|
44
|
+
# Least-privilege default: this job only checks out the release/prerelease
|
|
45
|
+
# branch it happened to run against, warms the Docker/Kroki image cache and
|
|
46
|
+
# writes it via actions/cache (a separate, token-independent cache API, not
|
|
47
|
+
# repository contents) — it never uses GITHUB_TOKEN itself, so it never
|
|
48
|
+
# needs more than read access. Declared explicitly rather than left to
|
|
49
|
+
# inherit whatever the repository/organization's default token permissions
|
|
50
|
+
# happen to be.
|
|
38
51
|
permissions:
|
|
39
52
|
contents: read
|
|
40
53
|
|
|
@@ -75,8 +88,9 @@ jobs:
|
|
|
75
88
|
- name: Install dependencies
|
|
76
89
|
run: __DOCOUTURE_INSTALL_CI__
|
|
77
90
|
|
|
78
|
-
# This is
|
|
79
|
-
# ever runs on a push to
|
|
91
|
+
# This is whichever branch triggered this run's own real
|
|
92
|
+
# antora-playbook.yml (this workflow only ever runs on a push to the
|
|
93
|
+
# prerelease or release branch, so there's no local/tag ambiguity to
|
|
80
94
|
# worry about the way docouture-release.yml's build step has) — see
|
|
81
95
|
# docouture-pr-verify.yml's own comment on the `kroki-enabled` attribute.
|
|
82
96
|
- name: Kroki / Detect enabled
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
name: docouture-publish-prerelease
|
|
2
2
|
|
|
3
|
-
# Rebuilds and republishes the prerelease (
|
|
4
|
-
# every ordinary push to
|
|
5
|
-
# docs/release label needed, unlike
|
|
6
|
-
# specifically so ordinary content merges
|
|
7
|
-
# fall back to docouture-publish.yml's own
|
|
3
|
+
# Rebuilds and republishes the prerelease (prerelease-branch) docs
|
|
4
|
+
# automatically on every ordinary push to the prerelease branch that
|
|
5
|
+
# actually touches content — no docs/release label needed, unlike
|
|
6
|
+
# docouture-release.yml. This exists specifically so ordinary content merges
|
|
7
|
+
# show up without anyone having to fall back to docouture-publish.yml's own
|
|
8
|
+
# workflow_dispatch every time.
|
|
8
9
|
#
|
|
9
|
-
# A plain `on: push: branches: [
|
|
10
|
-
# docouture-publish.yml and was removed for two reasons — see that
|
|
11
|
-
# header comment. Both are avoided here by construction rather
|
|
12
|
-
# reintroducing the same trigger in the same place:
|
|
10
|
+
# A plain `on: push: branches: [<prerelease branch>*]` used to live directly
|
|
11
|
+
# on docouture-publish.yml and was removed for two reasons — see that
|
|
12
|
+
# file's own header comment. Both are avoided here by construction rather
|
|
13
|
+
# than by reintroducing the same trigger in the same place:
|
|
13
14
|
#
|
|
14
15
|
# 1. An unrelated commit shouldn't kick off a rebuild with nothing new to
|
|
15
16
|
# publish. `check-changes-in-paths` (below) gates on real content paths
|
|
16
17
|
# only. In particular this deliberately excludes docs/.release-version:
|
|
17
18
|
# that file is the ONLY thing docouture-release.yml's own "Bump release
|
|
18
|
-
# descriptor" step pushes straight to
|
|
19
|
-
# workflow's own comment on that step) — a bot commit that is not
|
|
20
|
-
# docs content and
|
|
19
|
+
# descriptor" step pushes straight to the release branch directly (see
|
|
20
|
+
# that workflow's own comment on that step) — a bot commit that is not
|
|
21
|
+
# new docs content, and (trunk-based only, where prerelease and release
|
|
22
|
+
# are the same branch) would otherwise fire this workflow for nothing.
|
|
21
23
|
#
|
|
22
24
|
# 2. Firing twice for one release — once from a docs/release-labeled
|
|
23
25
|
# merge's own content, and again from docouture-release.yml's chained
|
|
@@ -29,10 +31,13 @@ name: docouture-publish-prerelease
|
|
|
29
31
|
# from a merged pull request carrying the docs/release label,
|
|
30
32
|
# docouture-release.yml is already about to publish the definitive
|
|
31
33
|
# post-release build itself, so this workflow skips rather than
|
|
32
|
-
# duplicate it.
|
|
34
|
+
# duplicate it. (Only reachable at all in a trunk-based site, where the
|
|
35
|
+
# prerelease and release branches are the same one — under git-flow
|
|
36
|
+
# they're different branches, so a docs/release-labeled PR never
|
|
37
|
+
# targets the prerelease branch this workflow watches.)
|
|
33
38
|
on:
|
|
34
39
|
push:
|
|
35
|
-
branches: ['
|
|
40
|
+
branches: ['__DOCOUTURE_PRERELEASE_BRANCH__*']
|
|
36
41
|
|
|
37
42
|
permissions:
|
|
38
43
|
contents: read
|
|
@@ -89,9 +94,9 @@ jobs:
|
|
|
89
94
|
# rebase) — GitHub tracks this association itself rather than this
|
|
90
95
|
# step having to guess from the SHA, see
|
|
91
96
|
# https://docs.github.com/en/rest/commits/commits#list-pull-requests-associated-with-a-commit.
|
|
92
|
-
# A direct push to
|
|
93
|
-
# pushing straight to
|
|
94
|
-
# skipped here.
|
|
97
|
+
# A direct push to the prerelease branch with no associated pull
|
|
98
|
+
# request (e.g. an admin pushing straight to it) simply resolves no
|
|
99
|
+
# labels and is never skipped here.
|
|
95
100
|
- name: Check for docs/release label
|
|
96
101
|
id: check
|
|
97
102
|
run: |
|
|
@@ -29,7 +29,7 @@ name: docouture-publish
|
|
|
29
29
|
# than a coincidence of two workflows independently reacting to the same
|
|
30
30
|
# git push. `workflow_call` is what makes that direct call possible.
|
|
31
31
|
# `workflow_dispatch` is kept alongside it for a manual rebuild+republish
|
|
32
|
-
# of whatever is currently
|
|
32
|
+
# of whatever is currently checked out, without cutting a new release.
|
|
33
33
|
on:
|
|
34
34
|
workflow_call: {}
|
|
35
35
|
workflow_dispatch: {}
|
|
@@ -21,7 +21,7 @@ name: docouture-release-preview
|
|
|
21
21
|
on:
|
|
22
22
|
pull_request:
|
|
23
23
|
types: [labeled, synchronize, ready_for_review, opened]
|
|
24
|
-
branches: ['
|
|
24
|
+
branches: ['__DOCOUTURE_RELEASE_BRANCH__*']
|
|
25
25
|
|
|
26
26
|
concurrency:
|
|
27
27
|
group: release-preview
|
|
@@ -66,7 +66,8 @@ jobs:
|
|
|
66
66
|
|
|
67
67
|
# Same signal docouture-release.yml's own "Detect mode" step reads:
|
|
68
68
|
# antora-playbook.yml's content.sources[] tags, not docs/antora.yml
|
|
69
|
-
# (identical on
|
|
69
|
+
# (identical on the release branch for both modes, so it carries no
|
|
70
|
+
# mode signal).
|
|
70
71
|
- name: Detect mode
|
|
71
72
|
id: detect
|
|
72
73
|
run: |
|