I'm using Github Enterprise.
Below is the workflow to allow PR to be merged only if PR changes pass test
.
on:
pull_request:
branches: [...]
types: [opened, reopened, synchronize, edited]
jobs:
test:
runs-on: self-hosted
steps:
- name: Checkout code
uses: actions/checkout@v4
steps:
...
Apparently edited
activity also includes changing just the body of PR as well as changing the base, so I tried to ignore it by putting if
statement like below:
jobs:
test:
if: github.event.action != 'edited' || github.event.changes.base
runs-on: self-hosted
steps:
...
But problem is that Github accepts skipped test
as "success".
Which means that PR that fails test
job can be merged if PR body changes after.
I tried to use needs:
in test
job, so test
can run only when it's code changes, but Github accepts the fact that test
job is not run as "failure".
How can I make Github not consider runs for PR check that are triggered by changing PR body?
This is the exact way I solved it, thanks to @Azeem.
name: foo
on:
pull_request:
branches: [...]
types: [opened, reopened, synchronize, edited]
concurrency:
group: ${{ github.event.pull_request.head.sha }}
cancel-in-progress: false
jobs:
prepare:
runs-on: self-hosted
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
check-the-last-test-status:
needs: prepare
runs-on: self-hosted
outputs:
status: ${{ steps.check-status.outputs.result }}
steps:
- name: Check the 'test' status of the latest commit (${{ github.event.pull_request.head.sha }})
id: check-status
if: ${{ github.event.action == 'edited' && !github.event.changes.base }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
IS_THE_LAST_TEST_SUCCESS=$(gh run list \
--workflow "foo" \
--event pull_request \
--branch ${{ github.event.pull_request.head.ref }} \
--commit ${{ github.event.pull_request.head.sha }} \
--json status,conclusion \
--jq '[.[] | select(.status == "completed" and .conclusion == "success")] | any')
echo "Is the last test success: $IS_THE_LAST_TEST_SUCCESS"
if [[ "$IS_THE_LAST_TEST_SUCCESS" == 'true' ]]; then
echo "result=success" >> $GITHUB_OUTPUT
else
echo "result=failure" >> $GITHUB_OUTPUT
fi;
- name: Cancel
if: steps.check-status.conclusion != 'skipped' && steps.check-status.outputs.result == 'failure'
run: |
gh run cancel ${{ github.run_id }}
gh run watch ${{ github.run_id }}
test:
needs: check-the-last-test-status
if: needs.check-the-last-test-status.outputs.status != 'success'
runs-on: self-hosted
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20.10.0'
- ...
Yes, the edited
action of the pull_request
event means that:
The title or body of a pull request was edited, or the base branch of a pull request was changed.
For your specific use case, if the PR's title or body is edited, you can fetch the result of the previous workflow run using GitHub CLI's gh run list
command, evaluate it, set the result as an output parameter (at job or step level) and use it for further decision making.
Here's an example:
- name: Check last workflow run status
id: last-run
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
STATUS=$(gh run list \
--workflow test \
--event pull_request \
--branch "$GITHUB_HEAD_REF" \
--limit 1 \
--json status,conclusion \
--jq '.[].status == "completed" and .[].conclusion == "success"')
echo "STATUS=$STATUS" >>"$GITHUB_OUTPUT"
- name: Tests
if: ${{ steps.last-run.outputs.STATUS == 'false' }}
run: ...
You can expand on this idea and adapt it according to your use case.