Skip to content

Commit 289aa64

Browse files
authored
feat(ng-dev): support releasing when operating in a hybrid pnpm rules_js repo (#2514)
* feat(ng-dev): support releasing when operating in a hybrid pnpm rules_js repo Updating the `package.json` for a release also requires updating some Aspect lock files that capture the hash of the `package.json` file. The release tool currently doesn't do this, and some tricky manual workaround steps are needed. This commit automatically runs the sync command. * fixup! feat(ng-dev): support releasing when operating in a hybrid pnpm rules_js repo Feedback
1 parent 36b7540 commit 289aa64

File tree

4 files changed

+49
-6
lines changed

4 files changed

+49
-6
lines changed

ng-dev/release/config/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ export interface ReleaseConfig {
6161
newVersion: string,
6262
builtPackagesWithInfo: BuiltPackageWithInfo[],
6363
) => Promise<void>;
64+
65+
/**
66+
* Whether the repository is in rules_js interop mode, relying on
67+
* integrity files to be automatically updated.
68+
*/
69+
rulesJsInteropMode?: boolean;
6470
}
6571

6672
/**

ng-dev/release/publish/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ ts_library(
2323
"@npm//@types/semver",
2424
"@npm//@types/yargs",
2525
"@npm//ejs",
26+
"@npm//fast-glob",
2627
"@npm//folder-hash",
2728
"@npm//semver",
2829
"@npm//typed-graphqlify",

ng-dev/release/publish/actions.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {promises as fs} from 'fs';
10-
import {join} from 'path';
9+
import {promises as fs, existsSync} from 'fs';
10+
import path, {join} from 'path';
1111
import semver from 'semver';
1212

1313
import {workspaceRelativePackageJsonPath} from '../../utils/constants.js';
@@ -41,6 +41,7 @@ import {githubReleaseBodyLimit} from './constants.js';
4141
import {ExternalCommands} from './external-commands.js';
4242
import {promptToInitiatePullRequestMerge} from './prompt-merge.js';
4343
import {Prompt} from '../../utils/prompt.js';
44+
import {glob} from 'fast-glob';
4445

4546
/** Interface describing a Github repository. */
4647
export interface GithubRepo {
@@ -129,6 +130,10 @@ export abstract class ReleaseAction {
129130
// to avoid unnecessary diff. IDEs usually add a trailing new line.
130131
await fs.writeFile(pkgJsonPath, `${JSON.stringify(pkgJson, null, 2)}\n`);
131132
Log.info(green(` ✓ Updated project version to ${pkgJson.version}`));
133+
134+
if (this.config.rulesJsInteropMode && existsSync(path.join(this.projectDir, '.aspect'))) {
135+
await ExternalCommands.invokeBazelUpdateAspectLockFiles(this.projectDir);
136+
}
132137
}
133138

134139
/** Gets the most recent commit of a specified branch. */
@@ -217,11 +222,16 @@ export abstract class ReleaseAction {
217222
// Commit message for the release point.
218223
const commitMessage = getCommitMessageForRelease(newVersion);
219224

225+
const filesToCommit = [workspaceRelativePackageJsonPath, workspaceRelativeChangelogPath];
226+
227+
// Ensure modified Aspect lock files are included in the release commit.
228+
// TODO: Remove after `rules_js` migration is complete.
229+
if (this.config.rulesJsInteropMode) {
230+
filesToCommit.push(...glob.sync(['.aspect/**', 'pnpm-lock.yaml'], {cwd: this.projectDir}));
231+
}
232+
220233
// Create a release staging commit including changelog and version bump.
221-
await this.createCommit(commitMessage, [
222-
workspaceRelativePackageJsonPath,
223-
workspaceRelativeChangelogPath,
224-
]);
234+
await this.createCommit(commitMessage, filesToCommit);
225235

226236
// The caretaker may have attempted to make additional changes. These changes would
227237
// not be captured into the release commit. The working directory should remain clean,

ng-dev/release/publish/external-commands.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,30 @@ export abstract class ExternalCommands {
256256
throw new FatalReleaseActionError();
257257
}
258258
}
259+
260+
/**
261+
* Invokes the `yarn bazel run @npm2//:sync` command in order
262+
* to refresh Aspect lock files.
263+
*/
264+
static async invokeBazelUpdateAspectLockFiles(projectDir: string): Promise<void> {
265+
// Note: We cannot use `yarn` directly as command because we might operate in
266+
// a different publish branch and the current `PATH` will point to the Yarn version
267+
// that invoked the release tool. More details in the function description.
268+
const yarnCommand = await resolveYarnScriptForProject(projectDir);
269+
270+
try {
271+
// Note: No progress indicator needed as that is the responsibility of the command.
272+
// TODO: Consider using an Ora spinner instead to ensure minimal console output.
273+
await ChildProcess.spawn(
274+
yarnCommand.binary,
275+
[...yarnCommand.args, 'bazelisk', 'run', '@npm2//:sync'],
276+
{cwd: projectDir},
277+
);
278+
} catch (e) {
279+
// Note: Gracefully handling these errors because `sync` command
280+
// alway exits with a non-zero exit code.
281+
}
282+
283+
Log.info(green(' ✓ Updated Aspect `rules_js` lock files.'));
284+
}
259285
}

0 commit comments

Comments
 (0)