diff --git a/.bumpy/changelog-bump-labels.md b/.bumpy/changelog-bump-labels.md
new file mode 100644
index 0000000..f7d9fa5
--- /dev/null
+++ b/.bumpy/changelog-bump-labels.md
@@ -0,0 +1,5 @@
+---
+'@varlock/bumpy': patch
+---
+
+Always show bump type label on each changelog item instead of only when it differs from the release type
diff --git a/docs/differences-from-changesets.md b/docs/differences-from-changesets.md
index 0f96ecf..b8ffe4f 100644
--- a/docs/differences-from-changesets.md
+++ b/docs/differences-from-changesets.md
@@ -68,9 +68,9 @@ Changesets uses `npm publish` even in Yarn/pnpm workspaces, so `workspace:^` and
- [changesets#979](https://github.com/changesets/changesets/issues/979) — non-interactive mode (15 thumbs-up)
- [changesets#1118](https://github.com/changesets/changesets/discussions/1118) — CLI automation support
-### Provenance and custom publish args
+### Provenance, staged publishing, and custom publish args
-Bumpy supports passing extra args (like `--provenance`) to the publish command via config.
+Bumpy has first-class `provenance` and `npmStaged` config options, plus support for passing extra args to the publish command.
- [changesets#1152](https://github.com/changesets/changesets/issues/1152) — provenance support (36 thumbs-up, 26 comments)
diff --git a/packages/bumpy/CHANGELOG.md b/packages/bumpy/CHANGELOG.md
index 241f5c8..e43fcbb 100644
--- a/packages/bumpy/CHANGELOG.md
+++ b/packages/bumpy/CHANGELOG.md
@@ -4,7 +4,7 @@
2026-05-27
-- [#87](https://github.com/dmno-dev/bumpy/pull/87) - Fix draft release functions (`createDraftRelease`, `updateReleaseBody`, `finalizeRelease`, `deleteRelease`) to use `BUMPY_GH_TOKEN` via `withReleaseToken` so that GitHub release events trigger downstream workflows. Also disables npm staged publishing (not yet ready) and removes the npm upgrade step from the release workflow.
+- [#87](https://github.com/dmno-dev/bumpy/pull/87) - Fix draft release functions (`createDraftRelease`, `updateReleaseBody`, `finalizeRelease`, `deleteRelease`) to use `BUMPY_GH_TOKEN` via `withReleaseToken` so that GitHub release events trigger downstream workflows. Also disables npm staged publishing (not yet ready).
## 1.10.0
diff --git a/packages/bumpy/config-schema.json b/packages/bumpy/config-schema.json
index b4fc2a3..6c28a79 100644
--- a/packages/bumpy/config-schema.json
+++ b/packages/bumpy/config-schema.json
@@ -143,7 +143,7 @@
"publishArgs": {
"type": "array",
"items": { "type": "string" },
- "description": "Extra args appended to the publish command (e.g., \"--provenance\")",
+ "description": "Extra args appended to the publish command (e.g., \"--tag next\")",
"default": []
},
"protocolResolution": {
diff --git a/packages/bumpy/src/core/changelog-github.ts b/packages/bumpy/src/core/changelog-github.ts
index b28410c..f8e37de 100644
--- a/packages/bumpy/src/core/changelog-github.ts
+++ b/packages/bumpy/src/core/changelog-github.ts
@@ -64,7 +64,7 @@ export function createGithubFormatter(options: GithubChangelogOptions = {}): Cha
if (!bf.summary) continue;
const type = getBumpTypeForPackage(bf, release.name);
- const tag = type !== release.type ? ` *(${type})*` : '';
+ const tag = ` *(${type})*`;
// Extract metadata overrides from summary (pr, commit, author lines)
const { cleanSummary, overrides } = extractSummaryMeta(bf.summary);
@@ -106,16 +106,24 @@ export function createGithubFormatter(options: GithubChangelogOptions = {}): Cha
(max, s) => maxBump(max, s.bumpType),
undefined,
);
- const depTag = depBumpType && depBumpType !== release.type ? ` *(${depBumpType})* -` : '';
+ const depTag = depBumpType ? ` *(${depBumpType})*` : '';
lines.push(`-${depTag} Updated dependency ${sourceList || '(internal)'}`);
}
if (release.isGroupBump) {
- lines.push(sourceList ? `- Version bump from group with ${sourceList}` : '- Version bump from group');
+ lines.push(
+ sourceList
+ ? `- *(${release.type})* Version bump from group with ${sourceList}`
+ : `- *(${release.type})* Version bump from group`,
+ );
}
if (release.isCascadeBump && !release.isDependencyBump && !release.isGroupBump) {
- lines.push(sourceList ? `- Version bump from ${sourceList}` : '- Version bump via cascade rule');
+ lines.push(
+ sourceList
+ ? `- *(${release.type})* Version bump from ${sourceList}`
+ : `- *(${release.type})* Version bump via cascade rule`,
+ );
}
lines.push('');
diff --git a/packages/bumpy/src/core/changelog.ts b/packages/bumpy/src/core/changelog.ts
index cc6c6b4..01b3c05 100644
--- a/packages/bumpy/src/core/changelog.ts
+++ b/packages/bumpy/src/core/changelog.ts
@@ -55,9 +55,8 @@ export const defaultFormatter: ChangelogFormatter = (ctx) => {
for (const bf of sorted) {
if (!bf.summary) continue;
const type = getBumpTypeForPackage(bf, release.name);
- const tag = type !== release.type ? `*(${type})* ` : '';
const summaryLines = bf.summary.split('\n');
- lines.push(`- ${tag}${summaryLines[0]}`);
+ lines.push(`- *(${type})* ${summaryLines[0]}`);
for (let i = 1; i < summaryLines.length; i++) {
if (summaryLines[i]!.trim()) {
lines.push(` ${summaryLines[i]}`);
@@ -73,16 +72,24 @@ export const defaultFormatter: ChangelogFormatter = (ctx) => {
(max, s) => maxBump(max, s.bumpType),
undefined,
);
- const tag = depBumpType && depBumpType !== release.type ? `*(${depBumpType})* ` : '';
- lines.push(`- ${tag}Updated dependency ${sourceList || '(internal)'}`);
+ const depBumpTag = depBumpType ? `*(${depBumpType})* ` : '';
+ lines.push(`- ${depBumpTag}Updated dependency ${sourceList || '(internal)'}`);
}
if (release.isGroupBump) {
- lines.push(sourceList ? `- Version bump from group with ${sourceList}` : '- Version bump from group');
+ lines.push(
+ sourceList
+ ? `- *(${release.type})* Version bump from group with ${sourceList}`
+ : `- *(${release.type})* Version bump from group`,
+ );
}
if (release.isCascadeBump && !release.isDependencyBump && !release.isGroupBump) {
- lines.push(sourceList ? `- Version bump from ${sourceList}` : '- Version bump via cascade rule');
+ lines.push(
+ sourceList
+ ? `- *(${release.type})* Version bump from ${sourceList}`
+ : `- *(${release.type})* Version bump via cascade rule`,
+ );
}
lines.push('');
diff --git a/packages/bumpy/src/types.ts b/packages/bumpy/src/types.ts
index 97d053a..05aaa17 100644
--- a/packages/bumpy/src/types.ts
+++ b/packages/bumpy/src/types.ts
@@ -69,7 +69,7 @@ export interface PublishConfig {
packManager: 'auto' | 'npm' | 'pnpm' | 'bun' | 'yarn';
/** Command to use for publishing. "npm" uses npm publish (supports OIDC). Default: "npm" */
publishManager: 'npm' | 'pnpm' | 'bun' | 'yarn';
- /** Extra args appended to the publish command (e.g., "--provenance") */
+ /** Extra args appended to the publish command (e.g., "--tag next") */
publishArgs: string[];
/**
* How to handle workspace:/catalog: protocol resolution.
diff --git a/packages/bumpy/test/core/changelog-github.test.ts b/packages/bumpy/test/core/changelog-github.test.ts
index cf24657..daa5718 100644
--- a/packages/bumpy/test/core/changelog-github.test.ts
+++ b/packages/bumpy/test/core/changelog-github.test.ts
@@ -145,7 +145,7 @@ describe('createGithubFormatter', () => {
const result = await formatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('Updated dependency `core` v2.0.0');
+ expect(result).toContain('*(patch)* Updated dependency `core` v2.0.0');
});
test('handles dependency bump without source packages (fallback)', async () => {
@@ -170,7 +170,7 @@ describe('createGithubFormatter', () => {
const result = await formatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump from `core` v1.1.0');
+ expect(result).toContain('- *(patch)* Version bump from `core` v1.1.0');
});
test('handles cascade bump without source packages (fallback)', async () => {
@@ -182,7 +182,7 @@ describe('createGithubFormatter', () => {
const result = await formatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump via cascade rule');
+ expect(result).toContain('- *(patch)* Version bump via cascade rule');
});
test('handles group bump with source packages', async () => {
@@ -196,7 +196,7 @@ describe('createGithubFormatter', () => {
const result = await formatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump from group with `core` v1.1.0');
+ expect(result).toContain('- *(minor)* Version bump from group with `core` v1.1.0');
});
test('handles group bump without source packages (fallback)', async () => {
@@ -209,7 +209,7 @@ describe('createGithubFormatter', () => {
const result = await formatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump from group');
+ expect(result).toContain('- *(minor)* Version bump from group');
});
test('resolves bump file info from git log', async () => {
diff --git a/packages/bumpy/test/core/changelog.test.ts b/packages/bumpy/test/core/changelog.test.ts
index ddd24d5..4f45386 100644
--- a/packages/bumpy/test/core/changelog.test.ts
+++ b/packages/bumpy/test/core/changelog.test.ts
@@ -24,9 +24,9 @@ describe('defaultFormatter', () => {
expect(result).toContain('## 1.1.0');
expect(result).toContain('2026-04-14');
- expect(result).toContain('- Added new feature');
+ expect(result).toContain('- *(minor)* Added new feature');
expect(result).toContain('- *(patch)* Fixed a bug');
- // Minor (matching release type, no tag) should come before patch
+ // Major should come before minor, before patch
expect(result.indexOf('Added new feature')).toBeLessThan(result.indexOf('Fixed a bug'));
});
@@ -39,7 +39,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Updated dependency `core` v2.0.0');
+ expect(result).toContain('*(patch)* Updated dependency `core` v2.0.0');
});
test('formats dependency bump without source packages (fallback)', async () => {
@@ -50,7 +50,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Updated dependency (internal)');
+ expect(result).toContain('Updated dependency (internal)');
});
test('formats cascade bump with source packages', async () => {
@@ -62,7 +62,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump from `core` v1.1.0');
+ expect(result).toContain('- *(patch)* Version bump from `core` v1.1.0');
});
test('formats cascade bump without source packages (fallback)', async () => {
@@ -73,7 +73,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump via cascade rule');
+ expect(result).toContain('- *(patch)* Version bump via cascade rule');
});
test('formats group bump with source packages', async () => {
@@ -86,7 +86,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump from group with `core` v1.1.0');
+ expect(result).toContain('- *(minor)* Version bump from group with `core` v1.1.0');
});
test('formats group bump without source packages (fallback)', async () => {
@@ -98,7 +98,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Version bump from group');
+ expect(result).toContain('- *(minor)* Version bump from group');
});
test('dependency + cascade shows only dependency message', async () => {
@@ -111,7 +111,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
- expect(result).toContain('- Updated dependency `core` v2.0.0');
+ expect(result).toContain('*(patch)* Updated dependency `core` v2.0.0');
expect(result).not.toContain('cascade');
});
@@ -130,7 +130,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles: [], date: '2026-04-14' });
expect(result).toContain('Updated dependency');
- expect(result).toContain('Version bump from group with');
+ expect(result).toContain('*(minor)* Version bump from group with');
});
test('direct changes + group upgrade shows both', async () => {
@@ -145,7 +145,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles, date: '2026-04-14' });
expect(result).toContain('*(patch)* Fixed a typo');
- expect(result).toContain('Version bump from group with `pkg-a` v1.1.0');
+ expect(result).toContain('*(minor)* Version bump from group with `pkg-a` v1.1.0');
});
test('handles multi-line bump file summaries', async () => {
@@ -157,7 +157,7 @@ describe('defaultFormatter', () => {
const result = await defaultFormatter({ release, bumpFiles, date: '2026-04-14' });
- expect(result).toContain('- First line');
+ expect(result).toContain('- *(minor)* First line');
expect(result).toContain(' Second paragraph');
});
@@ -183,7 +183,7 @@ describe('generateChangelogEntry', () => {
const result = await generateChangelogEntry(release, bumpFiles);
expect(result).toContain('## 1.0.1');
- expect(result).toContain('- Fix');
+ expect(result).toContain('- *(patch)* Fix');
});
test('uses custom formatter', async () => {
@@ -291,6 +291,6 @@ describe('loadFormatter', () => {
const result = await formatter({ release, bumpFiles, date: '2026-04-14' });
expect(result).toContain('## 1.0.0');
- expect(result).toContain('- A fix');
+ expect(result).toContain('- *(patch)* A fix');
});
});