如何在github动作中获取当前分支

abo*_*lov 7 github github-actions

我正在使用Github Actions构建docker映像,并想用分支名称标记映像,我只找到了GITHUB_REF变量,但结果是refs/heads/feature-branch-1,我只需要feature-branch-1

ysf*_*ran 197

长话短说

这适用于您可以在on(例如pushpull_request)下指定的每个触发器:

env:
 BRANCH_NAME: ${{ github.head_ref || github.ref_name }} 
Run Code Online (Sandbox Code Playgroud)

解释

诀窍是,github.head_ref仅当工作流由 a 触发时才设置pull_request,并且它包含 PR 源分支的值。 github.ref_name仅当工作流不是由 a 触发pull_request并且它也只包含分支名称时才会使用。

GitHub 文档

来自GitHub官方文档的详细解释:

github.ref_name string 触发工作流运行的分支或标签的短引用名称。该值与 GitHub 上显示的分支或标签名称匹配。例如,功能分支-1。

github.head_ref string 工作流程运行中拉取请求的 head_ref 或源分支。仅当触发工作流运行的事件是 pull_request 或 pull_request_target 时,此属性才可用。

  • 这是唯一一个对我有用的尝试获取 github 操作的分支名称的方法,该操作在将新提交推送到拉取请求时触发。 (10认同)
  • 很棒的单行解决方案。请注意,如果所需的是拉取请求的 **目标分支**,则应设置 env `BRANCH_NAME: ${{ github.base_ref || github.ref_name }}` 相反,因为 `github.head_ref` 返回源分支(例如“feat/to-be-merged”)而不是目标(例如“main”)。 (3认同)

Tay*_*ton 115

我相信GITHUB_REF是唯一包含分支名称的环境变量。

您可以像这样从该字符串的其余部分中提取分支名称:

