From fba70ca56376664d055074123bdfa0f446036b85 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 20 Aug 2025 06:38:19 +0000 Subject: [PATCH] feat(ng-dev): handle updating the `MODULE.bazel.lock` file during a release This lock has contains hashes of the package.json file. Thus it needs to be updated once the version is updating during the release. --- ng-dev/release/publish/actions.ts | 23 ++++++++++++++++++- .../actions/configure-next-as-major.ts | 12 ++++++++-- .../prepare-exceptional-minor.ts | 14 +++++++++-- .../actions/shared/branch-off-next-branch.ts | 5 ++++ ng-dev/release/publish/external-commands.ts | 20 +++++++++++++++- ng-dev/utils/constants.ts | 3 +++ 6 files changed, 71 insertions(+), 6 deletions(-) diff --git a/ng-dev/release/publish/actions.ts b/ng-dev/release/publish/actions.ts index 45919beaa..329fcd729 100644 --- a/ng-dev/release/publish/actions.ts +++ b/ng-dev/release/publish/actions.ts @@ -10,7 +10,10 @@ import {promises as fs, existsSync} from 'fs'; import path, {join} from 'path'; import semver from 'semver'; -import {workspaceRelativePackageJsonPath} from '../../utils/constants.js'; +import { + workspaceRelativeBazelModuleLock, + workspaceRelativePackageJsonPath, +} from '../../utils/constants.js'; import {AuthenticatedGitClient} from '../../utils/git/authenticated-git-client.js'; import {isGithubApiError} from '../../utils/git/github.js'; import githubMacros from '../../utils/git/github-macros.js'; @@ -140,6 +143,10 @@ export abstract class ReleaseAction { if (this.config.rulesJsInteropMode && existsSync(path.join(this.projectDir, '.aspect'))) { await ExternalCommands.invokeBazelUpdateAspectLockFiles(this.projectDir); } + + if (existsSync(join(this.projectDir, workspaceRelativeBazelModuleLock))) { + await ExternalCommands.invokeBazelModDepsUpdate(this.projectDir); + } } /* @@ -152,6 +159,15 @@ export abstract class ReleaseAction { : []; } + /* + * Get the modified "MODULE.bazel.lock" if bazel modules are enabled. + */ + protected getModuleBazelLockFile(): string | undefined { + return existsSync(join(this.projectDir, workspaceRelativeBazelModuleLock)) + ? workspaceRelativeBazelModuleLock + : undefined; + } + /** Gets the most recent commit of a specified branch. */ protected async getLatestCommitOfBranch(branchName: string): Promise { const { @@ -225,6 +241,11 @@ export abstract class ReleaseAction { ...this.getAspectLockFiles(), ]; + const bazelModuleLockFile = this.getModuleBazelLockFile(); + if (bazelModuleLockFile) { + filesToCommit.push(bazelModuleLockFile); + } + const commitMessage = getCommitMessageForRelease(newVersion); // Create a release staging commit including changelog and version bump. diff --git a/ng-dev/release/publish/actions/configure-next-as-major.ts b/ng-dev/release/publish/actions/configure-next-as-major.ts index d829f239f..f6330d1e9 100644 --- a/ng-dev/release/publish/actions/configure-next-as-major.ts +++ b/ng-dev/release/publish/actions/configure-next-as-major.ts @@ -39,10 +39,18 @@ export class ConfigureNextAsMajorAction extends ReleaseAction { await this.checkoutUpstreamBranch(branchName); await this.updateProjectVersion(newVersion); - await this.createCommit(getCommitMessageForNextBranchMajorSwitch(newVersion), [ + const filesToCommit: string[] = [ workspaceRelativePackageJsonPath, ...this.getAspectLockFiles(), - ]); + ]; + + const bazelModuleLockFile = this.getModuleBazelLockFile(); + if (bazelModuleLockFile) { + filesToCommit.push(bazelModuleLockFile); + } + + await this.createCommit(getCommitMessageForNextBranchMajorSwitch(newVersion), filesToCommit); + const pullRequest = await this.pushChangesToForkAndCreatePullRequest( branchName, `switch-next-to-major-${newVersion}`, diff --git a/ng-dev/release/publish/actions/exceptional-minor/prepare-exceptional-minor.ts b/ng-dev/release/publish/actions/exceptional-minor/prepare-exceptional-minor.ts index 69119ad25..7242b6369 100644 --- a/ng-dev/release/publish/actions/exceptional-minor/prepare-exceptional-minor.ts +++ b/ng-dev/release/publish/actions/exceptional-minor/prepare-exceptional-minor.ts @@ -49,10 +49,20 @@ export class PrepareExceptionalMinorAction extends ReleaseAction { pkgJson[exceptionalMinorPackageIndicator] = true; }); - await this.createCommit(`build: prepare exceptional minor branch: ${this._newBranch}`, [ + const filesToCommit: string[] = [ workspaceRelativePackageJsonPath, ...this.getAspectLockFiles(), - ]); + ]; + + const bazelModuleLockFile = this.getModuleBazelLockFile(); + if (bazelModuleLockFile) { + filesToCommit.push(bazelModuleLockFile); + } + + await this.createCommit( + `build: prepare exceptional minor branch: ${this._newBranch}`, + filesToCommit, + ); await this.pushHeadToRemoteBranch(this._newBranch); diff --git a/ng-dev/release/publish/actions/shared/branch-off-next-branch.ts b/ng-dev/release/publish/actions/shared/branch-off-next-branch.ts index a21bcd31d..bb819a0b7 100644 --- a/ng-dev/release/publish/actions/shared/branch-off-next-branch.ts +++ b/ng-dev/release/publish/actions/shared/branch-off-next-branch.ts @@ -145,6 +145,11 @@ export abstract class BranchOffNextBranchBaseAction extends CutNpmNextPrerelease ...this.getAspectLockFiles(), ]; + const bazelModuleLockFile = this.getModuleBazelLockFile(); + if (bazelModuleLockFile) { + filesToCommit.push(bazelModuleLockFile); + } + const renovateConfigPath = await updateRenovateConfig( this.projectDir, `${version.major}.${version.minor}.x`, diff --git a/ng-dev/release/publish/external-commands.ts b/ng-dev/release/publish/external-commands.ts index 33e09253d..fef418664 100644 --- a/ng-dev/release/publish/external-commands.ts +++ b/ng-dev/release/publish/external-commands.ts @@ -7,7 +7,6 @@ */ import semver from 'semver'; - import {ChildProcess, SpawnResult, SpawnOptions} from '../../utils/child-process.js'; import {Spinner} from '../../utils/spinner.js'; import {NpmDistTag} from '../versioning/index.js'; @@ -263,6 +262,25 @@ export abstract class ExternalCommands { } } + /** + * Invokes the `bazel mod deps --lockfile_mode=update` command in order + * to refresh `MODULE.bazel.lock` file. + */ + static async invokeBazelModDepsUpdate(projectDir: string): Promise { + const spinner = new Spinner('Updating "MODULE.bazel.lock"'); + try { + await ChildProcess.spawn(getBazelBin(), ['mod', 'deps', '--lockfile_mode=update'], { + cwd: projectDir, + mode: 'silent', + }); + } catch (e) { + Log.error(e); + Log.error(' ✘ An error occurred while updating "MODULE.bazel.lock".'); + throw new FatalReleaseActionError(); + } + spinner.success(green(' Updated "MODULE.bazel.lock" file.')); + } + /** * Invokes the `yarn bazel sync --only=repo` command in order * to refresh Aspect lock files. diff --git a/ng-dev/utils/constants.ts b/ng-dev/utils/constants.ts index 9ddac8b9e..77301c4d3 100644 --- a/ng-dev/utils/constants.ts +++ b/ng-dev/utils/constants.ts @@ -11,3 +11,6 @@ export const ngDevNpmPackageName = '@angular/ng-dev'; /** Workspace-relative path for the "package.json" file. */ export const workspaceRelativePackageJsonPath = 'package.json'; + +/** Workspace-relative path for the "MODULE.bazel.lock" file. */ +export const workspaceRelativeBazelModuleLock = 'MODULE.bazel.lock';