Skip to content

Commit

Permalink
fix(ng-dev/release): run yarn integrity check before performing a rel…
Browse files Browse the repository at this point in the history
…ease

If the ng-dev command is run with an outdate version of the package, a dev may perform a release without
the latest changes to the tooling.  This can lead to not creating up to date artifacts and general issues.
By checking if the installed dependencies match the expected dependencies before performing the action we
can instruct the user to update their installed node_modules.

An example where this change would have prevented issue:
Framework releases from the patch branch which is currently a different version of the package as defined in
package.json. Calling them version 1 and version 2, with version 2 being the latest version. A patch release
is performed by checking out the latest commit from the upstream next branch, running yarn install and then
running ng-dev release publish.  This release process will occur using version 2 of the dev-infra package.
During the release process, the patch branch is checked out and yarn install is performed, causing version 1
to be installed.  Upon completion of the patch release, the next release is attempted unknowingly triggered
using version 1 of the package.  While generated artifacts are already ensured to built with the correct
dependency by the process, the tool itself is already running before this check can occur. Instead version 1
of the package is used to process the release, potentially resulting in an errant or unexpected process.

This situation will now be prevented by validating the expected version is being used for the action process,
in the situation above the user would be informed that yarn install was needed before performing the second
release.
  • Loading branch information
josephperrott committed Oct 13, 2021
1 parent a1b3152 commit a40a49c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
14 changes: 14 additions & 0 deletions ng-dev/release/publish/external-commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,17 @@ export async function invokeYarnInstallCommand(projectDir: string): Promise<void
throw new FatalReleaseActionError();
}
}

/**
* Invokes the `yarn check --integrity` command in order to verify up to date dependencies.
*/
export async function invokeYarnIntegryCheck(projectDir: string): Promise<void> {
try {
await spawn('yarn', ['check', '--integrity'], {cwd: projectDir, mode: 'silent'});
info(green(' ✓ Confirmed installed dependencies match those defined in package.json.'));
} catch (e) {
error(red(' ✘ Failed yarn integrity check, your installed dependencies are likely out of'));
error(red(' date. Please run `yarn install` to update your installed dependencies.'));
throw new FatalReleaseActionError();
}
}
18 changes: 17 additions & 1 deletion ng-dev/release/publish/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {getNextBranchName, ReleaseRepoWithApi} from '../versioning/version-branc
import {ReleaseAction} from './actions';
import {FatalReleaseActionError, UserAbortedReleaseActionError} from './actions-error';
import {actions} from './actions/index';
import {invokeYarnIntegryCheck} from './external-commands';

export enum CompletionState {
SUCCESS,
Expand Down Expand Up @@ -51,7 +52,8 @@ export class ReleaseTool {
if (
!(await this._verifyNoUncommittedChanges()) ||
!(await this._verifyRunningFromNextBranch(nextBranchName)) ||
!(await this._verifyNoShallowRepository())
!(await this._verifyNoShallowRepository()) ||
!(await this._verifyInstalledDependenciesAreUpToDate())
) {
return CompletionState.FATAL_ERROR;
}
Expand Down Expand Up @@ -144,6 +146,20 @@ export class ReleaseTool {
return true;
}

/**
* Verifiy that the install dependencies match the the versions defined in the package.json and
* yarn.lock files.
* @returns a boolean indicating success or failure.
*/
private async _verifyInstalledDependenciesAreUpToDate(): Promise<boolean> {
try {
await invokeYarnIntegryCheck(this._projectRoot);
return true;
} catch {
return false;
}
}

/**
* Verifies that the local repository is not configured as shallow.
* @returns a boolean indicating success or failure.
Expand Down

0 comments on commit a40a49c

Please sign in to comment.