Skip to content

Commit 849553c

Browse files
Lee Troutclaude
andcommitted
feat: skip PR comment when no changes; add disable-no-changes-comment flag
- Add `disable-no-changes-comment` action input (default: false) that, when enabled, suppresses the PR comment only when there are no module changes and no legacy tags/releases pending deletion - Has no effect when there are changes to report — comments always post in that case Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent c78d892 commit 849553c

11 files changed

Lines changed: 2142 additions & 1044 deletions

File tree

__tests__/config.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ describe('config', () => {
338338
expect(config.disableWiki).toBe(false);
339339
expect(config.wikiSidebarChangelogMax).toBe(5);
340340
expect(config.disableBranding).toBe(false);
341+
expect(config.disableNoChangesComment).toBe(false);
341342
expect(config.githubToken).toBe('ghp_test_token_2c6912E7710c838347Ae178B4');
342343
expect(config.modulePathIgnore).toEqual([]);
343344
expect(config.moduleChangeExcludePatterns).toEqual(['.gitignore', '*.md', '*.tftest.hcl', 'tests/**']);
@@ -365,6 +366,7 @@ describe('config', () => {
365366
['Tag Directory Separator: /'],
366367
['Use Version Prefix: true'],
367368
['Module Ref Mode: tag'],
369+
['Disable No-Changes Comment: false'],
368370
]);
369371
});
370372
});

