【问题标题】:How to get the current branch within Github Actions?如何在 Github Actions 中获取当前分支?
【发布时间】:2020-01-21 19:22:54
【问题描述】:

我正在使用 Github Actions 构建 Docker 映像,并希望使用分支名称标记映像。

我找到了GITHUB_REF 变量,但它的结果是refs/heads/feature-branch-1,我只需要feature-branch-1

【问题讨论】:

  • 使用此操作:github.com/EthanSK/git-branch-name-action 它适用于 pull_request 和 push trigger
  • 恕我直言 stackoverflow.com/a/64210623/680454 应该是公认的答案;它处理@ambientlight 对当前接受的答案的反对,它避免使用现已弃用的setenv,并且它不使用任何外部包含。
  • 我在 GitHub 上打开了一个 Feature Request 来添加对此的原生支持。许多其他 CI 提供程序(Travis CI、CircleCI、Semaphore CI)都有本机支持,所以添加这样的东西有很好的优先级。如果您希望添加此行为,请对功能请求进行投票!

标签: github github-actions


【解决方案1】:

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

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

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

- 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 }}

【讨论】:

  • $GITHUB_REF 看起来像 (refs/pull/33/merge),$GITHUB_HEAD_REF 将只存储源分支名称,而 $GITHUB_BASE_REF 将代表 RP 目标分支。也许您可以在设置时更新您的答案以回退到 $GITHUB_HEAD_REF,您怎么看?
  • GITHUB_HEAD_REF 是头引用,格式相同,但仅适用于拉取请求。
  • 短版:run: echo "##[set-output name=branch;]${GITHUB_REF#refs/heads/}"
【解决方案2】:

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

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

