diff --git a/src/bin/release-please.ts b/src/bin/release-please.ts index 39aa9cd42..2ee885454 100644 --- a/src/bin/release-please.ts +++ b/src/bin/release-please.ts @@ -878,7 +878,7 @@ interface HandleError { } function extractManifestOptions( - argv: GitHubArgs & (PullRequestArgs | ReleaseArgs) + argv: GitHubArgs & (PullRequestArgs | ReleaseArgs) & Partial ): ManifestOptions { const manifestOptions: ManifestOptions = {}; if ('fork' in argv && argv.fork !== undefined) { @@ -907,6 +907,12 @@ function extractManifestOptions( if ('draftPullRequest' in argv && argv.draftPullRequest !== undefined) { manifestOptions.draftPullRequest = argv.draftPullRequest; } + if ('latestTagVersion' in argv && argv.latestTagVersion) { + manifestOptions.latestTagVersion = argv.latestTagVersion; + } + if ('latestTagSha' in argv && argv.latestTagSha) { + manifestOptions.lastReleaseSha = argv.latestTagSha; + } return manifestOptions; } diff --git a/src/manifest.ts b/src/manifest.ts index d4d453a07..2b598a2b3 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -194,6 +194,7 @@ interface ReleaserConfigJson { export interface ManifestOptions { bootstrapSha?: string; lastReleaseSha?: string; + latestTagVersion?: string; alwaysLinkLocal?: boolean; separatePullRequests?: boolean; plugins?: PluginType[]; @@ -437,6 +438,15 @@ export class Manifest { parseConfig(github, configFile, targetBranch, path, releaseAs), parseReleasedVersions(github, manifestFile, targetBranch), ]); + + // Override releasedVersions if latestTagVersion is provided via CLI + if (manifestOptionOverrides?.latestTagVersion) { + const targetPath = path || ROOT_PROJECT_PATH; + releasedVersions[targetPath] = Version.parse( + manifestOptionOverrides.latestTagVersion + ); + } + return new Manifest( github, targetBranch, @@ -492,14 +502,19 @@ export class Manifest { }); const component = await strategy.getBranchComponent(); const releasedVersions: ReleasedVersions = {}; - const latestVersion = await latestReleaseVersion( - github, - targetBranch, - version => isPublishedVersion(strategy, version), - config, - component, - manifestOptions?.logger - ); + let latestVersion: Version | undefined; + if (manifestOptions?.latestTagVersion) { + latestVersion = Version.parse(manifestOptions.latestTagVersion); + } else { + latestVersion = await latestReleaseVersion( + github, + targetBranch, + version => isPublishedVersion(strategy, version), + config, + component, + manifestOptions?.logger + ); + } if (latestVersion) { releasedVersions[path] = latestVersion; } diff --git a/test/manifest.ts b/test/manifest.ts index 90470b7e6..f47c16da9 100644 --- a/test/manifest.ts +++ b/test/manifest.ts @@ -918,6 +918,61 @@ describe('Manifest', () => { expect(manifest.repositoryConfig['node-packages'].draftPullRequest).to.be .false; }); + it('should override releasedVersions with latestTagVersion', async () => { + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('release-please-config.json', 'main') + .resolves( + buildGitHubFileContent(fixturesPath, 'manifest/config/simple.json') + ) + .withArgs('.release-please-manifest.json', 'main') + .resolves( + buildGitHubFileRaw('{".":" 0.0.0"}') + ); + const manifest = await Manifest.fromManifest( + github, + github.repository.defaultBranch, + undefined, + undefined, + {latestTagVersion: '1.2.3'} + ); + expect(manifest.releasedVersions['.']).to.not.be.undefined; + expect(manifest.releasedVersions['.'].toString()).to.eql('1.2.3'); + }); + it('should override releasedVersions for specific path with latestTagVersion', async () => { + const getFileContentsStub = sandbox.stub( + github, + 'getFileContentsOnBranch' + ); + getFileContentsStub + .withArgs('release-please-config.json', 'main') + .resolves( + buildGitHubFileContent(fixturesPath, 'manifest/config/config.json') + ) + .withArgs('.release-please-manifest.json', 'main') + .resolves( + buildGitHubFileContent( + fixturesPath, + 'manifest/versions/versions.json' + ) + ); + const manifest = await Manifest.fromManifest( + github, + github.repository.defaultBranch, + undefined, + undefined, + {latestTagVersion: '5.0.0'}, + 'packages/gcf-utils' + ); + expect(manifest.releasedVersions['packages/gcf-utils']).to.not.be + .undefined; + expect( + manifest.releasedVersions['packages/gcf-utils'].toString() + ).to.eql('5.0.0'); + }); }); describe('fromConfig', () => { @@ -1525,6 +1580,22 @@ describe('Manifest', () => { scope.done(); sinon.assert.callCount(sleepStub, 5); }); + it('should use latestTagVersion from manifestOptions if provided', async () => { + // No mocks for commits/releases needed since latestTagVersion bypasses discovery + const manifest = await Manifest.fromConfig( + github, + 'target-branch', + { + releaseType: 'simple', + }, + { + latestTagVersion: '2.3.4', + } + ); + expect(Object.keys(manifest.repositoryConfig)).lengthOf(1); + expect(Object.keys(manifest.releasedVersions)).lengthOf(1); + expect(manifest.releasedVersions['.'].toString()).to.equal('2.3.4'); + }); }); describe('buildPullRequests', () => {