Skip to content

Commit f5829b8

Browse files
authored
Prepare release v4.7.0 (#1289)
Major performance improvement: The new `externalJsonProps` option (enabled by default) dramatically reduces build times and bundle sizes by externalizing large JSON props from MDX files. - New `externalJsonProps` plugin option significantly improves build performance - Sticky positioning for the API Explorer right panel improves UX on long API pages - Dynamic request body updates when switching anyOf/oneOf tabs #### 🚀 New Feature - feat(plugin): add externalJsonProps option (enabled by default) to improve build performance (#1279) - feat(theme): add sticky positioning to API Explorer right panel (#1288) - feat: dynamically update request body when anyOf/oneOf tab changes (#1287) #### 🐛 Bug Fix - fix: render inline enum values in anyOf schemas (#1286) - fix: generate correct examples for different request content types (#1284) #### 🏠 Refactoring - refactor: change plugin and theme types.ts to types.d.ts (#1281) - refactor: externalize using create() and drop size threshold requirement (#1280) #### 📝 Documentation - docs: sync README and intro.mdx with plugin docs #### 🤖 Dependencies - chore(deps): bump lodash from 4.17.21 to 4.17.23 (#1282) #### Committers: 3 - dependabot[bot] - Ollie Monk - Steven Serrata
1 parent 71621ac commit f5829b8

File tree

6 files changed

+223
-45
lines changed

6 files changed

+223
-45
lines changed

AGENTS.md

Lines changed: 47 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -86,24 +86,62 @@ This outputs a changelog template comparing commits between the latest tag and `
8686

8787
**Changelog format:**
8888

89+
The changelog uses a categorized format inspired by [Docusaurus](https://github.com/facebook/docusaurus/blob/main/CHANGELOG.md). Each release includes a high-level summary followed by categorized changes with emoji headers.
90+
8991
```markdown
90-
## X.Y.Z (Mon DD, YYYY)
92+
## X.Y.Z (YYYY-MM-DD)
93+
94+
Brief summary of the most significant changes in this release (1-3 sentences).
95+
96+
- Bullet points highlighting major user-facing features or fixes
97+
98+
#### :rocket: New Feature
99+
100+
- feat: description of feature ([#123](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/123))
101+
102+
#### :bug: Bug Fix
103+
104+
- fix: description of fix ([#124](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/124))
91105

92-
High level enhancements
106+
#### :house: Refactoring
93107

94-
- Brief summary of major features or fixes
108+
- refactor: description ([#125](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/125))
95109

96-
Other enhancements and bug fixes
110+
#### :memo: Documentation
97111

98-
- Commit message ([#123](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/123))
112+
- docs: description ([#126](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/126))
113+
114+
#### :robot: Dependencies
115+
116+
- chore(deps): bump package from X to Y ([#127](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/127))
117+
118+
#### Committers: N
119+
120+
- Name or username
99121
```
100122

123+
**Category headers (include only sections with changes):**
124+
125+
| Emoji | Category | Commit Prefix |
126+
| --------------- | ------------- | --------------- |
127+
| :rocket: | New Feature | `feat` |
128+
| :bug: | Bug Fix | `fix`, `bugfix` |
129+
| :running_woman: | Performance | `perf` |
130+
| :nail_care: | Polish | `style` |
131+
| :house: | Refactoring | `refactor` |
132+
| :memo: | Documentation | `docs` |
133+
| :test_tube: | Testing | `test` |
134+
| :robot: | Dependencies | `chore(deps)` |
135+
| :wrench: | Maintenance | `chore` |
136+
101137
**Guidelines for changelog entries:**
102138

103-
- Replace `TODO HIGHLIGHTS` with a concise summary of user-facing changes
104-
- Remove internal commits (CI changes, minor refactors) that don't affect users
105-
- Group related changes together when appropriate
106-
- Use past tense for descriptions
139+
- Replace `TODO: Add high-level summary` with a concise summary of user-facing changes
140+
- Use ISO date format: `YYYY-MM-DD`
141+
- Remove internal commits (CI changes, workflow updates) that don't affect users
142+
- Keep the original commit message format (e.g., `feat:`, `fix:`)
143+
- Only include category sections that have changes
144+
- List committers alphabetically at the end
107145

108146
#### Step 3: Update Documentation (if needed)
109147

CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,41 @@
1+
## 4.7.0 (2026-01-27)
2+
3+
Major performance improvement: The new `externalJsonProps` option (enabled by default) dramatically reduces build times and bundle sizes by externalizing large JSON props from MDX files.
4+
5+
- New `externalJsonProps` plugin option significantly improves build performance
6+
- Sticky positioning for the API Explorer right panel improves UX on long API pages
7+
- Dynamic request body updates when switching anyOf/oneOf tabs
8+
9+
#### :rocket: New Feature
10+
11+
- feat(plugin): add externalJsonProps option (enabled by default) to improve build performance ([#1279](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1279))
12+
- feat(theme): add sticky positioning to API Explorer right panel ([#1288](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1288))
13+
- feat: dynamically update request body when anyOf/oneOf tab changes ([#1287](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1287))
14+
15+
#### :bug: Bug Fix
16+
17+
- fix: render inline enum values in anyOf schemas ([#1286](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1286))
18+
- fix: generate correct examples for different request content types ([#1284](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1284))
19+
20+
#### :house: Refactoring
21+
22+
- refactor: change plugin and theme types.ts to types.d.ts ([#1281](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1281))
23+
- refactor: externalize using create() and drop size threshold requirement ([#1280](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1280))
24+
25+
#### :memo: Documentation
26+
27+
- docs: sync README and intro.mdx with plugin docs
28+
29+
#### :robot: Dependencies
30+
31+
- chore(deps): bump lodash from 4.17.21 to 4.17.23 ([#1282](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1282))
32+
33+
#### Committers: 3
34+
35+
- dependabot[bot]
36+
- Ollie Monk
37+
- Steven Serrata
38+
139
## 4.6.0 (Jan 16, 2026)
240

341
High level enhancements

lerna.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"version": "4.6.0",
2+
"version": "4.7.0",
33
"npmClient": "yarn"
44
}

packages/docusaurus-plugin-openapi-docs/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "docusaurus-plugin-openapi-docs",
33
"description": "OpenAPI plugin for Docusaurus.",
4-
"version": "4.6.0",
4+
"version": "4.7.0",
55
"license": "MIT",
66
"keywords": [
77
"openapi",

packages/docusaurus-theme-openapi-docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "docusaurus-theme-openapi-docs",
33
"description": "OpenAPI theme for Docusaurus.",
4-
"version": "4.6.0",
4+
"version": "4.7.0",
55
"license": "MIT",
66
"keywords": [
77
"openapi",
@@ -38,7 +38,7 @@
3838
"@types/postman-collection": "^3.5.11",
3939
"@types/react-modal": "^3.16.3",
4040
"concurrently": "^9.2.0",
41-
"docusaurus-plugin-openapi-docs": "^4.6.0",
41+
"docusaurus-plugin-openapi-docs": "^4.7.0",
4242
"docusaurus-plugin-sass": "^0.2.6",
4343
"eslint-plugin-prettier": "^5.5.1"
4444
},

scripts/changelog.ts

Lines changed: 134 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,24 @@ const BRANCH = "main";
1616

1717
const COMMIT_FILTERS = [/\(release\) v.*/];
1818

19+
// Commit categorization patterns
20+
const CATEGORY_PATTERNS: {
21+
pattern: RegExp;
22+
category: string;
23+
emoji: string;
24+
}[] = [
25+
{ pattern: /^feat/i, category: "New Feature", emoji: ":rocket:" },
26+
{ pattern: /^fix/i, category: "Bug Fix", emoji: ":bug:" },
27+
{ pattern: /^bugfix/i, category: "Bug Fix", emoji: ":bug:" },
28+
{ pattern: /^perf/i, category: "Performance", emoji: ":running_woman:" },
29+
{ pattern: /^refactor/i, category: "Refactoring", emoji: ":house:" },
30+
{ pattern: /^docs/i, category: "Documentation", emoji: ":memo:" },
31+
{ pattern: /^chore\(deps\)/i, category: "Dependencies", emoji: ":robot:" },
32+
{ pattern: /^chore/i, category: "Maintenance", emoji: ":wrench:" },
33+
{ pattern: /^test/i, category: "Testing", emoji: ":test_tube:" },
34+
{ pattern: /^style/i, category: "Polish", emoji: ":nail_care:" },
35+
];
36+
1937
// Makes the script crash on unhandled rejections instead of silently
2038
// ignoring them. In the future, promise rejections that are not handled will
2139
// terminate the Node.js process with a non-zero exit code.
@@ -42,27 +60,85 @@ function findLatestTag() {
4260
return getOutput(`git describe --tags --abbrev=0 --match "v*"`);
4361
}
4462

45-
function getCommits(commitRange: string) {
46-
return getOutput(`git log --pretty="%s" ${commitRange}`).split(/\r?\n/);
63+
interface CommitInfo {
64+
message: string;
65+
author: string;
66+
hash: string;
67+
}
68+
69+
function getCommits(commitRange: string): CommitInfo[] {
70+
const output = getOutput(
71+
`git log --pretty=format:"%H|%an|%s" ${commitRange}`
72+
);
73+
if (!output.trim()) return [];
74+
75+
return output.split(/\r?\n/).map((line) => {
76+
const [hash, author, ...messageParts] = line.split("|");
77+
return {
78+
hash: hash || "",
79+
author: author || "",
80+
message: messageParts.join("|") || "",
81+
};
82+
});
4783
}
4884

49-
function formatCommits(commits: string[]) {
50-
return commits
51-
.filter((c) => {
52-
for (const filter of COMMIT_FILTERS) {
53-
if (filter.test(c)) {
54-
return false;
55-
}
85+
function categorizeCommit(message: string): {
86+
category: string;
87+
emoji: string;
88+
} {
89+
for (const { pattern, category, emoji } of CATEGORY_PATTERNS) {
90+
if (pattern.test(message)) {
91+
return { category, emoji };
92+
}
93+
}
94+
return { category: "Other", emoji: ":sparkles:" };
95+
}
96+
97+
function formatCommitMessage(message: string): string {
98+
const r = /\(#(\d+)\)$/;
99+
return message.replace(
100+
r,
101+
`([#$1](https://github.com/${ORG}/${REPO}/pull/$1))`
102+
);
103+
}
104+
105+
function filterCommits(commits: CommitInfo[]): CommitInfo[] {
106+
return commits.filter((c) => {
107+
for (const filter of COMMIT_FILTERS) {
108+
if (filter.test(c.message)) {
109+
return false;
56110
}
57-
return true;
58-
})
59-
.map((c) => {
60-
const r = /\(#(\d+)\)$/;
61-
return `- ${c.replace(
62-
r,
63-
`([#$1](https://github.com/${ORG}/${REPO}/pull/$1))`
64-
)}`;
65-
});
111+
}
112+
return true;
113+
});
114+
}
115+
116+
function groupCommitsByCategory(
117+
commits: CommitInfo[]
118+
): Map<string, { emoji: string; commits: CommitInfo[] }> {
119+
const grouped = new Map<string, { emoji: string; commits: CommitInfo[] }>();
120+
121+
for (const commit of commits) {
122+
const { category, emoji } = categorizeCommit(commit.message);
123+
if (!grouped.has(category)) {
124+
grouped.set(category, { emoji, commits: [] });
125+
}
126+
grouped.get(category)!.commits.push(commit);
127+
}
128+
129+
return grouped;
130+
}
131+
132+
function getUniqueCommitters(commits: CommitInfo[]): string[] {
133+
const authors = new Set<string>();
134+
for (const commit of commits) {
135+
if (commit.author && commit.author.trim()) {
136+
authors.add(commit.author);
137+
}
138+
}
139+
return Array.from(authors).sort((a, b) =>
140+
a.toLowerCase().localeCompare(b.toLowerCase())
141+
);
66142
}
67143

68144
function main() {
@@ -88,30 +164,56 @@ function main() {
88164
console.log(`Comparing ${commitRange}`);
89165

90166
const commits = getCommits(commitRange);
91-
const formattedCommits = formatCommits(commits);
167+
const filteredCommits = filterCommits(commits);
92168

93-
if (formattedCommits.length === 0) {
169+
if (filteredCommits.length === 0) {
94170
console.error("Error: There has been no changes since last release.");
95171
process.exit(1);
96172
}
97173

98-
const date = new Date().toLocaleDateString("en-US", {
99-
month: "short",
100-
day: "numeric",
101-
year: "numeric",
102-
});
174+
const groupedCommits = groupCommitsByCategory(filteredCommits);
175+
const committers = getUniqueCommitters(filteredCommits);
176+
177+
// Format date as YYYY-MM-DD
178+
const date = new Date().toISOString().split("T")[0];
179+
180+
// Build changelog sections
181+
const sections: string[] = [];
182+
183+
// Category order for consistent output
184+
const categoryOrder = [
185+
"New Feature",
186+
"Bug Fix",
187+
"Performance",
188+
"Polish",
189+
"Refactoring",
190+
"Documentation",
191+
"Testing",
192+
"Dependencies",
193+
"Maintenance",
194+
"Other",
195+
];
196+
197+
for (const category of categoryOrder) {
198+
const group = groupedCommits.get(category);
199+
if (group && group.commits.length > 0) {
200+
const commitLines = group.commits
201+
.map((c) => `- ${formatCommitMessage(c.message)}`)
202+
.join("\n");
203+
sections.push(`#### ${group.emoji} ${category}\n\n${commitLines}`);
204+
}
205+
}
103206

104-
const changelog = `
105-
## ${pkg.version} (${date})
207+
const changelog = `## ${pkg.version} (${date})
106208
107-
High level enhancements
209+
TODO: Add high-level summary of major changes
108210
109-
- TODO HIGHLIGHTS
211+
${sections.join("\n\n")}
110212
111-
Other enhancements and bug fixes
213+
#### Committers: ${committers.length}
112214
113-
${formattedCommits.join("\n")}
114-
`;
215+
${committers.map((c) => `- ${c}`).join("\n")}
216+
`;
115217

116218
printBanner("Prepend the following to CHANGELOG.md");
117219
console.log(changelog);

0 commit comments

Comments
 (0)