Skip to content

Commit

Permalink
refactor(workers): Use limiting API for PRs instead of in-place count…
Browse files Browse the repository at this point in the history
…ers (#8031)
  • Loading branch information
zharinov committed Dec 16, 2020
1 parent 14166e9 commit 62c68d0
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 61 deletions.
15 changes: 11 additions & 4 deletions lib/workers/branch/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { PrState } from '../../types';
import * as _exec from '../../util/exec';
import { File, StatusResult } from '../../util/git';
import { BranchConfig, PrResult, ProcessBranchResult } from '../common';
import * as _limits from '../global/limits';
import * as _prWorker from '../pr';
import * as _automerge from './automerge';
import * as _checkExisting from './check-existing';
Expand All @@ -29,6 +30,7 @@ jest.mock('../pr');
jest.mock('../../util/exec');
jest.mock('../../util/git');
jest.mock('fs-extra');
jest.mock('../global/limits');

const getUpdated = mocked(_getUpdated);
const schedule = mocked(_schedule);
Expand All @@ -40,6 +42,7 @@ const commit = mocked(_commit);
const prWorker = mocked(_prWorker);
const exec = mocked(_exec);
const fs = mocked(_fs);
const limits = mocked(_limits);

describe('workers/branch', () => {
describe('processBranch', () => {
Expand Down Expand Up @@ -215,8 +218,9 @@ describe('workers/branch', () => {
artifactErrors: [],
updatedArtifacts: [],
});
git.branchExists.mockReturnValue(false);
expect(await branchWorker.processBranch(config, true)).toEqual(
limits.isLimitReached.mockReturnValueOnce(true);
limits.isLimitReached.mockReturnValueOnce(false);
expect(await branchWorker.processBranch(config)).toEqual(
ProcessBranchResult.PrLimitReached
);
});
Expand All @@ -232,7 +236,8 @@ describe('workers/branch', () => {
prWorker.ensurePr.mockResolvedValueOnce({
prResult: PrResult.LimitReached,
});
expect(await branchWorker.processBranch(config, true)).toEqual(
limits.isLimitReached.mockReturnValue(false);
expect(await branchWorker.processBranch(config)).toEqual(
ProcessBranchResult.PrLimitReached
);
});
Expand All @@ -245,7 +250,9 @@ describe('workers/branch', () => {
updatedArtifacts: [],
});
git.branchExists.mockReturnValue(false);
expect(await branchWorker.processBranch(config, false, true)).toEqual(
limits.isLimitReached.mockReturnValueOnce(false);
limits.isLimitReached.mockReturnValueOnce(true);
expect(await branchWorker.processBranch(config)).toEqual(
ProcessBranchResult.CommitLimitReached
);
});
Expand Down
11 changes: 5 additions & 6 deletions lib/workers/branch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import {
import { regEx } from '../../util/regex';
import * as template from '../../util/template';
import { BranchConfig, PrResult, ProcessBranchResult } from '../common';
import { Limit, isLimitReached } from '../global/limits';
import { checkAutoMerge, ensurePr, getPlatformPrOptions } from '../pr';
import { tryBranchAutomerge } from './automerge';
import { prAlreadyExisted } from './check-existing';
Expand Down Expand Up @@ -60,9 +61,7 @@ async function deleteBranchSilently(branchName: string): Promise<void> {
}

export async function processBranch(
branchConfig: BranchConfig,
prLimitReached?: boolean,
commitLimitReached?: boolean
branchConfig: BranchConfig
): Promise<ProcessBranchResult> {
const config: BranchConfig = { ...branchConfig };
const dependencies = config.upgrades
Expand Down Expand Up @@ -153,15 +152,15 @@ export async function processBranch(
}
if (
!branchExists &&
prLimitReached &&
isLimitReached(Limit.PullRequests) &&
!dependencyDashboardCheck &&
!config.vulnerabilityAlert
) {
logger.debug('Reached PR limit - skipping branch creation');
return ProcessBranchResult.PrLimitReached;
}
if (
commitLimitReached &&
isLimitReached(Limit.Commits) &&
!dependencyDashboardCheck &&
!config.vulnerabilityAlert
) {
Expand Down Expand Up @@ -583,7 +582,7 @@ export async function processBranch(
logger.debug(
`There are ${config.errors.length} errors and ${config.warnings.length} warnings`
);
const { prResult: result, pr } = await ensurePr(config, prLimitReached);
const { prResult: result, pr } = await ensurePr(config);
if (result === PrResult.LimitReached) {
logger.debug('Reached PR limit - skipping PR creation');
return ProcessBranchResult.PrLimitReached;
Expand Down
1 change: 1 addition & 0 deletions lib/workers/global/limits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { logger } from '../../logger';

export enum Limit {
Commits = 'Commits',
PullRequests = 'PullRequests',
}

interface LimitValue {
Expand Down
18 changes: 10 additions & 8 deletions lib/workers/pr/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { PLATFORM_TYPE_GITLAB } from '../../constants/platforms';
import { Pr, platform as _platform } from '../../platform';
import { BranchStatus } from '../../types';
import { BranchConfig, PrResult } from '../common';
import * as _limits from '../global/limits';
import * as _changelogHelper from './changelog';
import { getChangeLogJSON } from './changelog';
import * as codeOwners from './code-owners';
Expand All @@ -14,10 +15,12 @@ const changelogHelper = mocked(_changelogHelper);
const gitlabChangelogHelper = mocked(_changelogHelper);
const platform = mocked(_platform);
const defaultConfig = getConfig();
const limits = mocked(_limits);

jest.mock('../../util/git');
jest.mock('./changelog');
jest.mock('./code-owners');
jest.mock('../global/limits');

function setupChangelogMock() {
changelogHelper.getChangeLogJSON = jest.fn();
Expand Down Expand Up @@ -268,7 +271,8 @@ describe('workers/pr', () => {
config.prCreation = 'status-success';
config.automerge = true;
config.schedule = ['before 5am'];
const { prResult } = await prWorker.ensurePr(config, true);
limits.isLimitReached.mockReturnValueOnce(true);
const { prResult } = await prWorker.ensurePr(config);
expect(prResult).toEqual(PrResult.LimitReached);
expect(platform.createPr.mock.calls).toBeEmpty();
});
Expand All @@ -278,13 +282,11 @@ describe('workers/pr', () => {
config.prCreation = 'status-success';
config.automerge = true;
config.schedule = ['before 5am'];
const { prResult } = await prWorker.ensurePr(
{
...config,
dependencyDashboardChecks: { 'renovate/dummy-1.x': 'true' },
},
true
);
limits.isLimitReached.mockReturnValueOnce(true);
const { prResult } = await prWorker.ensurePr({
...config,
dependencyDashboardChecks: { 'renovate/dummy-1.x': 'true' },
});
expect(prResult).toEqual(PrResult.Created);
expect(platform.createPr).toHaveBeenCalled();
});
Expand Down
6 changes: 3 additions & 3 deletions lib/workers/pr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
isBranchModified,
} from '../../util/git';
import { BranchConfig, PrResult } from '../common';
import { Limit, isLimitReached } from '../global/limits';
import { getPrBody } from './body';
import { ChangeLogError } from './changelog';
import { codeOwnersForPr } from './code-owners';
Expand Down Expand Up @@ -114,8 +115,7 @@ export function getPlatformPrOptions(

// Ensures that PR exists with matching title/body
export async function ensurePr(
prConfig: BranchConfig,
prLimitReached?: boolean
prConfig: BranchConfig
): Promise<{
prResult: PrResult;
pr?: Pr;
Expand Down Expand Up @@ -381,7 +381,7 @@ export async function ensurePr(
logger.info('DRY-RUN: Would create PR: ' + prTitle);
pr = { number: 0, displayNumber: 'Dry run PR' } as never;
} else {
if (!dependencyDashboardCheck && prLimitReached) {
if (!dependencyDashboardCheck && isLimitReached(Limit.PullRequests)) {
return { prResult: PrResult.LimitReached };
}
pr = await platform.createPr({
Expand Down
32 changes: 11 additions & 21 deletions lib/workers/repository/process/write.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { RenovateConfig, getConfig, git, mocked } from '../../../../test/util';
import * as _branchWorker from '../../branch';
import { BranchConfig, ProcessBranchResult } from '../../common';
import { Limit, isLimitReached } from '../../global/limits';
import * as _limits from './limits';
import { writeUpdates } from './write';

Expand Down Expand Up @@ -57,28 +58,17 @@ describe('workers/repository/write', () => {
expect(res).toEqual('automerged');
expect(branchWorker.processBranch).toHaveBeenCalledTimes(4);
});
it('counts created branches', async () => {
const branches: BranchConfig[] = [
{ res: ProcessBranchResult.Pending, expect: false },
{ res: ProcessBranchResult.PrLimitReached, expect: true },
] as never;
limits.getPrsRemaining.mockResolvedValueOnce(1);

branches.forEach(({ res, expect: limitReached }) => {
branchWorker.processBranch.mockResolvedValueOnce(res);
git.branchExists.mockReturnValueOnce(false);
git.branchExists.mockReturnValueOnce(!limitReached as never);
});

await writeUpdates(config, branches);

branches.forEach((branch) =>
expect(branchWorker.processBranch).toHaveBeenCalledWith(
branch,
branch.expect,
false
)
it('increments branch counter', async () => {
const branches: BranchConfig[] = [{}] as never;
branchWorker.processBranch.mockResolvedValueOnce(
ProcessBranchResult.Pending
);
git.branchExists.mockReturnValueOnce(false);
git.branchExists.mockReturnValueOnce(true);
limits.getPrsRemaining.mockResolvedValueOnce(1);
expect(isLimitReached(Limit.PullRequests)).toBeFalse();
await writeUpdates({ config }, branches);
expect(isLimitReached(Limit.PullRequests)).toBeTrue();
});
});
});
30 changes: 11 additions & 19 deletions lib/workers/repository/process/write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { PrState } from '../../../types';
import { branchExists } from '../../../util/git';
import { processBranch } from '../../branch';
import { BranchConfig, ProcessBranchResult } from '../../common';
import { Limit, isLimitReached } from '../../global/limits';
import { Limit, incLimitedValue, setMaxLimit } from '../../global/limits';
import { getPrsRemaining } from './limits';

export type WriteUpdateResult = 'done' | 'automerged';
Expand Down Expand Up @@ -39,15 +39,14 @@ export async function writeUpdates(
}
return true;
});
let prsRemaining = await getPrsRemaining(config, branches);
const prsRemaining = await getPrsRemaining(config, branches);
logger.debug({ prsRemaining }, 'Calculated maximum PRs remaining this run');
setMaxLimit(Limit.PullRequests, prsRemaining);
for (const branch of branches) {
addMeta({ branch: branch.branchName });
const prLimitReached = prsRemaining <= 0;
const commitLimitReached = isLimitReached(Limit.Commits);
const branchExisted = branchExists(branch.branchName);
const prExisted = await prExists(branch.branchName);
const res = await processBranch(branch, prLimitReached, commitLimitReached);
const res = await processBranch(branch);
branch.res = res;
if (
res === ProcessBranchResult.Automerged &&
Expand All @@ -56,34 +55,27 @@ export async function writeUpdates(
// Stop processing other branches because base branch has been changed
return 'automerged';
}
let deductPrRemainingCount = 0;
if (res === ProcessBranchResult.PrCreated) {
deductPrRemainingCount = 1;
incLimitedValue(Limit.PullRequests);
}
// istanbul ignore if
if (
else if (
res === ProcessBranchResult.Automerged &&
branch.automergeType === 'pr-comment' &&
branch.requiredStatusChecks === null
) {
deductPrRemainingCount = 1;
}
if (
incLimitedValue(Limit.PullRequests);
} else if (
res === ProcessBranchResult.Pending &&
!branchExisted &&
branchExists(branch.branchName)
) {
deductPrRemainingCount = 1;
incLimitedValue(Limit.PullRequests);
}
// istanbul ignore if
if (
deductPrRemainingCount === 0 &&
!prExisted &&
(await prExists(branch.branchName))
) {
deductPrRemainingCount = 1;
else if (!prExisted && (await prExists(branch.branchName))) {
incLimitedValue(Limit.PullRequests);
}
prsRemaining -= deductPrRemainingCount;
}
removeMeta(['branch']);
return 'done';
Expand Down

0 comments on commit 62c68d0

Please sign in to comment.