Skip to content

Commit

Permalink
Merge pull request #35 from adRise/allow_ongoing_checks
Browse files Browse the repository at this point in the history
Add the `allow_ongoing_checks` option to enable updates to PRs with ongoing checks when the action is triggered.
  • Loading branch information
zhiyelee authored Aug 28, 2024
2 parents 5d27394 + c5bcec4 commit 6e6c6ee
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 16 deletions.
17 changes: 12 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,15 @@ We could retrieve this value from the repo settings through an API call but that

Default: true

The action will skip PRs that have failed checks.
The action will skip updating PRs that have failed checks. Please note that if `allow_ongoing_checks` is set to `false`, the action will skip updating PRs with ongoing checks. This will result in the failure to update PR branches when the action is triggered while checks for those PRs are still in progress.

### `allow_ongoing_checks`

**Optional**

Default: false

The action will consider PRs that have ongoing checks. This is useful when the action is triggered while checks for some otherwise qualified PRs are still in progress. Note, this option works only when `require_passed_checks` is set to `true`.

### `sort`

Expand All @@ -76,7 +84,6 @@ Notice: this is an option provided by github rest api. In this github action, we

The direction of the sort. Can be either `asc` or `desc`. Default: `desc` when sort is `created` or sort is not specified, otherwise `asc`.


This github action doesn't set any default parameters.

### `require_auto_merge_enabled`
Expand All @@ -87,7 +94,6 @@ Check if having auto-merge enabled in the PR is required, in order for the PR to
be considered. It defaults to `true`, but if set to `false`, all PRs are
considered for update (not just those with auto-merge enabled).


## Example usage

```yml
Expand All @@ -107,10 +113,11 @@ jobs:
token: ${{ secrets.ACTION_USER_TOKEN }}
base: 'master'
required_approval_count: 2
require_passed_checks: false
require_passed_checks: true
allow_ongoing_checks: true
sort: 'created'
direction: 'desc'
require_auto_merge_enabled: false
require_auto_merge_enabled: true
```
Replace the `VERSION_YOU_WANT_TO_USE` with the actual version you want to use, check the version format [here](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses)
Expand Down
6 changes: 5 additions & 1 deletion action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ inputs:
default: '2'
require_passed_checks:
required: false
description: 'If the action should skip PRs that have failed checks, defaults to `true`'
description: 'If the action should skip PRs that have failed checks, defaults to `true`. Please note that if `allow_ongoing_checks` is not set to `true`, the action will skip pull requests with ongoing checks. This may result in the failure to update PR branches when the action is triggered while checks for those pull requests are still in progress.'
default: 'true'
allow_ongoing_checks:
required: false
description: 'If the action should consider PRs that have ongoing checks, defaults to `false`. The action will consider PRs that have ongoing checks. This is useful when the action is triggered while checks for some otherwise qualified PRs are still in progress. Note, this option works only when `require_passed_checks` is set to `true`.'
default: 'false'
require_auto_merge_enabled:
required: false
description: 'When set to false, the action includes PRs without auto-merge; the default true excludes such PRs.'
Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
{
"name": "update-pr-branch",
"version": "0.1.2",
"description": "Automatically update PR branch",
"main": "dest/index.js",
"scripts": {
Expand Down
34 changes: 26 additions & 8 deletions src/lib/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export const getMergeableStatus = async (pullNumber) => {
/**
* whether all checks passed
*/
export const areAllChecksPassed = async (sha) => {
export const areAllChecksPassed = async (sha, allow_ongoing_checks) => {
const octokit = getOctokit();
const repo = github.context.repo;
const {
Expand All @@ -110,11 +110,20 @@ export const areAllChecksPassed = async (sha) => {
ref: sha,
});

const hasUnfinishedOrFailedChecks = check_runs.some((item) => {
return item.status !== 'completed' || item.conclusion === 'failure';
});
let hasOffensiveChecks = false;
if (allow_ongoing_checks) {
// check whether there are ongoing checks
hasOffensiveChecks = check_runs.some((item) => {
return item.conclusion === 'failure';
});
} else {
// check whether there are unfinished or failed checks
hasOffensiveChecks = check_runs.some((item) => {
return item.status !== 'completed' || item.conclusion === 'failure';
});
}

return !hasUnfinishedOrFailedChecks;
return !hasOffensiveChecks;
};

/**
Expand Down Expand Up @@ -154,7 +163,9 @@ export const getApprovalStatus = async (pullNumber) => {
};

export const filterApplicablePRs = (openPRs) => {
const includeNonAutoMergePRs = isStringFalse(core.getInput('require_auto_merge_enabled'));
const includeNonAutoMergePRs = isStringFalse(
core.getInput('require_auto_merge_enabled'),
);
if (includeNonAutoMergePRs) {
return openPRs;
}
Expand All @@ -171,6 +182,9 @@ export const getAutoUpdateCandidate = async (openPRs) => {
const requirePassedChecks = isStringTrue(
core.getInput('require_passed_checks'),
);
const allowOngoingChecks = isStringTrue(
core.getInput('allow_ongoing_checks'),
);
const applicablePRs = filterApplicablePRs(openPRs);

for (const pr of applicablePRs) {
Expand Down Expand Up @@ -216,9 +230,13 @@ export const getAutoUpdateCandidate = async (openPRs) => {
* need to note: the mergeable, and mergeable_state don't reflect the checks status
*/
if (requirePassedChecks) {
const didChecksPass = await areAllChecksPassed(sha);
const didChecksPass = await areAllChecksPassed(sha, allowOngoingChecks);

const reasonType = allowOngoingChecks
? 'failed check(s)'
: 'failed or ongoing check(s)';
if (!didChecksPass) {
printFailReason(pullNumber, 'The PR has failed or ongoing check(s)');
printFailReason(pullNumber, `The PR has ${reasonType}`);
continue;
}
}
Expand Down
45 changes: 45 additions & 0 deletions src/lib/github.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,51 @@ describe('areAllChecksPassed()', () => {
const result = await gitLib.areAllChecksPassed(sha);
expect(result).toEqual(false);
});

test('should return true if there is ongoing checks but no failed checks', async () => {
// mock pending check
const check = {
...oldCheck,
status: 'queued',
conclusion: null,
};
mockedResponse.data.check_runs[0] = check;

const mockedMethod = jest.fn().mockResolvedValue(mockedResponse);

github.getOctokit.mockReturnValue({
rest: { checks: { listForRef: mockedMethod } },
});

const allowOngoingChecks = true;
const result = await gitLib.areAllChecksPassed(sha, allowOngoingChecks);
expect(result).toEqual(true);
});

test('should return false if there is ongoing checks and failed checks', async () => {
// mock pending check
const check = {
...oldCheck,
status: 'queued',
conclusion: null,
};
const failedCheck = {
...oldCheck,
conclusion: 'failure',
};
mockedResponse.data.check_runs[0] = check;
mockedResponse.data.check_runs[1] = failedCheck;

const mockedMethod = jest.fn().mockResolvedValue(mockedResponse);

github.getOctokit.mockReturnValue({
rest: { checks: { listForRef: mockedMethod } },
});

const allowOngoingChecks = true;
const result = await gitLib.areAllChecksPassed(sha, allowOngoingChecks);
expect(result).toEqual(false);
});
});

describe('getApprovalStatus()', () => {
Expand Down

0 comments on commit 6e6c6ee

Please sign in to comment.