Skip to content

Commit

Permalink
Add option to filter PRs based on ready state (#183)
Browse files Browse the repository at this point in the history
Co-authored-by: Chin Godawita <1452384+chinthakagodawita@users.noreply.github.com>

Closes #176
  • Loading branch information
pjohnmeyer authored Jun 24, 2021
1 parent 9291f16 commit 9b68d45
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ All configuration values, except `GITHUB_TOKEN`, are optional.

- `PR_LABELS`: Controls which labels _autoupdate_ will look for when monitoring PRs. Only used if `PR_FILTER="labelled"`. This can be either a single label or a comma-separated list of labels.

- `PR_READY_STATE`: Controls how _autoupdate_ monitors pull requests based on their current [draft / ready for review](https://help.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request) state. Possible values are:

- `"all"`: (default): No filter, _autoupdate_ will monitor and update pull requests regardless of ready state.
- `"ready_for_review"`: Only monitor PRs that are not currently in the draft state.
- `"draft"`: Only monitor PRs that are currently in the draft state.

- `EXCLUDED_LABELS`: Controls which labels _autoupdate_ will ignore when evaluating otherwise-included PRs. This option works with all `PR_FILTER` options and can be either a single label or a comma-separated list of labels.

- `MERGE_MSG`: A custom message to use when creating the merge commit from the destination branch to your pull request's branch.
Expand Down
15 changes: 15 additions & 0 deletions src/autoupdater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,21 @@ export class AutoUpdater {
}
}

const readyStateFilter = this.config.pullRequestReadyState();
if (readyStateFilter !== 'all') {
ghCore.info('Checking PR ready state');

if (readyStateFilter === 'draft' && !pull.draft) {
ghCore.info('PR_READY_STATE=draft and pull request is not draft, skipping update.');
return false;
}

if (readyStateFilter === 'ready_for_review' && pull.draft) {
ghCore.info('PR_READY_STATE=ready_for_review and pull request is draft, skipping update.');
return false;
}
}

const prFilter = this.config.pullRequestFilter();

ghCore.info(
Expand Down
4 changes: 4 additions & 0 deletions src/config-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ export class ConfigLoader {
return this.getValue('GITHUB_REPOSITORY', true, '');
}

pullRequestReadyState(): string {
return this.getValue('PR_READY_STATE', false, 'all');
}

// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
getValue(key: string, required = false, defaultVal?: any): any {
if (
Expand Down
72 changes: 72 additions & 0 deletions test/autoupdate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const validPull = {
},
},
},
draft: false,
};
const clonePull = () => JSON.parse(JSON.stringify(validPull));

Expand Down Expand Up @@ -452,6 +453,77 @@ describe('test `prNeedsUpdate`', () => {
expect(config.pullRequestFilter).toHaveBeenCalled();
expect(config.excludedLabels).toHaveBeenCalled();
});

describe('pull request ready state filtering', () => {
const readyPull = clonePull();
const draftPull = Object.assign(clonePull(), { draft: true });

const nockCompareRequest = () =>
nock('https://api.github.com:443')
.get(`/repos/${owner}/${repo}/compare/${head}...${base}`)
.reply(200, {
behind_by: 1,
});

beforeEach(() => {
(config.excludedLabels as jest.Mock).mockReturnValue([]);
});

test('pull request ready state is not filtered', async () => {
(config.pullRequestReadyState as jest.Mock).mockReturnValue('all');

const readyScope = nockCompareRequest();
const draftScope = nockCompareRequest();

const updater = new AutoUpdater(config, emptyEvent);

const readyPullNeedsUpdate = await updater.prNeedsUpdate(readyPull);
const draftPullNeedsUpdate = await updater.prNeedsUpdate(draftPull);

expect(readyPullNeedsUpdate).toEqual(true);
expect(draftPullNeedsUpdate).toEqual(true);
expect(config.pullRequestReadyState).toHaveBeenCalled();
expect(readyScope.isDone()).toEqual(true);
expect(draftScope.isDone()).toEqual(true);
});

test('pull request is filtered to drafts only', async () => {
(config.pullRequestReadyState as jest.Mock).mockReturnValue('draft');

const readyScope = nockCompareRequest();
const draftScope = nockCompareRequest();

const updater = new AutoUpdater(config, emptyEvent);

const readyPullNeedsUpdate = await updater.prNeedsUpdate(readyPull);
const draftPullNeedsUpdate = await updater.prNeedsUpdate(draftPull);

expect(readyPullNeedsUpdate).toEqual(false);
expect(draftPullNeedsUpdate).toEqual(true);
expect(config.pullRequestReadyState).toHaveBeenCalled();
expect(readyScope.isDone()).toEqual(true);
expect(draftScope.isDone()).toEqual(true);
});

test('pull request ready state is filtered to ready PRs only', async () => {
(config.pullRequestReadyState as jest.Mock).mockReturnValue(
'ready_for_review',
);

const readyScope = nockCompareRequest();
const draftScope = nockCompareRequest();

const updater = new AutoUpdater(config, emptyEvent);
const readyPullNeedsUpdate = await updater.prNeedsUpdate(readyPull);
const draftPullNeedsUpdate = await updater.prNeedsUpdate(draftPull);

expect(readyPullNeedsUpdate).toEqual(true);
expect(draftPullNeedsUpdate).toEqual(false);
expect(config.pullRequestReadyState).toHaveBeenCalled();
expect(readyScope.isDone()).toEqual(true);
expect(draftScope.isDone()).toEqual(true);
});
});
});

describe('test `handlePush`', () => {
Expand Down
7 changes: 7 additions & 0 deletions test/config-loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ const tests = [
default: '',
type: 'string',
},
{
name: 'pullRequestReadyState',
envVar: 'PR_READY_STATE',
required: false,
default: 'all',
type: 'string',
},
];

for (const testDef of tests) {
Expand Down

0 comments on commit 9b68d45

Please sign in to comment.