docs
docs copied to clipboard
GITHUB_REF and GITHUB_REF_NAME examples in Actions docs unclear
Code of Conduct
- [X] I have read and agree to the GitHub Docs project's Code of Conduct
What article on docs.github.com is affected?
https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables
What part(s) of the article would you like to see updated?
GITHUB_REF
and GITHUB_REF_NAME
show example values of refs/heads/feature-branch-1
and feature-branch-1
respectively. However this is inconsistent with the values populated in the case of a PR-triggered workflow.
Given the description and example, one would expect to see the branch that triggered the workflow when running a PR-triggered workflow. Instead these variables are populated by values like refs/pull/26/merge
and 26/merge
respectively. The variable that contains the desired data in this case is actually GITHUB_HEAD_REF
.
The documentation should be updated to more accurately describe the content of GitHub Actions predefined variables.
Additional information
No response
Thanks for opening this issue. A GitHub docs team member should be by to give feedback soon. In the meantime, please check out the contributing guidelines.
@oofnikj Thanks so much for opening an issue! I'll triage this for the team to take a look :eyes:
Thanks for opening this issue! You proposal to add/clarify this information sounds good. You or anyone else is welcome to open a PR to address this. (Note that this was partially addressed in https://github.com/github/docs/pull/15304)
What's next... 411 please
Why should GITHUB_REF_NAME
be different for a PR? If it's supposed to return the source branch (a very useful thing) then it should do so regardless of the context. To me this seems more like a bug than bad documentation.
It would certainly be more helpful for our use case to have a simpler way to get the branch name regardless of context. Here is the snippet of Python code we are using to get the branch name now.
I think this has been covered and updated in a previous PR. I'm going to go ahead and close this now 💛
@cmwilson21 in what PR?
@airtonix Sorry, I may have been mistaken. I thought it was covered here. I'll reopen the issue.
My apologies! 🙈
Disclaimer: I'm the author of the following action
In this action https://github.com/rlespinasse/github-slug-action, the behavior, described by @wickkidd, is possible with ${{ env.GITHUB_REF_NAME }}
(read more).
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v4
- run:|
echo "$GITHUB_REF_NAME will serve the internal behavior of GitHub Action"
echo "${{ env.GITHUB_REF_NAME }} will serve the behavior of the GitHub Slug action"
shell: bash
This would be extremely useful to my team as we currently have to maintain hardcoded environment and terraform workspace names in our workflows, this forces us to have a different workflow for each environment. We could create some custom expression logic that only run on a Push or PR to export ref_name when event_name == push and github_base_ref when event_name == workflow_dispatch. I would highly prefer there to be some way to consistently get the ref_name regardless of event_name.
terraform:
runs-on: ubuntu-latest
environment:
name: ${{ github.ref_name }}
env:
working-directory: terraform
TF_WORKSPACE: ${{ github.ref_name }}
ARM_USE_OIDC: true
Edit: this is usable as a workaround that does not require an action.
jobs:
get_ref_name:
runs-on: ubuntu-latest
outputs:
ref_name: ${{ steps.get_ref_name.outputs.ref_name }}
steps:
- name: Get ref_name
id: get_ref_name
run: |
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "ref_name=${{ github.base_ref }}"
echo "ref_name=${{ github.base_ref }}" >> $GITHUB_OUTPUT || exit 1
else
echo "ref_name=${{ github.ref_name }}"
echo "ref_name=${{ github.ref_name }}" >> $GITHUB_OUTPUT || exit 1
fi
terraform:
needs: get_ref_name
runs-on: ubuntu-latest
environment:
name: ${{ needs.get_ref_name.outputs.ref_name }}
env:
working-directory: terraform
TF_WORKSPACE: ${{ needs.get_ref_name.outputs.ref_name }}
Can you please just add ${{ github.branch_name }}
. Why is getting something I can do on my console with git branch
so hard in a GHA environment?
Getting something as basic as the current branch name shouldn't require custom bash scripting depending on the context. Github, please make this easy for us.
https://docs.github.com/en/actions/learn-github-actions/variables is really unclear. Please get better WORKING examples. It shouldn't be that hard. If you can't do this just tell people to write their own logic in bash or pwsh or use gitlab.
I asked chatgpt and that got it right. Maybe you should have it write the docs.
works ${{ github.event_name == 'pull_request' && github.ref.name == 'dev' }}
doesn't work if: | github.ref.name == 'dev' && github.event_name == 'pull request'
or maybe these both don't work.
Asked ChatGPT again more specifically and got something like this.
if: ${{ github.event.pull_request.base.ref == 'dev' && github.event.pull_request.merged }}
But still not working it really shouldn't be this hard. Please tell us if we should just use bash but please give some examples
It is even more weird with pull_request
event. I'm using this code to pass env vars to an action :
env:
COMMIT_INFO_BRANCH: ${{ github.ref_name }}
COMMIT_INFO_MESSAGE: ${{ github.event.pull_request.title }}
COMMIT_INFO_SHA: ${{ github.sha }}
Branch name for PR is chore/ci-setup
. In logs I get this:
env:
COMMIT_INFO_BRANCH: 3/merge
COMMIT_INFO_MESSAGE: chore(ci): setup
COMMIT_INFO_SHA: fbf88412867d6d0475da156e1ad3deb2d02c43e9
Who would ever want 3/merge
to be returned for ref name?!
I know I should probably use github.event.pull_request.head.ref
but then I need to do some condition if same job is running also for push
trigger. This is just PITA.
Just wanted to add support for this issue. I was very confused as to why a GHA was skipping my branch and it was because the github.ref_name
wasn't accurate, which isn't something the documentation warns about. It makes it really sound like it's the way to get the branch name in all cases, and it's confusing that I need to use head_ref
for PRs, but ref_name
for non-PRs.
I think there'd be beneficial to have a github.branch_name
that works universally, and gives you the branch name irrespective of how it's ran or triggered, but I also think the docs are a little misleading as-is.
👋 Hey folks! Thanks for all the great feedback in this issue. We had this as an open issue for anyone to work on, but after reviewing it, we are going to remove it from the help wanted
board and discuss it a bit further.
Thanks again for all your input! 💖
I have a step like this at the start of most workflows:
- run: echo "REF=${{ github.event.pull_request && github.head_ref || github.ref_name }}" >> $GITHUB_ENV
which lets me reference $REF
in subsequent steps, to abstract over this head_ref
/ref_name
inconsistency.
@ryan-williams Thanks for your example. I did not know there was ternary available in expression until I saw your example. Must have missed it in docs. Super handy to know about this.
//EDIT
Missed it probably because this was just one sentence with one example. There should be whole section just for ternary. I mostly used bash to make some stuff conditional and with ternary I don't have to do this any more. Such useful feature and it is not emphasized enough in docs...
// EDIT 2
Just checked git blame for docs and ternary operator docs were added 2 months ago... So that is why I missed it.
👋 Hey folks! Thanks for all the great feedback in this issue. We had this as an open issue for anyone to work on, but after reviewing it, we are going to remove it from the
help wanted
board and discuss it a bit further.Thanks again for all your input! 💖
Does it mean you're on it, or that we're going to wait another year or two for this simple feature? By then, nearly everyone got a workaround in place...
A stale label has been added to this issue because it has been open for 60 days with no activity. To keep this issue open, add a comment within 3 days.
3 days pass quickly nowadays...
A simple and generic way to get the current branch name is still required and would be much appreciated. Thanks for considering this issue.
I recently learned that even using some bash condition can fail to figure out the ref name for current workflow run. Idk how GitHub runners work but this workflow step fails randomly (like 10% of times). I have already sent an issue about this to GitHub support.
I have a workflow that is run on release
and workflow_dispatch
events. When this workflow is triggered by publishing new release it is randomly failing because GITHUB_REF
and github.ref
is not set. I use some bash logic to handle both release
and workflows_dispatch
GIT ref like this:
name: 01 - Deploy To Staging
concurrency: staging
on:
release:
types:
- published
workflow_dispatch:
inputs:
release_ref:
description: "Release TAG"
required: true
jobs:
initialize:
name: "Initialize deploy"
runs-on: ubuntu-22.04
timeout-minutes: 2
outputs:
ref: "${{ steps.version.outputs.ref }}"
steps:
- name: Get git ref
id: git_ref
run: |
if [[ "${{ github.event_name }}" = "release" ]]; then
echo "value=${{ github.ref }}" >> $GITHUB_OUTPUT
else
echo "value=${{ github.event.inputs.release_ref }}" >> $GITHUB_OUTPUT
fi
# next steps are failing because they expect `steps.git_ref.outputs.value` or `GITHUB_REF` to be set
90% of times this works fine:
but in 10% of cases it fails:
Based on GitHub docs about github.ref
it should be always set for both of those events:
The fully-formed ref of the branch or tag that triggered the workflow run. For workflows triggered by push, this is the branch or tag ref that was pushed. For workflows triggered by pull_request, this is the pull request merge branch. For workflows triggered by release, this is the release tag created. For other triggers, this is the branch or tag ref that triggered the workflow run. This is only set if a branch or tag is available for the event type. The ref given is fully-formed, meaning that for branches the format is refs/heads/<branch_name>, for pull requests it is refs/pull/<pr_number>/merge, and for tags it is refs/tags/<tag_name>. For example, refs/heads/feature-branch-1.
Also this randomness is not just happening inside one repository workflow runs. When it happens it happens for multiple repositories at similar time.
Really weird stuff going on.
If anyone is interested about my issue with getting current ref with release
event, I got response from GitHub support:
Hello Piotr,
Thank you for reaching out to GitHub Support! I apologize for the delay here.
The behavior you're seeing is due to a known issue at this time affecting release event triggered runs. Our engineering team is tracking this behavior internally, and have confirmed that it has a fairly low repro rate - explaining the 90/10 split of times you noted seeing this issue.
Fix work will be planned and prioritized for this, but there is currently no concrete ETA. In the meantime, you can leverage data from the release payload to get the tag name (through github.event.release.tag_name) and set this up as a fallback value where you're calling github.ref.
In your provided snippet, this would look like the following:
if [[ "${{ github.event_name }}" = "release" ]]; then
echo "value=${{ github.ref || format('{0}{1}', 'refs/tags/', github.event.release.tag_name) }}" >> $GITHUB_OUTPUT
else
echo "value=${{ github.event.inputs.release_ref }}" >> $GITHUB_OUTPUT
fi
Since github.event.release.tag_name only returns the name of the tag minus the ref prefix, we're using the format function to add the prefix manually.
It seems for now this is low prio for them and as a workaround I should use
echo "value=${{ github.ref || format('{0}{1}', 'refs/tags/', github.event.release.tag_name) }}" >> $GITHUB_OUTPUT
to get release ref without random problems.
@piotrekkr Thanks for coming back and reporting the convo with support! 👍