Github Actions: Cookbook - conjure-cp/conjure-oxide GitHub Wiki

  • 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 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 >
    echo 'coverage<<EOFABC' >> $GITHUB_OUTPUT
    echo "$(cat" >> $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

    runs-on: ubuntu-latest

      - uses: actions/checkout@v2

      # imitation of a build process
      - name: Build
        run: /bin/bash ./

      - name: Save PR number
        run: |
          mkdir -p ./pr
          echo ${{ github.event.number }} > ./pr/NR
      - uses: actions/upload-artifact@v2
          name: pr
          path: pr/
name: Comment on the pull request

# read-write repo token
# access to secrets
    workflows: ["Receive PR"]
      - completed

    runs-on: ubuntu-latest
    if: >
      github.event.workflow_run.event == 'pull_request' &&
      github.event.workflow_run.conclusion == 'success'
      - name: 'Download artifact'
        uses: actions/[email protected]
          script: |
            var artifacts = await github.actions.listWorkflowRunArtifacts({
               owner: context.repo.owner,
               repo: context.repo.repo,
               run_id: ${{ }},
            var matchArtifact = => {
              return == "pr"
            var download = await github.actions.downloadArtifact({
               owner: context.repo.owner,
               repo: context.repo.repo,
               archive_format: 'zip',
            var fs = require('fs');
            fs.writeFileSync('${{github.workspace}}/', Buffer.from(;
      - run: unzip

      - name: 'Comment on PR'
        uses: actions/github-script@v3
          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.

⚠️ ** Fallback** ⚠️