Skip to content

Commit

Permalink
feat(ng-dev): add safety checks for shallow repositories (#218)
Browse files Browse the repository at this point in the history
Adds safety checks for shallow repositories when executing
the merge or release publish script. These two commands
have similar checks on the local repository and these tools
act on the local repository as part of a common development
workflow where an error beforehand would be more useful.

PR Close #218
  • Loading branch information
devversion authored and josephperrott committed Sep 14, 2021
1 parent 284cb3d commit 7bdd465
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 7 deletions.
5 changes: 4 additions & 1 deletion github-actions/slash-commands/main.js

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions ng-dev/pr/merge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ export async function mergePullRequest(prNumber: number, flags: PullRequestMerge
),
);
return false;
case MergeStatus.UNEXPECTED_SHALLOW_REPO:
error(red(`Unable to perform merge in a local repository that is configured as shallow.`));
error(red(`Please convert the repository to a complete one by syncing with upstream.`));
error(red(`https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt---unshallow`));
return false;
case MergeStatus.UNKNOWN_GIT_ERROR:
error(
red(
Expand Down
13 changes: 9 additions & 4 deletions ng-dev/pr/merge/task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {AutosquashMergeStrategy} from './strategies/autosquash-merge';
export const enum MergeStatus {
UNKNOWN_GIT_ERROR,
DIRTY_WORKING_DIR,
UNEXPECTED_SHALLOW_REPO,
SUCCESS,
FAILED,
USER_ABORTED,
Expand Down Expand Up @@ -69,6 +70,14 @@ export class PullRequestMergeTask {
* @param force Whether non-critical pull request failures should be ignored.
*/
async merge(prNumber: number, force = false): Promise<MergeResult> {
if (this.git.hasUncommittedChanges()) {
return {status: MergeStatus.DIRTY_WORKING_DIR};
}

if (this.git.isShallowRepo()) {
return {status: MergeStatus.UNEXPECTED_SHALLOW_REPO};
}

// Check whether the given Github token has sufficient permissions for writing
// to the configured repository. If the repository is not private, only the
// reduced `public_repo` OAuth scope is sufficient for performing merges.
Expand Down Expand Up @@ -98,10 +107,6 @@ export class PullRequestMergeTask {
};
}

if (this.git.hasUncommittedChanges()) {
return {status: MergeStatus.DIRTY_WORKING_DIR};
}

const pullRequest = await loadAndValidatePullRequest(this, prNumber, force);

if (!isPullRequest(pullRequest)) {
Expand Down
19 changes: 18 additions & 1 deletion ng-dev/release/publish/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ export class ReleaseTool {

if (
!(await this._verifyNoUncommittedChanges()) ||
!(await this._verifyRunningFromNextBranch(nextBranchName))
!(await this._verifyRunningFromNextBranch(nextBranchName)) ||
!(await this._verifyNoShallowRepository())
) {
return CompletionState.FATAL_ERROR;
}
Expand Down Expand Up @@ -137,6 +138,22 @@ export class ReleaseTool {
return true;
}

/**
* Verifies that the local repository is not configured as shallow.
* @returns a boolean indicating success or failure.
*/
private async _verifyNoShallowRepository(): Promise<boolean> {
if (this._git.isShallowRepo()) {
error(red(' ✘ The local repository is configured as shallow.'));
error(red(` Please convert the repository to a complete one by syncing with upstream.`));
error(
red(` https://git-scm.com/docs/git-fetch#Documentation/git-fetch.txt---unshallow`),
);
return false;
}
return true;
}

/**
* Verifies that the next branch from the configured repository is checked out.
* @returns a boolean indicating success or failure.
Expand Down
5 changes: 5 additions & 0 deletions ng-dev/utils/git/git-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ export class GitClient {
return this.run(['branch', branchName, '--contains', sha]).stdout !== '';
}

/** Whether the local repository is configured as shallow. */
isShallowRepo(): boolean {
return this.run(['rev-parse', '--is-shallow-repository']).stdout.trim() === 'true';
}

/** Gets the currently checked out branch or revision. */
getCurrentBranchOrRevision(): string {
const branchName = this.run(['rev-parse', '--abbrev-ref', 'HEAD']).stdout.trim();
Expand Down
5 changes: 4 additions & 1 deletion tools/local-actions/changelog/main.js

Large diffs are not rendered by default.

0 comments on commit 7bdd465

Please sign in to comment.