create-zudo-doc 5.9.0 → 5.11.0
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/CHANGELOG.md +11 -0
- package/README.md +9 -0
- package/dist/api.d.ts +2 -0
- package/dist/api.js +13 -2
- package/dist/claude-md-gen.js +3 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +16 -0
- package/dist/index.js +6 -0
- package/dist/preset.d.ts +14 -0
- package/dist/preset.js +54 -0
- package/dist/prompts.d.ts +3 -1
- package/dist/prompts.js +22 -0
- package/dist/scaffold.d.ts +1 -1
- package/dist/scaffold.js +92 -14
- package/dist/zfb-config-gen.js +20 -5
- package/package.json +3 -2
- package/templates/features/claudeSkills/files/.claude/skills/zudo-doc-version-bump/SKILL.md +121 -35
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `create-zudo-doc` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on Keep a Changelog, and release notes are generated from the changelog MDX pages.
|
|
6
|
+
|
|
7
|
+
## [5.11.0] - 2026-08-23
|
|
8
|
+
|
|
9
|
+
### Other Changes
|
|
10
|
+
|
|
11
|
+
- Updated newly generated projects to use the zfb 2.10.0 package family and the 5.11.0 zudo-doc package family. (`acaa01cf`)
|
package/README.md
CHANGED
|
@@ -20,6 +20,10 @@ bunx create-zudo-doc
|
|
|
20
20
|
|
|
21
21
|
Running without arguments starts the **interactive mode**: the CLI prompts for project name, language, color scheme, and which optional features to enable, then scaffolds the project and optionally installs dependencies.
|
|
22
22
|
|
|
23
|
+
Release history is shipped as `CHANGELOG.md` in the npm package. The file is
|
|
24
|
+
generated from the repository's changelog MDX pages; edit those source pages
|
|
25
|
+
instead of editing the generated markdown directly.
|
|
26
|
+
|
|
23
27
|
## Non-Interactive Usage
|
|
24
28
|
|
|
25
29
|
Pass `--yes` to accept all defaults and skip prompts, or provide flags to pre-answer specific questions:
|
|
@@ -91,6 +95,7 @@ Each feature has a `--[no-]<flag>` form. Passing `--feature` enables it; `--no-f
|
|
|
91
95
|
| `--[no-]footer-copyright` | Copyright notice in the footer | on |
|
|
92
96
|
| `--[no-]footer-taglist` | Grouped tag index in the footer (requires tag-governance) | off |
|
|
93
97
|
| `--[no-]changelog` | Changelog page | off |
|
|
98
|
+
| `--changelog-packages <a,b>` | Per-package changelog pages and a Changelog dropdown (implies `--changelog`) | none |
|
|
94
99
|
|
|
95
100
|
### Advanced
|
|
96
101
|
|
|
@@ -121,6 +126,9 @@ pnpm create zudo-doc my-docs \
|
|
|
121
126
|
|
|
122
127
|
# Fully featured site from a preset file
|
|
123
128
|
pnpm create zudo-doc my-docs --preset ./my-preset.json --install
|
|
129
|
+
|
|
130
|
+
# Per-package changelog pages
|
|
131
|
+
pnpm create zudo-doc my-docs --changelog-packages core,cli --yes
|
|
124
132
|
```
|
|
125
133
|
|
|
126
134
|
## Programmatic API
|
|
@@ -134,6 +142,7 @@ await createZudoDoc({
|
|
|
134
142
|
colorSchemeMode: "single",
|
|
135
143
|
singleScheme: "Default Dark",
|
|
136
144
|
features: ["search", "sidebarFilter", "tagGovernance"],
|
|
145
|
+
changelogPackages: ["core", "cli"],
|
|
137
146
|
packageManager: "pnpm",
|
|
138
147
|
install: true,
|
|
139
148
|
});
|
package/dist/api.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export interface CreateOptions {
|
|
|
13
13
|
/** Theme pack slug (ADR #2818 Decision 7), validated against THEME_PACKS. Default: "default". */
|
|
14
14
|
themePack?: string;
|
|
15
15
|
features: string[];
|
|
16
|
+
/** Package slugs for the nested changelog layout; implies `changelog`. */
|
|
17
|
+
changelogPackages?: string[];
|
|
16
18
|
/** GitHub repository URL — drives the header GitHub link and body-foot
|
|
17
19
|
* "View source on GitHub" link. Empty = disabled. */
|
|
18
20
|
githubUrl?: string;
|
package/dist/api.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import { SINGLE_SCHEMES, THEME_PACKS } from "./constants.js";
|
|
3
|
-
import { validateHeaderRightItems, validateMetaTags } from "./preset.js";
|
|
3
|
+
import { parseChangelogPackages, validateChangelogPackages, validateHeaderRightItems, validateMetaTags, } from "./preset.js";
|
|
4
4
|
import { scaffold } from "./scaffold.js";
|
|
5
5
|
import { initGitRepo, installDependencies, validateProjectName } from "./utils.js";
|
|
6
6
|
export async function createZudoDoc(options) {
|
|
@@ -45,7 +45,18 @@ export async function createZudoDoc(options) {
|
|
|
45
45
|
if (err)
|
|
46
46
|
throw new Error(err);
|
|
47
47
|
}
|
|
48
|
-
|
|
48
|
+
let changelogPackages = rest.changelogPackages;
|
|
49
|
+
if (changelogPackages !== undefined) {
|
|
50
|
+
const err = validateChangelogPackages(changelogPackages);
|
|
51
|
+
if (err)
|
|
52
|
+
throw new Error(err);
|
|
53
|
+
changelogPackages = parseChangelogPackages(changelogPackages);
|
|
54
|
+
}
|
|
55
|
+
const choices = {
|
|
56
|
+
...rest,
|
|
57
|
+
defaultLang: rest.defaultLang ?? "en",
|
|
58
|
+
changelogPackages,
|
|
59
|
+
};
|
|
49
60
|
await scaffold(choices);
|
|
50
61
|
const targetDir = path.resolve(process.cwd(), choices.projectName);
|
|
51
62
|
if (install) {
|
package/dist/claude-md-gen.js
CHANGED
|
@@ -128,7 +128,9 @@ export function generateCLAUDEFile(choices) {
|
|
|
128
128
|
llmsTxt: "Generates llms.txt for LLM consumption",
|
|
129
129
|
claudeResources: "Auto-generated docs for Claude Code resources",
|
|
130
130
|
codexResources: "Auto-generated docs for Codex resources (.codex/, AGENTS.md)",
|
|
131
|
-
changelog:
|
|
131
|
+
changelog: choices.changelogPackages && choices.changelogPackages.length > 0
|
|
132
|
+
? `Changelog pages at \`/docs/changelog/<slug>\` — one per package: ${choices.changelogPackages.join(", ")}`
|
|
133
|
+
: "Changelog page at `/docs/changelog`",
|
|
132
134
|
tauri: "Desktop app wrapper (`cargo tauri dev` / `cargo tauri build`) — Cmd/Ctrl+F find bar via the package-owned `FindInPageInit` island (`findInPage: true` in `zfb.config.ts`)",
|
|
133
135
|
tagGovernance: "Vocabulary-aware tag audit (`tags:audit`) / suggest (`tags:suggest`) scripts",
|
|
134
136
|
};
|
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import minimist from "minimist";
|
|
2
2
|
import pc from "picocolors";
|
|
3
3
|
import { FEATURES, SINGLE_SCHEMES, SUPPORTED_LANGS, THEME_PACKS } from "./constants.js";
|
|
4
|
+
import { parseChangelogPackages, validateChangelogPackages, } from "./preset.js";
|
|
4
5
|
import { validateProjectName } from "./utils.js";
|
|
5
6
|
export function parseArgs(argv = process.argv.slice(2)) {
|
|
6
7
|
const raw = minimist(argv, {
|
|
@@ -13,6 +14,7 @@ export function parseArgs(argv = process.argv.slice(2)) {
|
|
|
13
14
|
"dark-scheme",
|
|
14
15
|
"default-mode",
|
|
15
16
|
"theme-pack",
|
|
17
|
+
"changelog-packages",
|
|
16
18
|
"github-url",
|
|
17
19
|
"preset",
|
|
18
20
|
"pm",
|
|
@@ -52,6 +54,11 @@ export function parseArgs(argv = process.argv.slice(2)) {
|
|
|
52
54
|
args.defaultMode = raw["default-mode"];
|
|
53
55
|
if (raw["theme-pack"])
|
|
54
56
|
args.themePack = raw["theme-pack"];
|
|
57
|
+
if (raw["changelog-packages"] !== undefined) {
|
|
58
|
+
args.changelogPackages = parseChangelogPackages(typeof raw["changelog-packages"] === "string"
|
|
59
|
+
? raw["changelog-packages"]
|
|
60
|
+
: String(raw["changelog-packages"] ?? ""));
|
|
61
|
+
}
|
|
55
62
|
if (raw.preset)
|
|
56
63
|
args.preset = raw.preset;
|
|
57
64
|
if (raw.pm)
|
|
@@ -99,6 +106,7 @@ ${pc.bold("Options:")}
|
|
|
99
106
|
--theme-pack <slug> Theme pack (${themePackList})
|
|
100
107
|
Default: default
|
|
101
108
|
${featureHelp}
|
|
109
|
+
--changelog-packages <a,b> Per-package changelog pages (implies changelog)
|
|
102
110
|
--github-url <url> GitHub repository URL (drives header link + source link)
|
|
103
111
|
--preset <path> Load settings from a JSON preset file (use "-" for stdin)
|
|
104
112
|
--pm <manager> pnpm | npm | yarn | bun
|
|
@@ -117,6 +125,9 @@ ${pc.bold("Examples:")}
|
|
|
117
125
|
|
|
118
126
|
${pc.dim("# Fully specified")}
|
|
119
127
|
create-zudo-doc my-docs --lang ja --scheme "Default Dark" --no-i18n --pm pnpm --install
|
|
128
|
+
|
|
129
|
+
${pc.dim("# Per-package changelog pages")}
|
|
130
|
+
create-zudo-doc my-docs --changelog-packages core,cli --yes
|
|
120
131
|
`);
|
|
121
132
|
}
|
|
122
133
|
export function validateArgs(args) {
|
|
@@ -148,6 +159,11 @@ export function validateArgs(args) {
|
|
|
148
159
|
if (args.pm && !["pnpm", "npm", "yarn", "bun"].includes(args.pm)) {
|
|
149
160
|
return `Invalid package manager "${args.pm}". Must be pnpm, npm, yarn, or bun`;
|
|
150
161
|
}
|
|
162
|
+
if (args.changelogPackages !== undefined) {
|
|
163
|
+
const changelogError = validateChangelogPackages(args.changelogPackages);
|
|
164
|
+
if (changelogError)
|
|
165
|
+
return changelogError;
|
|
166
|
+
}
|
|
151
167
|
// Validate scheme combinations
|
|
152
168
|
if (args.colorSchemeMode === "single" && (args.lightScheme || args.darkScheme)) {
|
|
153
169
|
return `--light-scheme and --dark-scheme are only valid with --color-scheme-mode light-dark`;
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,9 @@ async function main() {
|
|
|
61
61
|
prefilled.packageManager = args.pm;
|
|
62
62
|
if (args.githubUrl !== undefined)
|
|
63
63
|
prefilled.githubUrl = args.githubUrl;
|
|
64
|
+
if (args.changelogPackages !== undefined) {
|
|
65
|
+
prefilled.changelogPackages = args.changelogPackages;
|
|
66
|
+
}
|
|
64
67
|
// Build feature overrides from explicit flags — driven by FEATURES constant
|
|
65
68
|
const featureFlags = {};
|
|
66
69
|
for (const f of FEATURES) {
|
|
@@ -96,6 +99,9 @@ async function main() {
|
|
|
96
99
|
prefilled.themePack ??= "default";
|
|
97
100
|
prefilled.packageManager ??= "pnpm";
|
|
98
101
|
prefilled.githubUrl ??= "";
|
|
102
|
+
// A blank package list is the explicit non-interactive choice for the
|
|
103
|
+
// existing single-page changelog. A non-empty CLI/preset list above wins.
|
|
104
|
+
prefilled.changelogPackages ??= [];
|
|
99
105
|
// For features: set defaults for any not explicitly specified
|
|
100
106
|
const featureDefaults = {};
|
|
101
107
|
for (const f of FEATURES) {
|
package/dist/preset.d.ts
CHANGED
|
@@ -26,6 +26,18 @@ export interface PresetMetaTagsConfig {
|
|
|
26
26
|
twitterSite?: string;
|
|
27
27
|
twitterCreator?: string;
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse the comma-separated CLI form (or normalize the array form used by
|
|
31
|
+
* presets and the programmatic API). Empty entries are ignored so a trailing
|
|
32
|
+
* comma is harmless; validation below still rejects an entirely empty list.
|
|
33
|
+
*/
|
|
34
|
+
export declare function parseChangelogPackages(value: string | readonly string[]): string[];
|
|
35
|
+
/**
|
|
36
|
+
* Shared changelog-package validation for CLI, JSON presets, and the
|
|
37
|
+
* programmatic API. Keeping this next to the parser prevents the three entry
|
|
38
|
+
* points from accepting different slug grammars or duplicate lists.
|
|
39
|
+
*/
|
|
40
|
+
export declare function validateChangelogPackages(list: unknown): string | null;
|
|
29
41
|
/**
|
|
30
42
|
* Validates a `headerRightItems` value against the v1 preset allowlist.
|
|
31
43
|
* Shared by `validatePreset()` (JSON preset path) and `createZudoDoc()`
|
|
@@ -50,6 +62,8 @@ export interface PresetJson {
|
|
|
50
62
|
/** Theme pack slug (ADR #2818 Decision 7), validated against THEME_PACKS. */
|
|
51
63
|
themePack?: string;
|
|
52
64
|
features?: string[];
|
|
65
|
+
/** Package slugs for the nested changelog layout. */
|
|
66
|
+
changelogPackages?: string[];
|
|
53
67
|
githubUrl?: string;
|
|
54
68
|
cjkFriendly?: boolean;
|
|
55
69
|
minifyHtml?: boolean;
|
package/dist/preset.js
CHANGED
|
@@ -12,6 +12,46 @@ const VALID_HEADER_RIGHT_TRIGGERS = new Set([
|
|
|
12
12
|
"design-token-panel",
|
|
13
13
|
"ai-chat",
|
|
14
14
|
]);
|
|
15
|
+
const CHANGELOG_PACKAGE_SLUG_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
16
|
+
/**
|
|
17
|
+
* Parse the comma-separated CLI form (or normalize the array form used by
|
|
18
|
+
* presets and the programmatic API). Empty entries are ignored so a trailing
|
|
19
|
+
* comma is harmless; validation below still rejects an entirely empty list.
|
|
20
|
+
*/
|
|
21
|
+
export function parseChangelogPackages(value) {
|
|
22
|
+
const values = typeof value === "string" ? value.split(",") : value;
|
|
23
|
+
return values.map((slug) => slug.trim()).filter(Boolean);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Shared changelog-package validation for CLI, JSON presets, and the
|
|
27
|
+
* programmatic API. Keeping this next to the parser prevents the three entry
|
|
28
|
+
* points from accepting different slug grammars or duplicate lists.
|
|
29
|
+
*/
|
|
30
|
+
export function validateChangelogPackages(list) {
|
|
31
|
+
if (!Array.isArray(list)) {
|
|
32
|
+
return `"changelogPackages" must be an array`;
|
|
33
|
+
}
|
|
34
|
+
for (let i = 0; i < list.length; i++) {
|
|
35
|
+
if (typeof list[i] !== "string") {
|
|
36
|
+
return `changelogPackages[${i}] must be a string`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const packages = parseChangelogPackages(list);
|
|
40
|
+
if (packages.length === 0) {
|
|
41
|
+
return `"changelogPackages" must contain at least one package`;
|
|
42
|
+
}
|
|
43
|
+
const seen = new Set();
|
|
44
|
+
for (const slug of packages) {
|
|
45
|
+
if (!CHANGELOG_PACKAGE_SLUG_RE.test(slug)) {
|
|
46
|
+
return `Invalid changelog package slug "${slug}". Slugs must match /^[a-z0-9][a-z0-9-]*$/`;
|
|
47
|
+
}
|
|
48
|
+
if (seen.has(slug)) {
|
|
49
|
+
return `Duplicate changelog package "${slug}"`;
|
|
50
|
+
}
|
|
51
|
+
seen.add(slug);
|
|
52
|
+
}
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
15
55
|
/**
|
|
16
56
|
* Validates a `headerRightItems` value against the v1 preset allowlist.
|
|
17
57
|
* Shared by `validatePreset()` (JSON preset path) and `createZudoDoc()`
|
|
@@ -131,6 +171,17 @@ export function validatePreset(json) {
|
|
|
131
171
|
if (p.features !== undefined && !Array.isArray(p.features)) {
|
|
132
172
|
return `"features" must be an array in preset`;
|
|
133
173
|
}
|
|
174
|
+
if (p.changelogPackages !== undefined) {
|
|
175
|
+
if (!Array.isArray(p.changelogPackages)) {
|
|
176
|
+
return `"changelogPackages" must be an array in preset`;
|
|
177
|
+
}
|
|
178
|
+
const changelogPackages = p.changelogPackages.every((slug) => typeof slug === "string")
|
|
179
|
+
? parseChangelogPackages(p.changelogPackages)
|
|
180
|
+
: p.changelogPackages;
|
|
181
|
+
const err = validateChangelogPackages(changelogPackages);
|
|
182
|
+
if (err)
|
|
183
|
+
return err;
|
|
184
|
+
}
|
|
134
185
|
if (p.defaultLang && !VALID_LANGS.has(p.defaultLang)) {
|
|
135
186
|
return `Invalid language "${p.defaultLang}" in preset`;
|
|
136
187
|
}
|
|
@@ -215,6 +266,9 @@ export function presetToChoices(json) {
|
|
|
215
266
|
choices.cjkFriendly = json.cjkFriendly;
|
|
216
267
|
if (json.minifyHtml !== undefined)
|
|
217
268
|
choices.minifyHtml = json.minifyHtml;
|
|
269
|
+
if (json.changelogPackages !== undefined) {
|
|
270
|
+
choices.changelogPackages = parseChangelogPackages(json.changelogPackages);
|
|
271
|
+
}
|
|
218
272
|
if (json.headerRightItems !== undefined) {
|
|
219
273
|
choices.headerRightItems = json.headerRightItems;
|
|
220
274
|
}
|
package/dist/prompts.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PresetHeaderRightItem, type PresetMetaTagsConfig } from "./preset.js";
|
|
2
2
|
export interface UserChoices {
|
|
3
3
|
projectName: string;
|
|
4
4
|
defaultLang: string;
|
|
@@ -10,6 +10,7 @@ export interface UserChoices {
|
|
|
10
10
|
defaultMode?: "light" | "dark";
|
|
11
11
|
themePack?: string;
|
|
12
12
|
features: string[];
|
|
13
|
+
changelogPackages?: string[];
|
|
13
14
|
explicitlyDisabledFeatures?: string[];
|
|
14
15
|
githubUrl?: string;
|
|
15
16
|
cjkFriendly?: boolean;
|
|
@@ -29,6 +30,7 @@ export interface PartialChoices {
|
|
|
29
30
|
defaultMode?: "light" | "dark";
|
|
30
31
|
themePack?: string;
|
|
31
32
|
features?: Partial<Record<string, boolean>>;
|
|
33
|
+
changelogPackages?: string[];
|
|
32
34
|
explicitlyDisabledFeatures?: string[];
|
|
33
35
|
githubUrl?: string;
|
|
34
36
|
cjkFriendly?: boolean;
|
package/dist/prompts.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as p from "@clack/prompts";
|
|
2
2
|
import { SINGLE_SCHEMES, FEATURES, SUPPORTED_LANGS, THEME_PACKS } from "./constants.js";
|
|
3
|
+
import { parseChangelogPackages, validateChangelogPackages, } from "./preset.js";
|
|
3
4
|
import { validateProjectName } from "./utils.js";
|
|
4
5
|
export async function runPrompts(prefilled = {}) {
|
|
5
6
|
// 1. Project name
|
|
@@ -170,6 +171,26 @@ export async function runPrompts(prefilled = {}) {
|
|
|
170
171
|
process.exit(0);
|
|
171
172
|
features = result;
|
|
172
173
|
}
|
|
174
|
+
// 4.5 Changelog package layout. A blank answer deliberately preserves the
|
|
175
|
+
// existing single-page starter. CLI/preset/--yes callers prefill this value
|
|
176
|
+
// so they remain non-interactive.
|
|
177
|
+
let changelogPackages = prefilled.changelogPackages;
|
|
178
|
+
if (features.includes("changelog") && changelogPackages === undefined) {
|
|
179
|
+
const result = await p.text({
|
|
180
|
+
message: "Package changelogs (comma-separated slugs; leave empty for a single changelog):",
|
|
181
|
+
placeholder: "core,cli",
|
|
182
|
+
defaultValue: "",
|
|
183
|
+
validate(value) {
|
|
184
|
+
if (!value.trim())
|
|
185
|
+
return;
|
|
186
|
+
const parsed = parseChangelogPackages(value);
|
|
187
|
+
return validateChangelogPackages(parsed) ?? undefined;
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
if (p.isCancel(result))
|
|
191
|
+
process.exit(0);
|
|
192
|
+
changelogPackages = parseChangelogPackages(result);
|
|
193
|
+
}
|
|
173
194
|
// 5. GitHub URL (drives header GitHub icon + view-source link)
|
|
174
195
|
let githubUrl = prefilled.githubUrl;
|
|
175
196
|
if (githubUrl === undefined) {
|
|
@@ -218,6 +239,7 @@ export async function runPrompts(prefilled = {}) {
|
|
|
218
239
|
defaultMode,
|
|
219
240
|
themePack,
|
|
220
241
|
features,
|
|
242
|
+
changelogPackages,
|
|
221
243
|
explicitlyDisabledFeatures: prefilled.explicitlyDisabledFeatures,
|
|
222
244
|
githubUrl,
|
|
223
245
|
cjkFriendly: prefilled.cjkFriendly,
|
package/dist/scaffold.d.ts
CHANGED
|
@@ -32,5 +32,5 @@ export declare function deriveDocSkillName(projectName: string): string;
|
|
|
32
32
|
*
|
|
33
33
|
* Bumped in lockstep by scripts/release-create-zudo-doc.sh.
|
|
34
34
|
*/
|
|
35
|
-
export declare const ZUDO_DOC_PIN = "^5.
|
|
35
|
+
export declare const ZUDO_DOC_PIN = "^5.11.0";
|
|
36
36
|
export declare function scaffold(choices: UserChoices): Promise<void>;
|
package/dist/scaffold.js
CHANGED
|
@@ -43,7 +43,7 @@ export function deriveDocSkillName(projectName) {
|
|
|
43
43
|
*
|
|
44
44
|
* Bumped in lockstep by scripts/release-create-zudo-doc.sh.
|
|
45
45
|
*/
|
|
46
|
-
export const ZUDO_DOC_PIN = "^5.
|
|
46
|
+
export const ZUDO_DOC_PIN = "^5.11.0";
|
|
47
47
|
/**
|
|
48
48
|
* Files in `templates/base/**` that must not be copied by the unconditional
|
|
49
49
|
* base mirror. Each entry is matched against the path relative to
|
|
@@ -186,8 +186,6 @@ title: Changelog
|
|
|
186
186
|
sidebar_position: 99
|
|
187
187
|
---
|
|
188
188
|
|
|
189
|
-
# Changelog
|
|
190
|
-
|
|
191
189
|
## Unreleased
|
|
192
190
|
|
|
193
191
|
- Initial release
|
|
@@ -197,7 +195,45 @@ title: 変更履歴
|
|
|
197
195
|
sidebar_position: 99
|
|
198
196
|
---
|
|
199
197
|
|
|
200
|
-
|
|
198
|
+
## 未リリース
|
|
199
|
+
|
|
200
|
+
- 初回リリース
|
|
201
|
+
`;
|
|
202
|
+
const CHANGELOG_LANDING_CONTENT_EN = () => `---
|
|
203
|
+
title: Changelog
|
|
204
|
+
description: Release notes for each package.
|
|
205
|
+
sidebar_position: 99
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
Release notes for each package.
|
|
209
|
+
|
|
210
|
+
<CategoryNav category="changelog" />
|
|
211
|
+
`;
|
|
212
|
+
const CHANGELOG_LANDING_CONTENT_JA = () => `---
|
|
213
|
+
title: 変更履歴
|
|
214
|
+
description: パッケージごとのリリースノート。
|
|
215
|
+
sidebar_position: 99
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
パッケージごとのリリースノート。
|
|
219
|
+
|
|
220
|
+
<CategoryNav category="changelog" />
|
|
221
|
+
`;
|
|
222
|
+
const CHANGELOG_PACKAGE_CONTENT_EN = (slug, position) => `---
|
|
223
|
+
title: "${slug}"
|
|
224
|
+
description: Release notes for ${slug}.
|
|
225
|
+
sidebar_position: ${position}
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Unreleased
|
|
229
|
+
|
|
230
|
+
- Initial release
|
|
231
|
+
`;
|
|
232
|
+
const CHANGELOG_PACKAGE_CONTENT_JA = (slug, position) => `---
|
|
233
|
+
title: "${slug}"
|
|
234
|
+
description: ${slug} のリリースノート。
|
|
235
|
+
sidebar_position: ${position}
|
|
236
|
+
---
|
|
201
237
|
|
|
202
238
|
## 未リリース
|
|
203
239
|
|
|
@@ -222,6 +258,16 @@ export async function scaffold(choices) {
|
|
|
222
258
|
}
|
|
223
259
|
choices.features = [...choices.features, "docHistory"];
|
|
224
260
|
}
|
|
261
|
+
// A non-empty package list implies the changelog feature. Warn when the
|
|
262
|
+
// CLI explicitly disabled it, then honor the package-layout request.
|
|
263
|
+
if (choices.changelogPackages !== undefined &&
|
|
264
|
+
choices.changelogPackages.length > 0 &&
|
|
265
|
+
!choices.features.includes("changelog")) {
|
|
266
|
+
if (choices.explicitlyDisabledFeatures?.includes("changelog")) {
|
|
267
|
+
console.warn("changelog-packages requires changelog; enabling it despite --no-changelog");
|
|
268
|
+
}
|
|
269
|
+
choices.features = [...choices.features, "changelog"];
|
|
270
|
+
}
|
|
225
271
|
// Resolve template directories
|
|
226
272
|
const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
227
273
|
const templatesDir = path.join(pkgRoot, "templates");
|
|
@@ -324,14 +370,44 @@ export async function scaffold(choices) {
|
|
|
324
370
|
}
|
|
325
371
|
// When changelog is ON, create a starter changelog page
|
|
326
372
|
if (choices.features.includes("changelog")) {
|
|
327
|
-
const
|
|
328
|
-
|
|
373
|
+
const packageSlugs = choices.changelogPackages ?? [];
|
|
374
|
+
if (packageSlugs.length === 0) {
|
|
375
|
+
const changelogContent = defaultLang === "ja" ? CHANGELOG_CONTENT_JA() : CHANGELOG_CONTENT_EN();
|
|
376
|
+
await fs.outputFile(path.join(targetDir, "src/content/docs/changelog/index.mdx"), changelogContent);
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
const landingContent = defaultLang === "ja"
|
|
380
|
+
? CHANGELOG_LANDING_CONTENT_JA()
|
|
381
|
+
: CHANGELOG_LANDING_CONTENT_EN();
|
|
382
|
+
await fs.outputFile(path.join(targetDir, "src/content/docs/changelog/index.mdx"), landingContent);
|
|
383
|
+
for (const [index, slug] of packageSlugs.entries()) {
|
|
384
|
+
const packageContent = defaultLang === "ja"
|
|
385
|
+
? CHANGELOG_PACKAGE_CONTENT_JA(slug, index + 1)
|
|
386
|
+
: CHANGELOG_PACKAGE_CONTENT_EN(slug, index + 1);
|
|
387
|
+
await fs.outputFile(path.join(targetDir, `src/content/docs/changelog/${slug}/index.mdx`), packageContent);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
329
390
|
if (choices.features.includes("i18n")) {
|
|
330
391
|
const secondaryLang = getSecondaryLang(defaultLang);
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
392
|
+
if (packageSlugs.length === 0) {
|
|
393
|
+
const secondaryChangelogContent = secondaryLang === "ja"
|
|
394
|
+
? CHANGELOG_CONTENT_JA()
|
|
395
|
+
: CHANGELOG_CONTENT_EN();
|
|
396
|
+
await fs.outputFile(path.join(targetDir, `src/content/docs-${secondaryLang}/changelog/index.mdx`), secondaryChangelogContent);
|
|
397
|
+
}
|
|
398
|
+
else {
|
|
399
|
+
const secondaryLandingContent = secondaryLang === "ja"
|
|
400
|
+
? CHANGELOG_LANDING_CONTENT_JA()
|
|
401
|
+
: CHANGELOG_LANDING_CONTENT_EN();
|
|
402
|
+
const secondaryDir = `src/content/docs-${secondaryLang}/changelog`;
|
|
403
|
+
await fs.outputFile(path.join(targetDir, `${secondaryDir}/index.mdx`), secondaryLandingContent);
|
|
404
|
+
for (const [index, slug] of packageSlugs.entries()) {
|
|
405
|
+
const secondaryPackageContent = secondaryLang === "ja"
|
|
406
|
+
? CHANGELOG_PACKAGE_CONTENT_JA(slug, index + 1)
|
|
407
|
+
: CHANGELOG_PACKAGE_CONTENT_EN(slug, index + 1);
|
|
408
|
+
await fs.outputFile(path.join(targetDir, `${secondaryDir}/${slug}/index.mdx`), secondaryPackageContent);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
335
411
|
}
|
|
336
412
|
}
|
|
337
413
|
// 3. Generate the one config file. There is no more src/config/settings.ts —
|
|
@@ -624,9 +700,11 @@ function generatePackageJson(choices) {
|
|
|
624
700
|
// default, so a fresh scaffold needs no config change to pick it up.
|
|
625
701
|
// Also fixes the client router to tolerate about:srcdoc history
|
|
626
702
|
// restrictions. No generator-side migration.
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
"@takazudo/zfb
|
|
703
|
+
// 2.10.0: routine toolchain bump from 2.9.0, adopted in lockstep with the
|
|
704
|
+
// root package.json pins. No generator-side migration.
|
|
705
|
+
"@takazudo/zfb": "2.10.0",
|
|
706
|
+
"@takazudo/zfb-runtime": "2.10.0",
|
|
707
|
+
"@takazudo/zfb-md-wasm": "2.10.0",
|
|
630
708
|
// @takazudo/zudo-doc — published from this monorepo via
|
|
631
709
|
// .github/workflows/publish-zudo-doc.yml. The pin here is bumped in
|
|
632
710
|
// lockstep by scripts/release-create-zudo-doc.sh whenever zudo-doc's
|
|
@@ -748,7 +826,7 @@ function generatePackageJson(choices) {
|
|
|
748
826
|
// `/exclude` at module scope from the always-bundled chrome graph; #3110
|
|
749
827
|
// moved compileExclude into @takazudo/zudo-doc, so docHistory-OFF projects
|
|
750
828
|
// no longer need the package at all.
|
|
751
|
-
deps["@takazudo/zudo-doc-history-server"] = "^5.
|
|
829
|
+
deps["@takazudo/zudo-doc-history-server"] = "^5.11.0";
|
|
752
830
|
// tsx is no longer needed here: the relocated package plugin imports the
|
|
753
831
|
// runner directly (no `tsx -e` spawn) since the package ships compiled
|
|
754
832
|
// dist/ — package-first migration #2321 (#2337).
|
package/dist/zfb-config-gen.js
CHANGED
|
@@ -309,11 +309,26 @@ function buildDesiredConfig(choices) {
|
|
|
309
309
|
});
|
|
310
310
|
}
|
|
311
311
|
if (choices.features.includes("changelog")) {
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
312
|
+
if (choices.changelogPackages && choices.changelogPackages.length > 0) {
|
|
313
|
+
headerNav.push({
|
|
314
|
+
label: "Changelog",
|
|
315
|
+
path: "/docs/changelog",
|
|
316
|
+
categoryMatch: "changelog",
|
|
317
|
+
// nav-scope matches the first slug segment only; nested children
|
|
318
|
+
// highlight by path and must not carry a multi-segment categoryMatch.
|
|
319
|
+
children: choices.changelogPackages.map((slug) => ({
|
|
320
|
+
label: slug,
|
|
321
|
+
path: `/docs/changelog/${slug}`,
|
|
322
|
+
})),
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
headerNav.push({
|
|
327
|
+
label: "Changelog",
|
|
328
|
+
path: "/docs/changelog",
|
|
329
|
+
categoryMatch: "changelog",
|
|
330
|
+
});
|
|
331
|
+
}
|
|
317
332
|
}
|
|
318
333
|
desired.headerNav = headerNav;
|
|
319
334
|
if (choices.headerRightItems !== undefined) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-zudo-doc",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.11.0",
|
|
4
4
|
"description": "Create a new zudo-doc documentation site",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Takeshi Takatsudo",
|
|
@@ -40,7 +40,8 @@
|
|
|
40
40
|
"bin",
|
|
41
41
|
"dist",
|
|
42
42
|
"templates",
|
|
43
|
-
"!dist/__tests__"
|
|
43
|
+
"!dist/__tests__",
|
|
44
|
+
"CHANGELOG.md"
|
|
44
45
|
],
|
|
45
46
|
"scripts": {
|
|
46
47
|
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
@@ -103,32 +103,61 @@ which package manager (`<pm>`) the project otherwise uses. `--no-git-tag-version
|
|
|
103
103
|
also creating a commit/tag — this skill handles that later, once everything else is ready. A
|
|
104
104
|
direct edit of the `"version"` field in `package.json` works identically if preferred.
|
|
105
105
|
|
|
106
|
+
The project has **one root version**. All packages represented in a multi-package changelog move
|
|
107
|
+
to `{NEW_VERSION}` in lockstep; independent per-package versions are out of scope for this skill.
|
|
108
|
+
|
|
106
109
|
## Update the changelog (if enabled)
|
|
107
110
|
|
|
108
|
-
|
|
111
|
+
First check whether the default-language changelog exists:
|
|
109
112
|
|
|
110
113
|
```bash
|
|
111
114
|
test -f src/content/docs/changelog/index.mdx && echo "changelog present"
|
|
112
115
|
```
|
|
113
116
|
|
|
114
|
-
If
|
|
115
|
-
go straight to "Archive docs as a versioned snapshot".
|
|
117
|
+
If `src/content/docs/changelog/index.mdx` does not exist, the changelog feature is not in use —
|
|
118
|
+
skip this whole section and go straight to "Archive docs as a versioned snapshot".
|
|
116
119
|
|
|
117
|
-
|
|
118
|
-
release as a section **above** the existing ones (newest first), using only the categories that
|
|
119
|
-
have entries.
|
|
120
|
+
### Discover package and page layouts
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
Treat `src/content/docs/changelog/` as the primary changelog root. List every immediate child
|
|
123
|
+
directory that contains an `index.mdx`; each directory name is a package slug:
|
|
122
124
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
```bash
|
|
126
|
+
find src/content/docs/changelog -mindepth 2 -maxdepth 2 -type f -name index.mdx \
|
|
127
|
+
-print | sed 's#/index\.mdx$##; s#.*/##' | sort
|
|
128
|
+
```
|
|
126
129
|
|
|
127
|
-
|
|
130
|
+
Then follow exactly one branch:
|
|
128
131
|
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
1. **One or more package directories:** the root `index.mdx` is a landing page and must never be
|
|
133
|
+
edited. Show the package slugs to the user and ask which packages this release touches. Default
|
|
134
|
+
to **all packages**; accept a comma-separated list. Reject names that are not in the discovered
|
|
135
|
+
list. Apply the per-directory procedure below to each selected package directory.
|
|
136
|
+
2. **No package directories:** apply the per-directory procedure to the changelog root itself.
|
|
137
|
+
|
|
138
|
+
For every selected directory, detect its layout independently, before making changes:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
find "<changelog-directory>" -maxdepth 1 -type f -name '*.mdx' ! -name index.mdx \
|
|
142
|
+
-print -quit
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- Any output means **per-version-file layout**. Create a new version file; never insert a version
|
|
146
|
+
section into that directory's `index.mdx`.
|
|
147
|
+
- No output means **single-page layout**. Edit that directory's `index.mdx` using the existing
|
|
148
|
+
section procedure.
|
|
149
|
+
|
|
150
|
+
This per-directory check is mandatory: packages in one project may use different layouts.
|
|
151
|
+
|
|
152
|
+
### Choose the language-specific headings
|
|
153
|
+
|
|
154
|
+
The primary content directory was seeded in the project's `defaultLang`, so do not assume it is
|
|
155
|
+
English. For a single-page directory, inspect its `index.mdx`. For a per-version-file directory,
|
|
156
|
+
inspect its existing sibling version entries. Use the heading set already used by those files.
|
|
131
157
|
|
|
158
|
+
**English heading set:**
|
|
159
|
+
|
|
160
|
+
```mdx
|
|
132
161
|
### Breaking Changes
|
|
133
162
|
|
|
134
163
|
- Description (commit-hash)
|
|
@@ -146,14 +175,9 @@ assume English.
|
|
|
146
175
|
- Description (commit-hash)
|
|
147
176
|
```
|
|
148
177
|
|
|
149
|
-
|
|
150
|
-
replace that heading with `## {NEW_VERSION}` rather than adding a second heading.
|
|
151
|
-
|
|
152
|
-
**If the page uses Japanese headings:**
|
|
178
|
+
**Japanese heading set:**
|
|
153
179
|
|
|
154
180
|
```mdx
|
|
155
|
-
## {NEW_VERSION}
|
|
156
|
-
|
|
157
181
|
### 破壊的変更
|
|
158
182
|
|
|
159
183
|
- Description (commit-hash)
|
|
@@ -171,8 +195,44 @@ replace that heading with `## {NEW_VERSION}` rather than adding a second heading
|
|
|
171
195
|
- Description (commit-hash)
|
|
172
196
|
```
|
|
173
197
|
|
|
174
|
-
|
|
175
|
-
|
|
198
|
+
In either language, include only categories that have entries. Each entry is the commit subject
|
|
199
|
+
with its short hash in parentheses.
|
|
200
|
+
|
|
201
|
+
### Update a single-page directory
|
|
202
|
+
|
|
203
|
+
Add this release above all existing release sections in the directory's `index.mdx` (newest
|
|
204
|
+
first):
|
|
205
|
+
|
|
206
|
+
```mdx
|
|
207
|
+
## {NEW_VERSION}
|
|
208
|
+
|
|
209
|
+
<!-- categories and entries from the matching heading set above -->
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
On the first bump, replace the starter `## Unreleased` or `## 未リリース` heading with
|
|
213
|
+
`## {NEW_VERSION}` instead of adding a second release heading.
|
|
214
|
+
|
|
215
|
+
### Update a per-version-file directory
|
|
216
|
+
|
|
217
|
+
Create `<changelog-directory>/<version>.mdx`, where `<version>` is `{NEW_VERSION}` without a
|
|
218
|
+
leading `v`. Never section-edit this directory's `index.mdx`. Determine the greatest numeric
|
|
219
|
+
`sidebar_position` in the existing sibling version files and use that value plus one. The new file
|
|
220
|
+
must have localized frontmatter and body text matching its siblings, in this shape:
|
|
221
|
+
|
|
222
|
+
```mdx
|
|
223
|
+
---
|
|
224
|
+
title: "{NEW_VERSION}"
|
|
225
|
+
description: Release notes for {NEW_VERSION}.
|
|
226
|
+
sidebar_position: {MAX_EXISTING_PLUS_ONE}
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
Released: {YYYY-MM-DD}
|
|
230
|
+
|
|
231
|
+
<!-- categories and entries from the matching heading set above -->
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Use a concise Japanese `description` when the sibling entries are Japanese, but keep the required
|
|
235
|
+
`Released: {YYYY-MM-DD}` line in either language. Use today's date for `{YYYY-MM-DD}`.
|
|
176
236
|
|
|
177
237
|
### Other-locale changelog
|
|
178
238
|
|
|
@@ -180,17 +240,13 @@ Only applies when i18n is enabled — i.e. a second content directory exists alo
|
|
|
180
240
|
one. Which locale that is depends on the project's `defaultLang`: for an English-default project
|
|
181
241
|
this is the Japanese changelog at `src/content/docs-ja/changelog/index.mdx`; for a
|
|
182
242
|
Japanese-default project this is the English changelog under the `docs-en` directory instead. If
|
|
183
|
-
the other-locale changelog
|
|
184
|
-
|
|
185
|
-
Use the OTHER heading set from above (the one you didn't use for the default-language page —
|
|
186
|
-
English primary means Japanese secondary, and vice versa), following the same "add a new
|
|
187
|
-
`## {NEW_VERSION}` section above the existing ones" rule, and replace that page's own starter
|
|
188
|
-
heading on the very first bump.
|
|
243
|
+
the other-locale changelog root doesn't exist, skip mirroring.
|
|
189
244
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
|
|
245
|
+
Mirror exactly the selected primary targets by relative path under the other-locale root, detect
|
|
246
|
+
each mirror directory's layout independently, and apply the matching single-page or
|
|
247
|
+
per-version-file procedure. Use the other language's heading set. In a multi-package layout,
|
|
248
|
+
never edit either locale's landing `changelog/index.mdx`. If a selected package has no matching
|
|
249
|
+
other-locale directory, report it and stop instead of silently creating a divergent layout.
|
|
194
250
|
|
|
195
251
|
## Archive docs as a versioned snapshot (if enabled, major bumps only)
|
|
196
252
|
|
|
@@ -253,7 +309,7 @@ Stage and commit **all** version bump changes:
|
|
|
253
309
|
|
|
254
310
|
```bash
|
|
255
311
|
git add package.json
|
|
256
|
-
git add src/content/docs
|
|
312
|
+
git add src/content/docs*/changelog/ 2>/dev/null
|
|
257
313
|
git add src/content/docs-v* 2>/dev/null
|
|
258
314
|
# Also stage any other modified files (e.g. formatting fixes from the build/test step)
|
|
259
315
|
git diff --name-only | xargs -r git add
|
|
@@ -288,14 +344,44 @@ git tag v{NEW_VERSION}
|
|
|
288
344
|
git push --tags
|
|
289
345
|
```
|
|
290
346
|
|
|
291
|
-
After pushing the tag, create a GitHub release. If
|
|
292
|
-
section you just wrote out
|
|
347
|
+
After pushing the tag, create a GitHub release. If a root single-page changelog was updated, pull
|
|
348
|
+
the section you just wrote out as before:
|
|
293
349
|
|
|
294
350
|
```bash
|
|
295
351
|
NOTES=$(awk -v ver="## {NEW_VERSION}" '$0==ver{f=1;next} f&&/^## /{f=0} f' src/content/docs/changelog/index.mdx)
|
|
296
352
|
gh release create v{NEW_VERSION} --title "v{NEW_VERSION}" --notes "$NOTES"
|
|
297
353
|
```
|
|
298
354
|
|
|
355
|
+
For a root per-version-file layout, remove the frontmatter from the new entry and use the rest of
|
|
356
|
+
its body as `NOTES`:
|
|
357
|
+
|
|
358
|
+
```bash
|
|
359
|
+
NOTES=$(awk 'NR==1&&$0=="---"{fm=1;next} fm&&$0=="---"{fm=0;next} !fm{print}' "src/content/docs/changelog/{NEW_VERSION}.mdx")
|
|
360
|
+
gh release create v{NEW_VERSION} --title "v{NEW_VERSION}" --notes "$NOTES"
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
For a multi-package changelog, concatenate the primary-language notes for every selected package,
|
|
364
|
+
in the same order shown to the user, under a `## <slug>` heading. This concrete loop handles a mix
|
|
365
|
+
of single-page and per-version-file package directories:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
NOTES=""
|
|
369
|
+
for slug in $SELECTED_PACKAGES; do
|
|
370
|
+
dir="src/content/docs/changelog/$slug"
|
|
371
|
+
if test -f "$dir/{NEW_VERSION}.mdx"; then
|
|
372
|
+
body=$(awk 'NR==1&&$0=="---"{fm=1;next} fm&&$0=="---"{fm=0;next} !fm{print}' "$dir/{NEW_VERSION}.mdx")
|
|
373
|
+
else
|
|
374
|
+
body=$(awk -v ver="## {NEW_VERSION}" '$0==ver{f=1;next} f&&/^## /{f=0} f' "$dir/index.mdx")
|
|
375
|
+
fi
|
|
376
|
+
printf -v NOTES '%s## %s\n\n%s\n\n' "$NOTES" "$slug" "$body"
|
|
377
|
+
done
|
|
378
|
+
gh release create v{NEW_VERSION} --title "v{NEW_VERSION}" --notes "$NOTES"
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
Set `SELECTED_PACKAGES` to the validated, space-separated package slugs chosen earlier. Build
|
|
382
|
+
release notes from the primary-language files only; the other-locale mirror is not duplicated in
|
|
383
|
+
the GitHub release body.
|
|
384
|
+
|
|
299
385
|
If the changelog feature is off, write the release notes directly from the categorized commit
|
|
300
386
|
analysis instead:
|
|
301
387
|
|
|
@@ -326,7 +412,7 @@ Package is marked as private — skipping npm publish.
|
|
|
326
412
|
Report the summary:
|
|
327
413
|
|
|
328
414
|
- Version bumped: `{OLD_VERSION}` → `{NEW_VERSION}`
|
|
329
|
-
- Changelog updated (EN + JA, if
|
|
415
|
+
- Changelog layout(s) and selected package(s) updated (EN + JA, if enabled)
|
|
330
416
|
- Docs snapshot created (if the versioning feature is enabled and a snapshot was taken)
|
|
331
417
|
- Git tag: `v{NEW_VERSION}`
|
|
332
418
|
- GitHub release: link to the release
|