${GITHUB_REF##*/}
Run Code Online (Sandbox Code Playgroud)

例子:

$ GITHUB_REF=refs/heads/feature-branch-1
$ echo ${GITHUB_REF##*/}
feature-branch-1
Run Code Online (Sandbox Code Playgroud)

更新:添加了一个完整的工作流程示例。

工作流程

name: CI
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Git checkout
        uses: actions/checkout@v1
      - name: Branch name
        run: echo running on branch ${GITHUB_REF##*/}
      - name: Build
        run: docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
Run Code Online (Sandbox Code Playgroud)

来源:https : //github.com/tedmiston/x/blob/master/.github/workflows/workflow.yml

示例输出 - 主分支

Run docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  shell: /bin/bash -e {0}
Sending build context to Docker daemon  146.9kB

Step 1/1 : FROM alpine
latest: Pulling from library/alpine
9d48c3bd43c5: Pulling fs layer
9d48c3bd43c5: Verifying Checksum
9d48c3bd43c5: Download complete
9d48c3bd43c5: Pull complete
Digest: sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb
Status: Downloaded newer image for alpine:latest
 ---> 961769676411
Successfully built 961769676411
Successfully tagged tedmiston/tag-example:master
Run Code Online (Sandbox Code Playgroud)

日志:https : //github.com/tedmiston/x/commit/cdcc58a908e41d3d90c39ab3bf6fef1ad2c4238a/checks#step :4 :16

示例输出 - 非主分支

Run docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  shell: /bin/bash -e {0}
Sending build context to Docker daemon  144.9kB

Step 1/1 : FROM alpine
latest: Pulling from library/alpine
9d48c3bd43c5: Pulling fs layer
9d48c3bd43c5: Verifying Checksum
9d48c3bd43c5: Download complete
9d48c3bd43c5: Pull complete
Digest: sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb
Status: Downloaded newer image for alpine:latest
 ---> 961769676411
Successfully built 961769676411
Successfully tagged tedmiston/tag-example:branch-name-test
Run Code Online (Sandbox Code Playgroud)

日志:https : //github.com/tedmiston/x/commit/4e8d31259f861aaa2c30375756fc081c3659bddf/checks#step :4 :16


有关参数扩展语法的更多信息,请参阅此答案

作为参考,GitHub 操作的虚拟环境页面列出了执行环境中可用的所有环境变量。

  • 请注意,如果您使用 Gitflow 风格的分支名称,例如 `feature/foo`,则 `${GITHUB_REF##*/}` 语法将不会执行您想要的操作:它会从分支名称中删除 `feature/`,而只是返回`foo`。我建议使用 `${GITHUB_REF#refs/heads/}` 而不是 `${GITHUB_REF##*/}`,这样 `refs/heads/feature/foo` 将变成 `feature/foo`。如果您的 ref 是 PR,那么这将不起作用,其中“$GITHUB_REF”的值不是“refs/heads/branchname”,而是“pull/123/merge”...但是如果您的工作流脚本期望 PR ,您可能知道这一点(例如您正在触发“pull_request”)。 (60认同)
  • 我们现在可以简单地使用`GITHUB_REF_NAME`。不需要从`GITHUB_REF`中提取。更多[信息](https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables)。 (48认同)
  • 这将在 shell 脚本中工作,但在工作流程 YAML 文件中不起作用 (2认同)

Dus*_*vak 82

请注意,如果您在拉取请求触发器上执行您的 GitHub 操作,那么GITHUB_REF变量将包含类似的内容refs/pull/421/merge,如果您尝试git push使用该名称,它很可能会失败。

您可以使用的是 YAML 中 GitHub 上下文中的引用。就像是:${{ github.head_ref }}

https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-context

Github 操作上下文参考

  • 谢谢!仅供参考,这也可以用作环境变量 GITHUB_HEAD_REF。 (15认同)
  • 这个答案应该在列表中更高的位置。 (3认同)
  • 您可以修改此答案,使用适用于“${GITHUB_HEAD_REF-${GITHUB_REF##*/}}”等两种情况的选项吗? (3认同)
  • 这个 `##*/` 语法是什么 (2认同)

小智 66

更新

GitHub 现在支持GITHUB_REF_NAME,它代表:The branch or tag name that triggered the workflow run

GitHub 文档在此https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables

  • 这是2022年最相关的答案! (6认同)
  • 您还可以在 github 操作中使用 `${{ github.ref_name }}` (3认同)
  • `if: ${{ github.event_name == 'pull_request' }} run: echo "This is a PR for ${{ github.ref_name }}"` 不幸的是,这不会打印出分支名称 :( 我的分支名称是“feature/foo”,但我得到的是:“这是 438/merge 的 PR” (2认同)

Ant*_*ine 27

你可以使用https://github.com/rlespinasse/github-slug-action

# Just add this  => 
- name: Inject slug/short variables
  uses: rlespinasse/github-slug-action@v3.x



# And you get this  => 
- name: Print slug/short variables
  run: |
    echo "Slug variables"
    echo " - ${{ env.GITHUB_REF_SLUG }}"    
    echo " - ${{ env.GITHUB_HEAD_REF_SLUG }}"
    echo " - ${{ env.GITHUB_BASE_REF_SLUG }}"
    echo " - ${{ env.GITHUB_REPOSITORY_SLUG }}"
    # output e.g. : master feat-new-feature v1.0.0 product-1.0.0-rc.2 new-awesome-product
    echo "Slug URL variables"
    echo " - ${{ env.GITHUB_REF_SLUG_URL }}"
    echo " - ${{ env.GITHUB_HEAD_REF_SLUG_URL }}"
    echo " - ${{ env.GITHUB_BASE_REF_SLUG_URL }}"
    echo " - ${{ env.GITHUB_REPOSITORY_SLUG_URL }}"
    # output e.g. : master feat-new-feature v1-0-0 product-1-0-0-rc-2 new-awesome-product
    echo "Short SHA variables"
    echo " - ${{ env.GITHUB_SHA_SHORT }}"
    # output e.g. : ffac537e
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。对于使用操作而不是在 shell 中运行命令的步骤非常有用 (2认同)
  • 尝试了 3-5 个不同的其他答案,这个答案更容易使用。 (2认同)

ssh*_*how 25

使用setenv现在已经过时。建议使用环境文件。基于@youjin 的回答,同时仍然允许feature/ 分支(替换所有出现的/with -),我现在使用这个:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Get branch name (merge)
        if: github.event_name != 'pull_request'
        shell: bash
        run: echo "BRANCH_NAME=$(echo ${GITHUB_REF#refs/heads/} | tr / -)" >> $GITHUB_ENV

      - name: Get branch name (pull request)
        if: github.event_name == 'pull_request'
        shell: bash
        run: echo "BRANCH_NAME=$(echo ${GITHUB_HEAD_REF} | tr / -)" >> $GITHUB_ENV

      - name: Debug
        run: echo ${{ env.BRANCH_NAME }}
Run Code Online (Sandbox Code Playgroud)


Chr*_*ook 25

对于那些刚刚找到此线程的人,您现在可以使用GITHUB_REF_NAME例如${{ github.ref_name }}https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables

因此,如果您的触发操作工作流分支是main此变量将设置为main。例如,如果您有多个带有release和分支的存储库,这非常有用。main


Nae*_*Nae 18

${{ github.ref_name }}
Run Code Online (Sandbox Code Playgroud)

似乎至少对于推动来说效果很好。有关更多详细信息,请参阅ref_name 。它说:

The branch or tag name that triggered the workflow run.


LE *_*oît 11

要将其设置为 en 变量,我使用以下语法:

- name: Extract branch name
  shell: bash
  run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
- name: Test
  run: echo "${BRANCH_NAME}"
Run Code Online (Sandbox Code Playgroud)

我在这里找到了这个语法:Github actions - starter worflows#How to define env variable? 第68话

RMQ:sed 's/\//_/g'是替换/通过_在分支名

  • 这已被弃用 (3认同)

ken*_*orb 11

如何在 Github Actions 中获取当前分支?

假设${{ github.ref }}类似于refs/heads/mybranch,您可以使用以下方法提取分支名称:

steps:
  - name: Prints the current branch name
    run: echo "${GITHUB_BRANCH##*/}"
    env:
      GITHUB_BRANCH: ${{ github.ref }}
Run Code Online (Sandbox Code Playgroud)

如果您的分支包含斜杠(例如feature/foo),请使用以下语法:

steps:
  - name: Prints the current branch name
    run: echo "${GITHUB_REF#refs/heads/}"
Run Code Online (Sandbox Code Playgroud)

致谢:@rmunn 评论

或者使用已接受答案中的方法,这里是更短的版本(lint 友好):

steps:
  - name: Get the current branch name
    shell: bash
    run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}"
    id: myref
Run Code Online (Sandbox Code Playgroud)

然后在其他步骤中参考${{ steps.myref.outputs.branch }}

笔记:


Che*_*ana 10

我刚刚使用 bash 脚本在GitHub Actions 中做了一个简单的测试:

#!/bin/bash

echo Reserved for REPO_NAME=${GITHUB_REPOSITORY##*/}
echo GITHUB_REF=${GITHUB_REF}
echo EXTRACT_GITHUB_REF=${GITHUB_REF##*/}
echo EXTRACT_GITHUB_REF_HEADS=$(echo ${GITHUB_REF#refs/heads/})

cd $REPO_NAME
git checkout ${GITHUB_REF##*/}
git checkout $(echo ${GITHUB_REF#refs/heads/})
Run Code Online (Sandbox Code Playgroud)

这是输出的屏幕截图:

在此处输入图片说明 所以${GITHUB_REF##*/}$(echo ${GITHUB_REF#refs/heads/})都是正确的


Fra*_*old 10

GitHub Action FranzDiebold/github-env-vars-action公开了几个有用的环境变量,例如当前分支名称和它们的 slug 值。我正是为这个用例做了这个动作。

用法

steps:
  - uses: FranzDiebold/github-env-vars-action@v1.2.0
  - name: Print environment variables
    run: |
      echo "GITHUB_REPOSITORY_SLUG=$GITHUB_REPOSITORY_SLUG"
      echo "GITHUB_REPOSITORY_OWNER=$GITHUB_REPOSITORY_OWNER"
      echo "GITHUB_REPOSITORY_OWNER_SLUG=$GITHUB_REPOSITORY_OWNER_SLUG"
      echo "GITHUB_REPOSITORY_NAME=$GITHUB_REPOSITORY_NAME"
      echo "GITHUB_REPOSITORY_NAME_SLUG=$GITHUB_REPOSITORY_NAME_SLUG"
      echo "GITHUB_REF_SLUG=$GITHUB_REF_SLUG"
      echo "GITHUB_REF_NAME=$GITHUB_REF_NAME"
      echo "GITHUB_REF_NAME_SLUG=$GITHUB_REF_NAME_SLUG"
      echo "GITHUB_SHA_SHORT=$GITHUB_SHA_SHORT"
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

存储库的演示工作流文件中还提供了适用于所有操作系统(Linux、macOS 和 Windows)的演示


abo*_*lov 9

我添加了一个单独的步骤,用于从中提取分支名称$GITHUB_REF并将其设置为步骤输出

- name: Extract branch name
      shell: bash
      run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
      id: extract_branch
Run Code Online (Sandbox Code Playgroud)

之后,我可以在以下步骤中使用它

- name: Push to ECR
      id: ecr
      uses: jwalton/gh-ecr-push@master
      with:
        access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        region: us-west-2
        image: eng:${{ steps.extract_branch.outputs.branch }}
Run Code Online (Sandbox Code Playgroud)

  • $GITHUB_REF 看起来像 (refs/pull/33/merge),$GITHUB_HEAD_REF 仅存储源分支名称,而 $GITHUB_BASE_REF 将表示 RP 目标分支。也许您可以在设置时更新您的答案以回退到 $GITHUB_HEAD_REF,您觉得怎么样? (15认同)
  • 感谢您在找到答案后花时间回答自己的问题 (11认同)
  • GITHUB_HEAD_REF 是头引用,其格式相同,但仅适用于拉取请求。 (5认同)
  • 较短版本:`run: echo "##[set-output name=branch;]${GITHUB_REF#refs/heads/}"` (3认同)

you*_*jin 7

这是一个适用于pushpull_request事件的完整工作流程

name: whichBranch
on: [pull_request, push]

jobs:
  which_branch:
    runs-on: ubuntu-latest
    steps:
      # extract branch name
      - name: Extract branch name
        if: github.event_name != 'pull_request'
        shell: bash
        run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/})"
        id: extract_branch

      # extract branch name on pull request
      - name: Print branch name
        if: github.event_name == 'pull_request'
        run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_HEAD_REF})"

      # print branch name
      - name: Get branch name
        run: echo 'The branch name is' $BRANCH_NAME
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您使用的是 V2,actions/checkout那么您始终可以运行git branch --show-current以获取当前签出的分支的名称。


Pie*_*rek 5

现在${{github.ref}}是获取分支名称的正确方法。请记住${{github.ref}}refs/heads/..前缀