__tests__/main.test.ts

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ describe('main', () => {
6363
context.isPrMergeEvent = false;
6464
config.disableWiki = false;
6565
config.deleteLegacyTags = true;
66+
config.disableNoChangesComment = false;
6667

6768
// Reset mocks with default values
6869
vi.mocked(hasReleaseComment).mockResolvedValue(false);
@@ -228,7 +229,38 @@ describe('main', () => {
228229
vi.mocked(TerraformModule.getTagsToDelete).mockReturnValue([]);
229230
});
230231

231-
it('should handle non-merge event (pull request event)', async () => {
232+
it('should skip PR comment when no version changes and disable-no-changes-comment is true', async () => {
233+
config.disableNoChangesComment = true;
234+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([]);
235+
236+
await run();
237+
238+
expect(addReleasePlanComment).not.toHaveBeenCalled();
239+
expect(info).toHaveBeenCalledWith('No version changes detected. Skipping PR comment.');
240+
241+
// Should NOT call merge-specific functions
242+
expect(createTaggedReleases).not.toHaveBeenCalled();
243+
expect(addPostReleaseComment).not.toHaveBeenCalled();
244+
245+
// Should still set outputs
246+
expect(setOutput).toHaveBeenCalled();
247+
});
248+
249+
it('should skip PR comment when no module changes and delete-legacy-tags is disabled even with items to delete', async () => {
250+
config.disableNoChangesComment = true;
251+
config.deleteLegacyTags = false;
252+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([]);
253+
vi.spyOn(TerraformModule, 'getReleasesToDelete').mockReturnValue([{ id: 1, title: 'old', body: '', tagName: 'modules/old/v0' }]);
254+
vi.spyOn(TerraformModule, 'getTagsToDelete').mockReturnValue(['modules/old/v0']);
255+
256+
await run();
257+
258+
expect(addReleasePlanComment).not.toHaveBeenCalled();
259+
expect(info).toHaveBeenCalledWith('No version changes detected. Skipping PR comment.');
260+
});
261+
262+
it('should handle non-merge event (pull request event) when modules need release', async () => {
263+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([mockTerraformModuleNeedingRelease]);
232264
vi.mocked(getWikiStatus).mockReturnValue({ status: WIKI_STATUS.SUCCESS });
233265

234266
await run();
@@ -250,7 +282,65 @@ describe('main', () => {
250282
expect(setOutput).toHaveBeenCalled();
251283
});
252284

285+
it('should comment when no modules need release but there are releases to delete', async () => {
286+
const mockReleaseToDelete = { id: 99, title: 'old-release', body: '', tagName: 'old/v1.0.0' };
287+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([]);
288+
vi.mocked(TerraformModule.getReleasesToDelete).mockReturnValue([mockReleaseToDelete]);
289+
vi.mocked(getWikiStatus).mockReturnValue({ status: WIKI_STATUS.SUCCESS });
290+
291+
await run();
292+
293+
expect(addReleasePlanComment).toHaveBeenCalledWith([mockTerraformModule], [mockReleaseToDelete], [], {
294+
status: WIKI_STATUS.SUCCESS,
295+
});
296+
});
297+
298+
it('should comment when no modules need release but there are tags to delete', async () => {
299+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([]);
300+
vi.mocked(TerraformModule.getTagsToDelete).mockReturnValue(['old/v1.0.0']);
301+
vi.mocked(getWikiStatus).mockReturnValue({ status: WIKI_STATUS.SUCCESS });
302+
303+
await run();
304+
305+
expect(addReleasePlanComment).toHaveBeenCalledWith([mockTerraformModule], [], ['old/v1.0.0'], {
306+
status: WIKI_STATUS.SUCCESS,
307+
});
308+
});
309+
310+
it('should skip PR comment when disable-no-changes-comment is true and no changes', async () => {
311+
config.disableNoChangesComment = true;
312+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([]);
313+
314+
await run();
315+
316+
expect(addReleasePlanComment).not.toHaveBeenCalled();
317+
expect(info).toHaveBeenCalledWith('No version changes detected. Skipping PR comment.');
318+
});
319+
320+
it('should still post PR comment when disable-no-changes-comment is true but modules need release', async () => {
321+
config.disableNoChangesComment = true;
322+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([mockTerraformModuleNeedingRelease]);
323+
vi.mocked(getWikiStatus).mockReturnValue({ status: WIKI_STATUS.SUCCESS });
324+
325+
await run();
326+
327+
expect(addReleasePlanComment).toHaveBeenCalled();
328+
});
329+
330+
it('should still post PR comment when disable-no-changes-comment is true but there are legacy items to delete', async () => {
331+
config.disableNoChangesComment = true;
332+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([]);
333+
vi.mocked(TerraformModule.getReleasesToDelete).mockReturnValue([{ id: 99, title: 'old', body: '', tagName: 'old/v1.0.0' }]);
334+
vi.mocked(getWikiStatus).mockReturnValue({ status: WIKI_STATUS.SUCCESS });
335+
336+
await run();
337+
338+
expect(addReleasePlanComment).toHaveBeenCalled();
339+
});
340+
253341
it('should handle wiki checkout errors and add release plan comment', async () => {
342+
vi.mocked(TerraformModule.getModulesNeedingRelease).mockReturnValue([mockTerraformModuleNeedingRelease]);
343+
254344
const mockError: ExecSyncError = Object.assign(new Error('Wiki checkout failed\nAdditional error details'), {
255345
name: 'ExecSyncError',
256346
pid: 12345,

__tests__/utils/metadata.test.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ describe('utils/metadata', () => {
1919
'wiki-sidebar-changelog-max',
2020
'wiki-usage-template',
2121
'disable-branding',
22+
'disable-no-changes-comment',
2223
'module-path-ignore',
2324
'module-change-exclude-patterns',
2425
'module-asset-exclude-patterns',
@@ -59,6 +60,7 @@ describe('utils/metadata', () => {
5960
'delete-legacy-tags',
6061
'disable-wiki',
6162
'disable-branding',
63+
'disable-no-changes-comment',
6264
'use-ssh-source-format',
6365
'use-version-prefix',
6466
];
@@ -130,6 +132,7 @@ describe('utils/metadata', () => {
130132
'wiki-sidebar-changelog-max': 'wikiSidebarChangelogMax',
131133
'wiki-usage-template': 'wikiUsageTemplate',
132134
'disable-branding': 'disableBranding',
135+
'disable-no-changes-comment': 'disableNoChangesComment',
133136
'module-path-ignore': 'modulePathIgnore',
134137
'module-change-exclude-patterns': 'moduleChangeExcludePatterns',
135138
'module-asset-exclude-patterns': 'moduleAssetExcludePatterns',

action.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ inputs:
111111
or where third-party branding is undesirable.
112112
required: true
113113
default: "false"
114+
disable-no-changes-comment:
115+
description: >
116+
When set to true, suppresses the PR comment when there are no module changes and no legacy
117+
tags/releases to delete. Has no effect when there are changes to report; comments are always
118+
posted in that case. By default, this is false so a comment is always posted.
119+
required: true
120+
default: "false"
114121
module-path-ignore:
115122
description: >
116123
A comma-separated list of module paths to completely ignore during processing. Paths matching these patterns will

0 commit comments

Comments
 (0)