${GITHUB_REF##*/}

例子:

$ GITHUB_REF=refs/heads/feature-branch-1
$ echo ${GITHUB_REF##*/}
feature-branch-1

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

工作流程

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##*/} .

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

示例输出 - master 分支

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

日志: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

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


有关参数扩展语法的更多信息,请参阅this answer

作为参考,Virtual environments for GitHub Actions 页面列出了执行环境中可用的所有环境变量。

【讨论】:

  • 这将在 shell 脚本中起作用,但在工作流 YAML 文件中不起作用
  • @aborilov 你确定它不起作用吗?如果我正确理解了您的目标,那么它在我刚刚创建的 MVP 中对我有用。为了方便起见,我更新了我的答案以包含示例工作流 yaml 代码和示例运行链接。希望这会有所帮助!
  • 是的,这适用于run 步骤,但是当我将图像推送到 ECR 时,我还需要 ENV vars 中的分支名称
  • 请注意,如果您使用 Gitflow 风格的分支名称,例如 feature/foo${GITHUB_REF##*/} 语法将无法满足您的要求:它会从分支名称中删除 feature/,然后返回 @ 987654337@。我建议使用${GITHUB_REF#refs/heads/} 而不是${GITHUB_REF##*/},这样refs/heads/feature/foo 就会变成feature/foo。如果您的 ref 是 PR,这将不起作用,而不是 refs/heads/branchname$GITHUB_REF 的值将是 pull/123/merge... 但如果您的工作流程脚本需要 PR,您可能知道它(例如,您重新触发pull_request)。
  • 我们现在可以简单地使用GITHUB_REF_NAME。不需要从GITHUB_REF 中提取。更多info.
【解决方案3】:

请注意,如果您在拉取请求触发器上执行 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

【讨论】:

  • 谢谢!仅供参考,这也可以作为 env var GITHUB_HEAD_REF 使用。
  • 这个答案应该在列表中更高。
  • 您能否修改此答案,并选择适用于两种情况的选项,例如${GITHUB_HEAD_REF-${GITHUB_REF##*/}}
【解决方案4】:

使用setenvnow deprecated。建议使用environment files。基于@youjin 的answer,同时仍然允许feature/ 分支(用- 替换所有出现的/),我现在正在使用这个:

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 }}

【讨论】:

  • 非常感谢。请注意,如果工作目录不同,最终可能会出现“错误:没有这样的文件或目录”。设置working-directory: . 应该这样做,以防将不同的路径设置为默认值。
  • 不幸的是,这对我不起作用。另见this GitHub issue
【解决方案5】:

你可以使用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

【讨论】:

  • 谢谢。这对于使用操作而不是在 shell 中运行命令的步骤非常有用
  • 尝试了 3-5 个不同的其他答案,这个更容易使用。
【解决方案6】:

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

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

steps:
  - name: Prints the current branch name
    run: echo "${GITHUB_BRANCH##*/}"
    env:
      GITHUB_BRANCH: ${{ github.ref }}

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

steps:
  - name: Prints the current branch name
    run: echo "${GITHUB_REF#refs/heads/}"

致谢:@rmunn comment

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

steps:
  - name: Get the current branch name
    shell: bash
    run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}"
    id: myref

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

注意事项:

【讨论】:

  • 我喜欢这个使用输出的答案。许多其他答案都有问题。
【解决方案7】:

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"

存储库的demo workflows file 中还提供了适用于所有操作系统(Linux、macOS 和 Windows)的演示!

【讨论】:

    【解决方案8】:

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

    - 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}"
    

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

    Rmq:sed 's/\//_/g' 是用_ 替换分支名称中的/

    【讨论】:

    • 如果您在 Windows 中运行步骤,请按以下步骤操作:- run: echo ("::set-env name=BRANCH_NAME::" + $env:GITHUB_REF.replace('refs/heads/', ''))。该命令的 shell 应该是默认的 powershell。
    • 已弃用
    【解决方案9】:

    我刚刚使用 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/})
    

    这是输出的截图:

    所以${GITHUB_REF##*/}$(echo ${GITHUB_REF#refs/heads/}) 都是正确的

    【讨论】:

      【解决方案10】:

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

      name: whichBranch
      on: [pull_request, push]
      
      jobs:
        which_branch:
          runs-on: ubuntu-latest
          steps:
            - name: Extract branch name on push
              if: github.event_name != 'pull_request'
              shell: bash
              run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/})"
              id: extract_branch
      
            - name: Extract branch name on pull request
              if: github.event_name == 'pull_request'
              run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_HEAD_REF})"
      
            - name: Print branch name
              run: echo 'The branch name is' $BRANCH_NAME
      

      【讨论】:

        【解决方案11】:

        更新

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

        https://docs.github.com/en/actions/learn-github-actions/environment-variables 上的 GitHub 文档

        【讨论】:

        • 这适用于哪些活动?
        • @AnshulSahni 我相信它适用于所有活动。对于某些变量仅可用于特定事件集的情况,文档指向哪些事件。与GITHUB_HEAD_REF 一样,引用; “只为拉取请求事件设置。头分支的名称。”
        【解决方案12】:
        ${{ github.ref_name }}
        

        至少对于推送来说似乎可以正常工作。

        【讨论】:

          【解决方案13】:

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

          【讨论】:

            【解决方案14】:

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

            【解决方案15】:

            要同时处理pull_request 事件(在这种情况下,$GITHUB_REF 包含像refs/pull/519/merge 这样无用的东西),您可以使用这个衬垫:

               - name: Set branch name
                 run: echo "::set-output name=branch_name::$(echo ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}})"
            

            【讨论】:

              【解决方案16】:

              在 GitHub 操作上使用分支名称

              使用当前分支名称的便利操作。 用法

              name: build
              on: push
              
              jobs:
                build:
                  runs-on: ubuntu-latest
                  steps:
                  - uses: actions/checkout@v1
                  - run: npm ci
                  - uses: nelonoel/branch-name@v1
                  # Use branch name for whatever purpose
                  - run: echo ${BRANCH_NAME}
              

              【讨论】:

                【解决方案17】:

                对于使用 Windows 映像运行操作的人,需要了解的几个关键点:

                1. 假设 GitHub 操作使用 CMD shell 是不正确的。他们默认use PowerShell
                2. 您可以通过以下方式指定要使用的shell:
                - run: |
                    ...
                  shell: cmd
                
                1. 您可以使用值“bash”在 bash shell 的上下文中执行命令。

                因此,总而言之,您无需浪费可能的时间来试图弄清楚如何以破旧的 cmd 方式做事(就像我一样)。

                为了获取当前分支名称的简单目的,您可以在将 shell 设置为“bash”时使用流行的解决方案,或者使用例如以下简单方法在默认 PowerShell shell 中设置变量:

                $branchName = $Env:GITHUB_REF -replace "refs/heads/", ""
                

                【讨论】:

                  【解决方案18】:

                  无论是否触发 pull_request,我都做了一个获取分支名称的操作。 https://github.com/EthanSK/git-branch-name-action

                  【讨论】:

                    【解决方案19】:

                    同时处理pull_requestpush 事件的解决方案。由于不推荐使用set-env,因此实现了解决方法以保存获得的分支名称以进行进一步的步骤。 不需要第三方操作。

                    name: CI
                    on: [ pull_request, push ]
                    jobs:
                      build:
                        runs-on: ubuntu-latest
                        steps:
                          - name: "Get branch name and save to env"
                            env:
                              IS_PR: ${{ github.EVENT_NAME == 'pull_request' }}
                            run: |
                              if ${IS_PR}; then
                                BRANCH_NAME="${GITHUB_HEAD_REF}"
                              else
                                BRANCH_NAME="${GITHUB_REF##*/}"
                              fi
                              echo "BRANCH_NAME=${BRANCH_NAME}" >> $GITHUB_ENV
                    
                          - name: "Another step uses branch name"
                            run: echo "Branch name is ${{ env.BRANCH_NAME }}"
                    
                    

                    Runtime Variables in GitHub Actions

                    【讨论】:

                      【解决方案20】:

                      只需使用:

                      env:
                       BRANCH_NAME: ${{ github.head_ref || github.ref_name }} 
                      

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

                      【讨论】:

                        【解决方案21】:
                        if: github.ref == 'refs/heads/integration' && github.event_name == 'push' 
                        

                        您可以使用上述命令并替换您想要运行的任何分支或事件。

                        【讨论】:

                        • 这是做什么的?
                        【解决方案22】:

                        在 Windows 上运行? Windows 默认命令是 PowerShell 终端。

                          - name: SET CURRENT_BRANCH
                            run: |
                              $branchName = "${{github.ref}}".Split("/")["${{github.ref}}".Split("/").Length -1]
                              echo "::set-env name=CURRENT_BRANCH::$(echo $branchName)"
                        

                        【讨论】:

                        • 我只是做了$branchName = $Env:GITHUB_REF -replace "refs/heads/", ""。我不是 powershell 出口,所以我愿意接受你的推理
                        【解决方案23】:

                        这是一个 sn-p,它设置了一个基于 $GITHUB_REF 的环境变量,如果不存在,则默认为 dev

                        根据您的要求调整 sed 命令。

                        export GIT_BRANCH=$(echo ${GITHUB_REF:-dev} | sed s/.*\\///g)
                        

                        【讨论】:

                          【解决方案24】:

                          通常,我总是有一个用nodejspython 编写的脚本,它从workflow.yaml 调用。该脚本通常负责获取正确的分支引用等工作。

                          我在prepare-deployment.js 脚本中有一个类似下面的函数-

                          const VALID_REF_PREFIX = 'refs/heads/';
                          ...
                          
                          function getBranchRef(isProd = false) {
                            let branchRef = 'origin/master';
                          
                            if (isProd) {
                              return branchRef;
                            }
                            /**
                             * When the workflow is invoked from manual flow, the branch name
                             * is in GITHUB_REF, otherwise, we have to look into GITHUB_BASE_REF
                             */
                            if (GITHUB_REF.startsWith(VALID_REF_PREFIX)) {
                              // coming from a manual workflow trigger
                              branchName = `origin/${GITHUB_REF.replace(VALID_REF_PREFIX, '')}`;
                            } else {
                              // coming from a PR
                              branchRef = `origin/${GITHUB_HEAD_REF}`;
                            }
                          
                            return branchRef;
                          }
                          

                          这会处理以下场景-

                          1. 我想将更改从 PR 部署到我的开发环境
                          2. 我想通过手动触发器将我想要的任何分支的更改部署到我的开发环境中
                          3. 我想将更改从 master 部署到我的 prod env 中

                          【讨论】:

                            【解决方案25】:

                            有一个非常简单的 git 命令可以获取当前分支:

                            git rev-parse --abbrev-ref HEAD

                            要在 env 文件变量中获取输出,只需简单地说:

                             - 名称:设置 CURRENT_BRANCH
                                    运行: echo "CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)" >> $GITHUB_ENV

                            从 env 变量中获取输出:

                             - 名称:获取 CURRENT_BRANCH
                                    运行:回声 ${{ env.CURRENT_BRANCH}}

                            来源:https://www.techiedelight.com/determine-current-branch-name-git/

                            【讨论】:

                              【解决方案26】:

                              这里只是重复一下,以便更好地了解其他人在以前的回复中写成简单的 cmets:

                              https://docs.github.com/en/actions/learn-github-actions/environment-variables

                              分支名称​​仅用于拉取请求在此环境变量中公开:

                              GITHUB_HEAD_REF Only set for pull request events. The name of the head branch.

                              在 GitHub 动作中,对应的上下文键是:

                              github.head_ref
                              

                              【讨论】:

                                猜你喜欢
                                • 2022-06-21
                                • 2019-12-25
                                • 2020-01-30
                                • 1970-01-01
                                • 2020-10-01
                                • 2020-12-29
                                • 2022-01-08
                                • 1970-01-01
                                • 2020-08-20
                                相关资源
                                最近更新 更多