We implement https://iterative.ai/blog/testing-external-contributions-using-github-actions-secrets to allow to run workflows that require GitHub secrets on external PRs. For that, one member of the external
group needs to approve the workflow.
The authorize
job should be required for all following jobs (needs: authorize
).
When using actions/checkout
, we would like to check out on the merge commit, as this is the default for the pull_request
event (but not of the pull_request_target
, refer to actions/checkout#518). However, this is in itself not safe as malicious code can be commited between the approval and checkout.
Thus the step
- name: Security - check PR SHA
if: github.event_name == 'pull_request_target'
run: |
[[ "$(git rev-parse 'HEAD^2')" == "${{ github.event.pull_request.head.sha }}" ]]
is required, checking that the second parent (namely the last PR commit) SHA matches with the SHA captured at the start of the workflow.
All in all this is safe:
name: Unit and integration tests
on:
workflow_dispatch:
pull_request_target:
jobs:
authorize:
environment:
${{ github.event_name == 'pull_request_target' &&
github.event.pull_request.head.repo.full_name != github.repository &&
'external' || 'internal' }}
runs-on: ubuntu-latest
steps:
- run: true
mytest:
name: Run my tests
needs: authorize
steps:
- name: Checkout on branch
if: github.event_name != 'pull_request_target'
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
- name: Checkout on PR merge commit
if: github.event_name == 'pull_request_target'
uses: actions/checkout@v2
with:
ref: "refs/pull/${{ github.event.number }}/merge"
fetch-depth: 2
- name: Security - check PR SHA
if: github.event_name == 'pull_request_target'
run: |
[[ "$(git rev-parse 'HEAD^2')" == "${{ github.event.pull_request.head.sha }}" ]]