Integration tests can run for hours, they cover edge cases and complex flows which the regular unit test suit doesn't check, in my case, integration test is deeper level of testing.
The point is that I don't want them to run for any commit in my PR.
Yes, this flow won't work for me:
name: Java CI
on: [push]
jobs:
build:
I want them to run before I make the merge, will the bellow flow satisfied me?
name: Java CI
on:
push:
branches:
- master
No, too late for me, the code is already merged, and if my tests will fail? master is broken? no way, I want to run them before the merge...
I came up with some "bot" style solution, I'll write a comment in the PR and it will trigger the integration job, it can be helpful to trigger it even before I'm ready to merge, just to get a feeling what is my PR status.
There are 2 issues with that solution (beside that it isn't automatic and require someone to "ask" for ci job..)
- The job is not running in the PR context.
- Need to check in any step that this is the required comment I looked for.
Both can be handled just keep it in mind, because it will make the solution a bit complex.
Let's start describe the flow step by step:
Here is the trigger, I want it to run per comment.
name: integration-test
on:
issue_comment:
types: [created]
But, only for comment with "ci" text :
I use a nice action that checks the comment text and give me output if that comment matches to my trigger word, it also has a nice ability to add emoji if the comment matches:
steps:
- uses: khan/pull-request-comment-trigger@master
id: check
with:
trigger: 'ci'
reaction: rocket
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
After my comment is verified I want to send a message to the PR with the job link, that is needed because the build is not running in the PR context, it runs from the master, in order to make the linkage between the PR and the build, I send this comment back to the PR:
- name: send comment
if: steps.check.outputs.triggered == 'true'
env:
URL: ${{ github.event.issue.comments_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl \
-X POST \
$URL \
-H "Content-Type: application/json" \
-H "Authorization: token $GITHUB_TOKEN" \
--data '{ "body": ":test_tube: [starting ci integration job]( https://github.com/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"')" }'
The next step will pull the PR branch ,as already said, it is needed because the build isn't running in PR context
- name: Get PR informations
if: steps.check.outputs.triggered == 'true'
id: pr_data
run: |
echo "::set-output name=branch::${{ fromJson(steps.request.outputs.data).head.ref }}"
echo "::set-output name=repo_name::${{ fromJson(steps.request.outputs.data).head.repo.full_name }}"
echo "::set-output name=repo_clone_url::${{ fromJson(steps.request.outputs.data).head.repo.clone_url }}"
echo "::set-output name=repo_ssh_url::${{ fromJson(steps.request.outputs.data).head.repo.ssh_url }}"
- name: Checkout PR Branch
if: steps.check.outputs.triggered == 'true'
uses: actions/checkout@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
repository: ${{ fromJson(steps.request.outputs.data).head.repo.full_name }}
ref: ${{ steps.pr_data.outputs.branch }}
And, last thing, add the checked commit revision to the step output, I will need in next steps.
- name: debug
if: steps.check.outputs.triggered == 'true'
id: debug
run: |
echo ::set-output name=sha::$( curl -u "u:${{github.token}}" https://api.github.com/repos/${{steps.pr_data.outputs.repo_name}}/git/ref/heads/${{steps.pr_data.outputs.branch}} | jq .object.sha | tr -d '"' )
Now comes the regular build step, in my case running Java unit test with Maven (-Pci will turn on maven profile that run only integration tests)
- name: Set up JDK 1.8
if: steps.check.outputs.triggered == 'true'
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Maven
if: steps.check.outputs.triggered == 'true'
run: mvn clean install -Pci
After this step the job is failed or succeeded and I want to send a message indicates the status, it will send a link with the job build url by using ${{GITHUB_RUN_ID}}
.
- name: Create success comment
if: steps.check.outputs.triggered == 'true' && success()
env:
URL: ${{ github.event.issue.comments_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl \
-X POST \
$URL \
-H "Content-Type: application/json" \
-H "Authorization: token $GITHUB_TOKEN" \
--data '{ "body": ":v: [finish ci integration job successfully]( https://github.com/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"')" }'
- name: Create fail comment
if: steps.check.outputs.triggered == 'true' && failure()
env:
URL: ${{ github.event.issue.comments_url }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
curl \
-X POST \
$URL \
-H "Content-Type: application/json" \
-H "Authorization: token $GITHUB_TOKEN" \
--data '{ "body": ":facepalm: [ci integration job failed]( https://github.com/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"')" }'
Bonus part!
relevant if your build has Surefire reports
You can generate test report by using this nice action.
But you have to send it your last PR commit in order ti see the test results in the PR itself, this is the reason I output the commit sha id in the debug
step.
- name: Publish Test Report
if: steps.check.outputs.triggered == 'true' && (failure() || success())
uses: scacap/action-surefire-report@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
commit: ${{ steps.debug.outputs.sha }}
check_name: integration_test_results
That is!
Here is it how it looks in the PR conversation:
Top comments (0)