GitHub 动作:默认分支变量

42

有没有智能的方法来确定 GitHub Actions 中的默认分支?

现在我需要写类似这样的内容:

on:
  push:
    branches:
      - master

有没有一种方法可以编写类似下面的代码?

on:
  push:
    branches:
      - $default-branch

我尝试使用谷歌搜索,但没有找到任何相关内容。

9个回答

55
我无意中找到了一个非常好的解决办法。这将评估分支名称,例如master。
${{ github.event.repository.default_branch }}

另外,我也从一次次的失败中发现了一个问题,那就是always()是有副作用的:如果没有调用always(),即使其他条件为真,我的工作也会被跳过。
这个方法只在默认分支上运行工作。
  if: ${{ always() && format('refs/heads/{0}', github.event.repository.default_branch) == github.ref }}

14
“${{ github.event.repository.default_branch }}”表达式可在作业中使用,但不能用于“on:”语句下的事件触发器定义,正如此问题所要求的那样。 - ddelange
1
这似乎无法与计划触发器一起工作。 - felipecrs
1
这种方法对我来说可以不用 always() 而运行。只需要 if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch) 即可。 - Gus
这个语句在我的if语句中起作用:if: github.ref == github.event.repository.default_branch - undefined
1
你可以通过使用以下方式来避免格式字符串:github.event.ref_name == github.event.repository.default_branch - undefined
显示剩余4条评论

30

该死!他们本可以做对的,为默认分支添加一个占位符。 - sorin

11
- if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
  run: echo "On the default branch"
- if: github.ref != format('refs/heads/{0}', github.event.repository.default_branch)
  run: echo "Not on the default branch"

编辑2023年

正如Elijah在评论中指出的那样,现在有一个新的ref_name字段可用。简化如下:

- if: github.ref_name == github.event.repository.default_branch
  run: echo "On the default branch"
- if: github.ref != github.event.repository.default_branch
  run: echo "Not on the default branch"

有趣的是,我查看了示例文档以打印上下文,看起来这在github.event.repository.master_branch中找到。 - Chris Knoll
@ChrisKnoll - 你有构建链接吗?那的确听起来很奇怪。 - friederbluemle
抱歉回复晚了,但我在文档中找不到参考资料,然而,为了检查负载对象中的内容,我“回显”了github.event JSON的内容,并在对象图中找到了该元素。 - Chris Knoll
1
使用 github.ref_name == github.event.repository.default_branch 来避免格式字符串。 - undefined

3

可以根据默认分支有条件地运行作业:

jobs:
  job-one:
    if: github.ref_name == github.event.repository.default_branch
    ...

您可以在默认分支上有条件地运行步骤:
jobs:
  job-one:
    steps:
      - name: step one
        if: github.ref_name == github.event.repository.default_branch
        ...

2

您可以在模板中使用$default-branch,当该模板被渲染到新存储库中时,它将被替换为存储库的默认分支名称(当时),但这是一个非常有限的用例,并且仍然无法帮助您当默认分支的名称更改时。我想到的最好方法是列出组织中所有默认分支的名称,如下所示:

on:
  push:
    branches:
      - master
      - main
      - root
      - default
      - production

然后您可以选择相信仓库不会有那些名称的非默认分支,或者启动作业并通过添加if条件进行过滤。

if: github.event.push.ref == format('refs/heads/{}', github.event.repository.default_branch)

Side note

For most events

${{ github.event.repository.default_branch }}

这段代码在正常运行时没有问题,但是通过计划事件运行时会出现问题。当github.event_name == "schedule"时,github.event中唯一的元素是计划事件(触发运行的字符串)。

在GitHub操作中,在可用的GitHub运行器上运行时,以下代码更可靠地获取默认分支名称:

gh repo view --json defaultBranchRef --jq .defaultBranchRef.name

然而,当您想要将默认分支作为触发运行的目标时,这并没有帮助到OP。

github.event.push.ref 是 ""。我使用了 if: github.ref_name == github.event.repository.default_branch 代替。 - undefined
@Elijah github.event.push.ref 只在push事件上起作用,这正是OP所询问的内容。 - undefined
我的 GH Actions 也是推动驱动的:https://github.com/elibroftw/blog.elijahlopez.ca/blob/master/.github/workflows/gh-pages.yml#L3。更不用说 GH Actions 的 vscode 扩展还为 github.event.push.ref 添加了一个 linting 错误。这里有证据表明 event.push.ref 是有问题的:https://github.com/elibroftw/blog.elijahlopez.ca/actions/runs/6916089771/job/18815753810。另外,因为你有防御性,你的格式字符串也是不正确的:https://github.com/elibroftw/blog.elijahlopez.ca/actions/runs/6915840457/job/18815230745。 - undefined

2

目前无法做到这一点。请在GitHub 社区上查看此主题。

您只能在此级别访问变量。

工作流程无效。.github/workflows/so-004-variables-in-trigger.yaml(第7行,第9列):无法识别的命名值:“env”。位于表达式内的位置1:env.default-branch

您可以考虑根据分支名称添加过滤器,例如这里,但目前您无法实现所需的功能。


请删除您的回答。github.event.repository.default_branch 是正确的方式。 - undefined

1
将此步骤添加到您的工作中:
    - name: Determine default branch
      run: |
        DEFAULT_BRANCH=$(git remote show origin | awk '/HEAD branch/ {print $NF}')
        echo "default_branch=$DEFAULT_BRANCH" >> $GITHUB_ENV
        echo "default_branch_ref=refs/heads/$DEFAULT_BRANCH" >> $GITHUB_ENV

这将在env环境变量中添加一个default_branchdefault_branch_ref变量。然后您可以在后续步骤中使用${{ env.default_branch }}访问默认分支名称。 default_branch_ref变量可用于直接与github.ref进行比较,以确定是否位于默认分支。

该方法使用当前设置环境变量以供稍后使用的方法[1]和JoeLinux确定默认分支名称的方法[2]

完整的工作流示例:

name: ci

on: [push, pull_request]

jobs:
  ci:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2

    - name: Determine default branch
      run: |
        DEFAULT_BRANCH=$(git remote show origin | awk '/HEAD branch/ {print $NF}')
        echo "default_branch=$DEFAULT_BRANCH" >> $GITHUB_ENV
        echo "default_branch_ref=refs/heads/$DEFAULT_BRANCH" >> $GITHUB_ENV

    - name: debug
      run: echo ${{ env.default_branch }}

    - name: Deploy
      if: github.ref == env.default_branch_ref
      run: echo "Run!"

1

尽管这在问题的具体代码中不起作用,但它确实涵盖了标题和主要问题的写作。

您可以做的更简单的事情就是指定一个环境变量:

env:
  DEFAULT_BRANCH: refs/heads/${{ github.event.repository.default_branch }}

0
希望将来有更好的方法来完成这个任务。在那之前,您可以使用GitHub API并将结果保存在命名步骤输出中。
例如:
    - name: Extract default branch name
      shell: bash
      run: |
        owner="my-org"
        repo="repo_x"
        branch=$(curl -L -H 'authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' \
            https://api.github.com/repos/${owner}/${repo} \
            | jq .default_branch)
        echo "##[set-output name=default_branch;]$(echo ${branch})"
      id: repo_x
...
${{ steps.repo_x.outputs.default_branch }}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接