Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 47 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,24 +86,62 @@ This outputs a changelog template comparing commits between the latest tag and `

**Changelog format:**

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.

```markdown
## X.Y.Z (Mon DD, YYYY)
## X.Y.Z (YYYY-MM-DD)

Brief summary of the most significant changes in this release (1-3 sentences).

- Bullet points highlighting major user-facing features or fixes

#### :rocket: New Feature

- feat: description of feature ([#123](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/123))

#### :bug: Bug Fix

- fix: description of fix ([#124](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/124))

High level enhancements
#### :house: Refactoring

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

Other enhancements and bug fixes
#### :memo: Documentation

- Commit message ([#123](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/123))
- docs: description ([#126](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/126))

#### :robot: Dependencies

- chore(deps): bump package from X to Y ([#127](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/127))

#### Committers: N

- Name or username
```

**Category headers (include only sections with changes):**

| Emoji | Category | Commit Prefix |
| --------------- | ------------- | --------------- |
| :rocket: | New Feature | `feat` |
| :bug: | Bug Fix | `fix`, `bugfix` |
| :running_woman: | Performance | `perf` |
| :nail_care: | Polish | `style` |
| :house: | Refactoring | `refactor` |
| :memo: | Documentation | `docs` |
| :test_tube: | Testing | `test` |
| :robot: | Dependencies | `chore(deps)` |
| :wrench: | Maintenance | `chore` |

**Guidelines for changelog entries:**

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

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

Expand Down
38 changes: 38 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,41 @@
## 4.7.0 (2026-01-27)

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

#### :rocket: New Feature

- feat(plugin): add externalJsonProps option (enabled by default) to improve build performance ([#1279](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1279))
- feat(theme): add sticky positioning to API Explorer right panel ([#1288](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1288))
- feat: dynamically update request body when anyOf/oneOf tab changes ([#1287](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1287))

#### :bug: Bug Fix

- fix: render inline enum values in anyOf schemas ([#1286](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1286))
- fix: generate correct examples for different request content types ([#1284](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1284))

#### :house: Refactoring

- refactor: change plugin and theme types.ts to types.d.ts ([#1281](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1281))
- refactor: externalize using create() and drop size threshold requirement ([#1280](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1280))

#### :memo: Documentation

- docs: sync README and intro.mdx with plugin docs

#### :robot: Dependencies

- chore(deps): bump lodash from 4.17.21 to 4.17.23 ([#1282](https://github.com/PaloAltoNetworks/docusaurus-openapi-docs/pull/1282))

#### Committers: 3

- dependabot[bot]
- Ollie Monk
- Steven Serrata

## 4.6.0 (Jan 16, 2026)

High level enhancements
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"version": "4.6.0",
"version": "4.7.0",
"npmClient": "yarn"
}
2 changes: 1 addition & 1 deletion packages/docusaurus-plugin-openapi-docs/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "docusaurus-plugin-openapi-docs",
"description": "OpenAPI plugin for Docusaurus.",
"version": "4.6.0",
"version": "4.7.0",
"license": "MIT",
"keywords": [
"openapi",
Expand Down
4 changes: 2 additions & 2 deletions packages/docusaurus-theme-openapi-docs/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "docusaurus-theme-openapi-docs",
"description": "OpenAPI theme for Docusaurus.",
"version": "4.6.0",
"version": "4.7.0",
"license": "MIT",
"keywords": [
"openapi",
Expand Down Expand Up @@ -38,7 +38,7 @@
"@types/postman-collection": "^3.5.11",
"@types/react-modal": "^3.16.3",
"concurrently": "^9.2.0",
"docusaurus-plugin-openapi-docs": "^4.6.0",
"docusaurus-plugin-openapi-docs": "^4.7.0",
"docusaurus-plugin-sass": "^0.2.6",
"eslint-plugin-prettier": "^5.5.1"
},
Expand Down
166 changes: 134 additions & 32 deletions scripts/changelog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,24 @@ const BRANCH = "main";

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

// Commit categorization patterns
const CATEGORY_PATTERNS: {
pattern: RegExp;
category: string;
emoji: string;
}[] = [
{ pattern: /^feat/i, category: "New Feature", emoji: ":rocket:" },
{ pattern: /^fix/i, category: "Bug Fix", emoji: ":bug:" },
{ pattern: /^bugfix/i, category: "Bug Fix", emoji: ":bug:" },
{ pattern: /^perf/i, category: "Performance", emoji: ":running_woman:" },
{ pattern: /^refactor/i, category: "Refactoring", emoji: ":house:" },
{ pattern: /^docs/i, category: "Documentation", emoji: ":memo:" },
{ pattern: /^chore\(deps\)/i, category: "Dependencies", emoji: ":robot:" },
{ pattern: /^chore/i, category: "Maintenance", emoji: ":wrench:" },
{ pattern: /^test/i, category: "Testing", emoji: ":test_tube:" },
{ pattern: /^style/i, category: "Polish", emoji: ":nail_care:" },
];

// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
Expand All @@ -42,27 +60,85 @@ function findLatestTag() {
return getOutput(`git describe --tags --abbrev=0 --match "v*"`);
}

function getCommits(commitRange: string) {
return getOutput(`git log --pretty="%s" ${commitRange}`).split(/\r?\n/);
interface CommitInfo {
message: string;
author: string;
hash: string;
}

function getCommits(commitRange: string): CommitInfo[] {
const output = getOutput(
`git log --pretty=format:"%H|%an|%s" ${commitRange}`
);
if (!output.trim()) return [];

return output.split(/\r?\n/).map((line) => {
const [hash, author, ...messageParts] = line.split("|");
return {
hash: hash || "",
author: author || "",
message: messageParts.join("|") || "",
};
});
}

function formatCommits(commits: string[]) {
return commits
.filter((c) => {
for (const filter of COMMIT_FILTERS) {
if (filter.test(c)) {
return false;
}
function categorizeCommit(message: string): {
category: string;
emoji: string;
} {
for (const { pattern, category, emoji } of CATEGORY_PATTERNS) {
if (pattern.test(message)) {
return { category, emoji };
}
}
return { category: "Other", emoji: ":sparkles:" };
}

function formatCommitMessage(message: string): string {
const r = /\(#(\d+)\)$/;
return message.replace(
r,
`([#$1](https://github.com/${ORG}/${REPO}/pull/$1))`
);
}

function filterCommits(commits: CommitInfo[]): CommitInfo[] {
return commits.filter((c) => {
for (const filter of COMMIT_FILTERS) {
if (filter.test(c.message)) {
return false;
}
return true;
})
.map((c) => {
const r = /\(#(\d+)\)$/;
return `- ${c.replace(
r,
`([#$1](https://github.com/${ORG}/${REPO}/pull/$1))`
)}`;
});
}
return true;
});
}

function groupCommitsByCategory(
commits: CommitInfo[]
): Map<string, { emoji: string; commits: CommitInfo[] }> {
const grouped = new Map<string, { emoji: string; commits: CommitInfo[] }>();

for (const commit of commits) {
const { category, emoji } = categorizeCommit(commit.message);
if (!grouped.has(category)) {
grouped.set(category, { emoji, commits: [] });
}
grouped.get(category)!.commits.push(commit);
}

return grouped;
}

function getUniqueCommitters(commits: CommitInfo[]): string[] {
const authors = new Set<string>();
for (const commit of commits) {
if (commit.author && commit.author.trim()) {
authors.add(commit.author);
}
}
return Array.from(authors).sort((a, b) =>
a.toLowerCase().localeCompare(b.toLowerCase())
);
}

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

const commits = getCommits(commitRange);
const formattedCommits = formatCommits(commits);
const filteredCommits = filterCommits(commits);

if (formattedCommits.length === 0) {
if (filteredCommits.length === 0) {
console.error("Error: There has been no changes since last release.");
process.exit(1);
}

const date = new Date().toLocaleDateString("en-US", {
month: "short",
day: "numeric",
year: "numeric",
});
const groupedCommits = groupCommitsByCategory(filteredCommits);
const committers = getUniqueCommitters(filteredCommits);

// Format date as YYYY-MM-DD
const date = new Date().toISOString().split("T")[0];

// Build changelog sections
const sections: string[] = [];

// Category order for consistent output
const categoryOrder = [
"New Feature",
"Bug Fix",
"Performance",
"Polish",
"Refactoring",
"Documentation",
"Testing",
"Dependencies",
"Maintenance",
"Other",
];

for (const category of categoryOrder) {
const group = groupedCommits.get(category);
if (group && group.commits.length > 0) {
const commitLines = group.commits
.map((c) => `- ${formatCommitMessage(c.message)}`)
.join("\n");
sections.push(`#### ${group.emoji} ${category}\n\n${commitLines}`);
}
}

const changelog = `
## ${pkg.version} (${date})
const changelog = `## ${pkg.version} (${date})

High level enhancements
TODO: Add high-level summary of major changes

- TODO HIGHLIGHTS
${sections.join("\n\n")}

Other enhancements and bug fixes
#### Committers: ${committers.length}

${formattedCommits.join("\n")}
`;
${committers.map((c) => `- ${c}`).join("\n")}
`;

printBanner("Prepend the following to CHANGELOG.md");
console.log(changelog);
Expand Down