From d8d27cab94c1693c465bf889a7fd5b366c7a533e Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 10 Jul 2025 07:06:28 +0000 Subject: [PATCH] fix(ng-dev): fix prerelease check in `cherryPickChangelogIntoNextBranch` Prerelease is not a boolean but rather an array. --- ng-dev/release/publish/actions.ts | 10 +-- ng-dev/release/publish/test/common.spec.ts | 81 ++++++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/ng-dev/release/publish/actions.ts b/ng-dev/release/publish/actions.ts index d77c7bc4a..1c4ce99a9 100644 --- a/ng-dev/release/publish/actions.ts +++ b/ng-dev/release/publish/actions.ts @@ -575,7 +575,8 @@ export abstract class ReleaseAction { stagingBranch: string, ): Promise { const nextBranch = this.active.next.branchName; - const commitMessage = getReleaseNoteCherryPickCommitMessage(releaseNotes.version); + const {version} = releaseNotes; + const commitMessage = getReleaseNoteCherryPickCommitMessage(version); // Checkout the next branch. await this.checkoutUpstreamBranch(nextBranch); @@ -583,7 +584,8 @@ export abstract class ReleaseAction { await this.prependReleaseNotesToChangelog(releaseNotes); const filesToCommit: string[] = [workspaceRelativeChangelogPath]; - if (releaseNotes.version.patch === 0 && !releaseNotes.version.prerelease) { + + if (version.patch === 0 && version.prerelease.length === 0) { // Switch the renovate labels for `target: rc` to `target: patch` const renovateConfigPath = await updateRenovateConfigTargetLabels( this.projectDir, @@ -597,12 +599,12 @@ export abstract class ReleaseAction { } await this.createCommit(commitMessage, filesToCommit); - Log.info(green(` ✓ Created changelog cherry-pick commit for: "${releaseNotes.version}".`)); + Log.info(green(` ✓ Created changelog cherry-pick commit for: "${version}".`)); // Create a cherry-pick pull request that should be merged by the caretaker. const pullRequest = await this.pushChangesToForkAndCreatePullRequest( nextBranch, - `changelog-cherry-pick-${releaseNotes.version}`, + `changelog-cherry-pick-${version}`, commitMessage, `Cherry-picks the changelog from the "${stagingBranch}" branch to the next ` + `branch (${nextBranch}).`, diff --git a/ng-dev/release/publish/test/common.spec.ts b/ng-dev/release/publish/test/common.spec.ts index f1517c3c1..3663d1bd4 100644 --- a/ng-dev/release/publish/test/common.spec.ts +++ b/ng-dev/release/publish/test/common.spec.ts @@ -582,6 +582,87 @@ describe('common release action logic', () => { }), ); }); + + it('should update the renovate config labels in the cherry-pick commit', async () => { + const baseReleaseTrains = new ActiveReleaseTrains({ + exceptionalMinor: null, + releaseCandidate: new ReleaseTrain('10.1.x', parse('10.1.0-rc.0')), + next: new ReleaseTrain('master', parse('10.2.0-next.0')), + latest: new ReleaseTrain('10.0.x', parse('10.0.0')), + }); + const {version, branchName} = baseReleaseTrains.latest; + const forkBranchName = `changelog-cherry-pick-${version}`; + + const {repo, fork, instance, gitClient, projectDir} = setupReleaseActionForTesting( + DelegateTestAction, + baseReleaseTrains, + ); + + // Expect the changelog to be fetched and return a fake changelog to test that + // it is properly appended. Also expect a pull request to be created in the fork. + repo + .expectFindForkRequest(fork) + .expectPullRequestToBeCreated('master', fork, forkBranchName, 200) + .expectPullRequestMergeCheck(200, false) + .expectPullRequestMerge(200); + + // Simulate that the fork branch name is available. + fork.expectBranchRequest(forkBranchName); + + const renovateConfigPath = join(projectDir, 'renovate.json'); + writeFileSync( + renovateConfigPath, + JSON.stringify({ + 'baseBranches': ['main', '20.1.x'], + 'packageRules': [ + { + 'matchBaseBranches': ['main'], + 'addLabels': ['target: minor'], + }, + { + 'matchBaseBranches': ['!main'], + 'addLabels': ['target: rc'], + }, + ], + }), + 'utf8', + ); + + await instance.testCherryPickWithPullRequest(version, branchName); + + expect(gitClient.pushed.length).toBe(1); + expect(gitClient.pushed[0]).toEqual( + getBranchPushMatcher({ + targetBranch: forkBranchName, + targetRepo: fork, + baseBranch: 'master', + baseRepo: repo, + expectedCommits: [ + { + message: `docs: release notes for the v${version} release`, + files: ['CHANGELOG.md', renovateConfigPath], + }, + ], + }), + ); + + // Verify renovate config contents + const {packageRules} = JSON.parse(readFileSync(renovateConfigPath, 'utf-8')) as Record< + string, + unknown + >; + + expect(packageRules).toEqual([ + { + 'matchBaseBranches': ['main'], + 'addLabels': ['target: minor'], + }, + { + 'matchBaseBranches': ['!main'], + 'addLabels': ['target: patch'], + }, + ]); + }); }); });