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

Posted

技术标签:

【中文标题】如何在 Github Actions 中获取当前分支?【英文标题】:How to get the current branch within 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 恕我直言 ***.com/a/64210623/680454 应该是公认的答案;它处理@ambientlight 对当前接受的答案的反对,它避免使用现已弃用的setenv,并且它不使用任何外部包含。 我在 GitHub 上打开了一个 Feature Request 来添加对此的原生支持。许多其他 CI 提供程序(Travis CI、CircleCI、Semaphore CI)都有本机支持,所以添加这样的东西有很好的优先级。如果您希望添加此行为,请对功能请求进行投票! 【参考方案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】:

使用setenv 是now 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

注意事项:

上述方法仅适用于基于 Unix 的映像(Linux 和 macOS)。 对于文档,请阅读:Context and expression syntax for GitHub Actions。

【讨论】:

我喜欢这个使用输出的答案。许多其他答案都有问题。【参考方案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.refrefs/heads/.. 前缀

【讨论】:

You can also use github.ref_name to get the branch or tag name without the prefix.【参考方案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 映像运行操作的人,需要了解的几个关键点:

    假设 GitHub 操作使用 CMD shell 是不正确的。他们默认use PowerShell。 您可以通过以下方式指定要使用的shell:
- run: |
    ...
  shell: cmd
    您可以使用值“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;

这会处理以下场景-

    我想将更改从 PR 部署到我的开发环境 我想通过手动触发器将我想要的任何分支的更改部署到我的开发环境中 我想将更改从 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

【讨论】:

以上是关于如何在 Github Actions 中获取当前分支?的主要内容,如果未能解决你的问题,请参考以下文章

GitHub Actions:如何通过终端访问当前构建的日志

如何从 GitHub Actions 获取我的日志文件?

在 Github Actions 中获取 Maven 项目版本

如何使用 GitHub Actions 对构建工件进行版本化?

使用 GitHub Actions 在 .net 应用程序中填充特定于环境的变量

GitHub Actions API:获取查看工作流运行历史记录