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
7 changes: 6 additions & 1 deletion apps/cli/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

Expand Down Expand Up @@ -75,7 +79,7 @@ config.plugins.push([
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'superdoc-cli',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -86,6 +90,7 @@ config.plugins.push([
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **superdoc-cli** v${nextRelease.version}\n\nThe release is available on [GitHub release](${releases.find(release => release.pluginName === "@semantic-release/github").url})',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
7 changes: 6 additions & 1 deletion apps/create/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

const config = {
Expand All @@ -35,7 +39,7 @@ config.plugins.push([
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'create',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -46,6 +50,7 @@ config.plugins.push([
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **@superdoc-dev/create** v${nextRelease.version}\n\nThe release is available on [GitHub release](${releases.find(release => release.pluginName === "@semantic-release/github").url})',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
7 changes: 6 additions & 1 deletion apps/mcp/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

Expand Down Expand Up @@ -78,7 +82,7 @@ config.plugins.push([
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'mcp',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -89,6 +93,7 @@ config.plugins.push([
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **@superdoc-dev/mcp** v${nextRelease.version}\n\nThe release is available on [GitHub release](${releases.find(release => release.pluginName === "@semantic-release/github").url})',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
7 changes: 6 additions & 1 deletion apps/vscode-ext/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

Expand Down Expand Up @@ -89,7 +93,7 @@ config.plugins.push([
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'vscode-ext',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -101,6 +105,7 @@ config.plugins.push([
assets: [{ path: '*.vsix', label: 'VS Code Extension' }],
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **vscode-ext** v${nextRelease.version}',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
7 changes: 6 additions & 1 deletion packages/esign/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

Expand Down Expand Up @@ -50,7 +54,7 @@ config.plugins.push([
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'esign',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -61,6 +65,7 @@ config.plugins.push([
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **esign** v${nextRelease.version}\n\nThe release is available on [GitHub release](https://github.com/superdoc-dev/superdoc/releases/tag/${nextRelease.gitTag})',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
10 changes: 9 additions & 1 deletion packages/react/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

Expand Down Expand Up @@ -69,13 +73,17 @@ if (!isPrerelease) {
}

// Linear integration - labels issues with version on release
config.plugins.push(['semantic-release-linear-app', { teamKeys: ['SD'], addComment: true, packageName: 'react' }]);
config.plugins.push([
'semantic-release-linear-app',
{ teamKeys: ['SD'], addComment: shouldCommentOnRelease, packageName: 'react' },
]);

config.plugins.push([
'@semantic-release/github',
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **@superdoc-dev/react** v${nextRelease.version}\n\nThe release is available on [GitHub release](https://github.com/superdoc-dev/superdoc/releases/tag/${nextRelease.gitTag})',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
7 changes: 6 additions & 1 deletion packages/sdk/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

Expand Down Expand Up @@ -102,7 +106,7 @@ config.plugins.push([
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'superdoc-sdk',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -113,6 +117,7 @@ config.plugins.push([
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **superdoc-sdk** v${nextRelease.version}',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
7 changes: 6 additions & 1 deletion packages/superdoc/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin =
isLocalPreview || isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];
Expand Down Expand Up @@ -104,7 +108,7 @@ if (!isLocalPreview) {
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'superdoc',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -118,6 +122,7 @@ if (!isLocalPreview) {
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **superdoc** v${nextRelease.version}\n\nThe release is available on [GitHub release](https://github.com/superdoc-dev/superdoc/releases/tag/${nextRelease.gitTag})',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);
}
Expand Down
7 changes: 6 additions & 1 deletion packages/template-builder/.releaserc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ const branches = [

const isPrerelease = branches.some((b) => typeof b === 'object' && b.name === branch && b.prerelease);

// stable -> main syncs (real merges) re-attribute prereleases to PRs already shipped on @latest.
// Gate per-PR/issue success comments off on prereleases to avoid duplicate "shipped" comments.
const shouldCommentOnRelease = !isPrerelease;

// Use AI-powered notes for stable releases, conventional generator for prereleases
const notesPlugin = isPrerelease ? createReleaseNotesGenerator() : ['semantic-release-ai-notes', { style: 'concise' }];

Expand Down Expand Up @@ -50,7 +54,7 @@ config.plugins.push([
'semantic-release-linear-app',
{
teamKeys: ['SD'],
addComment: true,
addComment: shouldCommentOnRelease,
packageName: 'template-builder',
commentTemplate: 'shipped in {package} {releaseLink} {channel}',
},
Expand All @@ -61,6 +65,7 @@ config.plugins.push([
{
successComment:
':tada: This ${issue.pull_request ? "PR" : "issue"} is included in **template-builder** v${nextRelease.version}\n\nThe release is available on [GitHub release](https://github.com/superdoc-dev/superdoc/releases/tag/${nextRelease.gitTag})',
successCommentCondition: shouldCommentOnRelease ? undefined : false,
},
]);

Expand Down
47 changes: 47 additions & 0 deletions scripts/__tests__/release-local.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,53 @@ test('stable recovery ignores PyPI gaps when SDK PyPI publishing is disabled', a
);
});

test('release configs suppress per-PR comment spam on prereleases', async () => {
const releasercPaths = [
'packages/superdoc/.releaserc.cjs',
'packages/react/.releaserc.cjs',
'packages/sdk/.releaserc.cjs',
'packages/template-builder/.releaserc.cjs',
'packages/esign/.releaserc.cjs',
'apps/cli/.releaserc.cjs',
'apps/mcp/.releaserc.cjs',
'apps/vscode-ext/.releaserc.cjs',
'apps/create/.releaserc.cjs',
];

for (const releasercPath of releasercPaths) {
const content = await readRepoFile(releasercPath);

const usesGithubPlugin = content.includes("'@semantic-release/github'");
const usesLinearPlugin = content.includes("'semantic-release-linear-app'");

if (!usesGithubPlugin && !usesLinearPlugin) continue;

assert.ok(
content.includes('const shouldCommentOnRelease = !isPrerelease'),
`${releasercPath}: must define shouldCommentOnRelease = !isPrerelease so the prerelease comment gate is consistent across configs`,
);

if (usesGithubPlugin) {
assert.ok(
content.includes('successCommentCondition: shouldCommentOnRelease ? undefined : false'),
`${releasercPath}: @semantic-release/github must gate successCommentCondition through shouldCommentOnRelease so prereleases don't re-comment on every PR after a stable -> main sync`,
);
}

if (usesLinearPlugin) {
assert.ok(
content.includes('addComment: shouldCommentOnRelease'),
`${releasercPath}: semantic-release-linear-app addComment must be gated through shouldCommentOnRelease so prereleases don't post duplicate Linear comments after a stable -> main sync`,
);
assert.equal(
content.includes('addComment: true'),
false,
`${releasercPath}: semantic-release-linear-app must not hardcode addComment: true`,
);
}
}
});

test('release-state probes wrap fetch in bounded retry to absorb transient blips', async () => {
const content = await readRepoFile('scripts/release-local-stable.mjs');
assert.ok(
Expand Down
Loading