How to get PR branch name in GitHub Actions

https://help.github.com/en/articles/virtual-environments-for-github-actions#default-environment-variables
The GITHUB_REF var is currently returning value like “refs/pull/421/merge” which contains no mention of any branch name from which the PR was created. How can I achieve the same?

4 Likes

The pull request event contains the information you’re looking for. If you’re in a javascript action, context.payload.pull_request.head.ref will give you the branch name. (where context comes from const {context} = require(’@actions/github’)).

If you’re in yaml, then I believe it would be github.payload.pull_request.head.ref (see https://help.github.com/en/articles/contexts-and-expression-syntax-for-github-actions#github-context).

3 Likes

@jaredly Here’s my problem, I am trying to use bundlesize package for my repo using github actions. The package uses another package called ci-env which reads branch name from process.env.GITHUB_REF here, which is wrong. So I just wanted to replace this env var value with the context value you suggested. But I see here that the GITHUB_ env vars can’t be overridden. What should be done now?

You’ll need to fork ci-env to allow the branch name to be overridden (using a different env vbl), I should think

That should be my final recourse. Is there no simpler solution according to you? Otherwise I will just raise a PR in ci-unv to fix the variable read.

I have raised a PR to fix this
https://github.com/siddharthkp/ci-env/pull/29/files

process.env.GITHUB_HEAD_REF || process.env.GITHUB_REF && process.env.GITHUB_REF.split(’/’)[2]

should suffice, right?

Thanks for your post. It led me down the right path that will save me loads of time in the future.

Regarding:

If you’re in yaml, then I believe it would be github.payload.pull_request.head.ref 

That didn’t work, but this produced the branch to be merged as expected:

github.event.pull_request.head.ref
7 Likes

One way get the pull request’s base branch is:

- name: Step that prints name of pull request's base branch
  run: |
    echo "Pull request's base branch is: ${BASE_BRANCH}"
  env:
    BASE_BRANCH: ${{ github.base_ref }}
  if: github.event_name == 'pull_request'

For more details, see the documentation on the github context.

6 Likes

if: github.ref == ‘refs/heads/integration’ && github.event_name == ‘push’ 

You can this command and replace whatever branch or event you want to run for.

I would like to know how can I get the title of a pull request too!

    - name: Dump GitHub context
      env:
        GITHUB_CONTEXT: ${{ toJson(github) }}
      run: |
        echo "$GITHUB_CONTEXT"
        echo ${{ github.event.pull_request.title }}
2 Likes

There is no solution so far, so I created an actions to achieve it but requires some prerequisites.
Check it out Github action custom vars · Actions · GitHub Marketplace · GitHub

For reference, this is NOT a good strategy.

/ is a valid (and in some places common) character in branch names:

% cat .git/HEAD
ref: refs/heads/dependabot/npm_and_yarn/next_js/acorn-6.4.1

If you want to strip the first two bits, I’d suggest a regular expression:

> b
'dependabot/npm_and_yarn/next_js/acorn-6.4.1'
> c
'refs/heads/dependabot/npm_and_yarn/next_js/acorn-6.4.1'
> c.split('/')[2]
'dependabot'
> c.replace(RegExp("^refs/heads/"),"")
'dependabot/npm_and_yarn/next_js/acorn-6.4.1'

I don’t know if you have all of Node available, but you probably do.

Here’s an action to spit out the three values I use to determine 1. is this a PR commit 2. what is the PR target branch name 3. or is this just a commit on a non-PR branch

      - name: Echo out branch values
        run: | 
          echo github.base_ref: ${{ github.base_ref }}
          echo github.head_ref: ${{ github.head_ref }}
          echo github.ref: ${{ github.ref }}
      # Example output: in a PR branch (head) named `feature-1 to a target branch (base) of `release-v1`, you'll see:
        # github.base_ref: release-v1
        # github.head_ref: feature-1
        # github.ref: refs/pull/2/merge
      # if github.base_ref is empty, then commit is against a branch with no PR
        # this could have been a commit on any branch
        # In that case, github.ref show the branch we are on: refs/heads/main
        # strip off the refs/heads/ with "sed 's/refs\/heads\///'"
      # elseif github.base_ref is not empty, then commit is against a branch with a PR target
        # github.base_ref will have the target branch name
        # github.head_ref will have the branch name we are on
        # github.ref will have the PR number: refs/pull/1/merge

Beware that it’s possible for a push event to trigger on a tag as opposed to a branch. It’s a fun edge case that most people forget.

The way to avoid this edge is:

on:
  push:
    branches:
      - "**"
    tags-ignore:
      - "**"

which is of course not remotely fun to copy+paste, but hey.

You can also use https://github.com/tj-actions/branch-names

on:
  pull_request:
    branches:
      - main

...
    steps:
      - name: Get branch names
        id: branch-name
        uses: tj-actions/branch-names@v4.9
      
      - name: Current branch name
        run: |
          echo "${{ steps.branch-name.outputs.current_branch }}"
        # Outputs: "feature/test" current PR branch.
1 Like