diff --git a/docs/manifest-releaser.md b/docs/manifest-releaser.md index eec9676c5..2fa24a4b7 100644 --- a/docs/manifest-releaser.md +++ b/docs/manifest-releaser.md @@ -122,7 +122,7 @@ documented in comments) // absence defaults to [] (i.e. no plugins) "plugins": ["node-workspace", "cargo-workspace"], - // optional top-level defaults that can be overriden per package: + // optional top-level defaults that can be overridden per package: // set default package release-type to "python" // absence defaults to "node" @@ -153,6 +153,10 @@ documented in comments) // absence defaults to false and Releases are created as already Published. "draft": true + // Skip creating GitHub Releases + // absence defaults to false and Releases will be created + "skip-github-release": true, + // when using the `node-workspace` plugin, package discovery forces all // local dependencies to be linked, even if the SemVer ranges don't match. // this allows breaking version bumps to update during a release. diff --git a/src/index.ts b/src/index.ts index 42d106b67..9bdb29bbb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,6 +35,7 @@ interface GitHubOptions { export interface GitHubReleaseOptions { releaseLabel?: string; draft?: boolean; + skipGithubRelease?: boolean; } // Used by ReleasePR: Factory and Constructor @@ -103,6 +104,7 @@ export type ManifestPackage = Pick< | 'releaseAs' | 'changelogSections' | 'changelogPath' + | 'skipGithubRelease' > & { // these items are not optional in the manifest context. path: string; diff --git a/src/manifest.ts b/src/manifest.ts index 03d8ff23b..d4249ee8d 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -50,6 +50,7 @@ interface ReleaserConfigJson { 'bump-patch-for-minor-pre-major'?: boolean; 'changelog-sections'?: ChangelogSection[]; 'release-as'?: string; + 'skip-github-release'?: boolean; draft?: boolean; } @@ -244,6 +245,10 @@ export class Manifest { config['release-as'] ), draft: pkgCfg['draft'] ?? config['draft'], + skipGithubRelease: + pkgCfg['skip-github-release'] ?? + config['skip-github-release'] ?? + false, }; packages.push(pkg); } @@ -714,6 +719,14 @@ export class Manifest { releases[pkg.config.path] = undefined; continue; } + if (pkg.config.skipGithubRelease) { + this.gh.commentOnIssue( + `:robot: ${pkgName} not configured for release :no_entry_sign:`, + lastMergedPR.number + ); + releases[pkg.config.path] = undefined; + continue; + } this.checkpoint( 'Creating release for ' + `${pkgLogDisp}@${pkg.lastVersion}`, CheckpointType.Success diff --git a/test/manifest.ts b/test/manifest.ts index aecd8ade4..122709a26 100644 --- a/test/manifest.ts +++ b/test/manifest.ts @@ -2056,6 +2056,56 @@ describe('Manifest', () => { }, }); }); + + it('"skip-github-release" option works', async () => { + const manifest = JSON.stringify({ + 'node/pkg1': '3.2.1', + }); + const config = JSON.stringify({ + packages: { + 'node/pkg1': { + 'skip-github-release': true, + }, + }, + }); + const github = new GitHub({ + owner: 'fake', + repo: 'repo', + defaultBranch, + }); + const mock = mockGithub(github); + expectManifest(mock, {manifest, lastReleaseSha}); + expectPR(mock, { + lastReleaseSha, + mergedPRFiles: [ + // lack of any "node/pkg2/ files indicates that package did not + // change in the last merged PR. + 'node/pkg1/package.json', + 'node/pkg1/CHANGELOG.md', + '.release-please-manifest.json', + ], + }); + expectGetFiles(mock, { + fixtureFiles: ['node/pkg1/package.json'], + inlineFiles: [ + ['release-please-config.json', config], + ['.release-please-manifest.json', manifest], + ], + }); + expectLabelAndComment(mock, { + addLabel: 'autorelease: tagged', + removeLabel: 'autorelease: pending', + prComments: [ + ':robot: @node/pkg1 not configured for release :no_entry_sign:', + ], + }); + + const releases = await new Manifest({github}).githubRelease(); + mock.verify(); + expect(releases).to.eql({ + 'node/pkg1': undefined, + }); + }); }); describe('validate', () => {