Github Actions Cookbook
- This document lists common patterns and issues we’ve had in our Github actions, and practical solutions to them.
- The first point of reference should be the official documentation, but if that is ever unclear, here would be a good place to look!
Terminology used in this document:
- A workflow contains multiple independently ran tasks. Each task runs a series of steps. Steps can call predefined actions, or run shell commands.
I want to skip CI tests
Adding [skip ci] to a commit message prevents CI tests from being triggered for that commit.
This is useful when pushing unfinished work, for example, to document what isn’t working yet or to ask for help on a draft.
I want to have a step output multilined / complex text
- name: Calculate PR doc coverage
id: prddoc
run: |
RUSTDOCFLAGS='-Z unstable-options --show-coverage' cargo +nightly doc --workspace --no-deps > coverage.md
echo 'coverage<<EOFABC' >> $GITHUB_OUTPUT
echo "$(cat coverage.md)" >> $GITHUB_OUTPUT
echo 'EOFABC' >> $GITHUB_OUTPUT```
The entire output of cargo doc can be substituted into later jobs by using ${{ steps.prdoc.outputs.coverage }}
workflow_run: I want a workflow that runs on a PR and can write to the repo
PR branches and their workflows typically live in on a branch on an external fork. Therefore, they cannot write to the repository. The solution is to split things into two workflows - one that runs on the PR with read-only permissions, and one that runs on main and can write to the repository. This is called a workflow_run workflow. Read the docs.
The workflow_run workflow should not run any user provided code as it has secrets in scope.
I want to access the calling PR in a workflow_run workflow
workflow_run jobs do not get access to the calling workflows detail. While one can access some things via the Github API such as head_sha, head_repo, this may not give any PR information. Github recommends saving the PR number to an artifact, and using this number to fetch the PR info through the API:
Example from this github blog post - see this for more explanation and details!
name: Receive PR
# read-only repo token
# no access to secrets
on:
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# imitation of a build process
- name: Build
run: /bin/bash ./build.sh
- name: Save PR number
run: |
mkdir -p ./pr
echo ${{ github.event.number }} > ./pr/NR
- uses: actions/upload-artifact@v2
with:
name: pr
path: pr/
name: Comment on the pull request
# read-write repo token
# access to secrets
on:
workflow_run:
workflows: ["Receive PR"]
types:
- completed
jobs:
upload:
runs-on: ubuntu-latest
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
steps:
- name: 'Download artifact'
uses: actions/github-script@v3.1.0
with:
script: |
var artifacts = await github.actions.listWorkflowRunArtifacts({
owner: context.repo.owner,
repo: context.repo.repo,
run_id: ${{github.event.workflow_run.id }},
});
var matchArtifact = artifacts.data.artifacts.filter((artifact) => {
return artifact.name == "pr"
})[0];
var download = await github.actions.downloadArtifact({
owner: context.repo.owner,
repo: context.repo.repo,
artifact_id: matchArtifact.id,
archive_format: 'zip',
});
var fs = require('fs');
fs.writeFileSync('${{github.workspace}}/pr.zip', Buffer.from(download.data));
- run: unzip pr.zip
- name: 'Comment on PR'
uses: actions/github-script@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
var fs = require('fs');
var issue_number = Number(fs.readFileSync('./NR'));
await github.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue_number,
body: 'Everything is OK. Thank you for the PR!'
});
How do I get x commit inside a PR workflow? What do all the different github sha’s mean?
If you are running in a workflow_run workflow, you will need to get the calling PR first. See I want to access the calling PR in a workflow_run workflow instead.
The default github.sha is a temporary commit representing the state of the repo should the PR be merged now. You probably want github.event.pull_request.head.sha. Read The many SHAs of a github pull request.
This section had been taken from the ‘Github Actions’ page of the conjure-oxide wiki