我对GitHub Actions相对较新,我有2个工作-一个运行我的测试,一个将我的项目部署到服务器上。

显然,我希望测试在每个分支上运行,但是部署应该只在某些东西被推到master时进行。

我正在努力寻找一种在特定分支上运行工作的方法。我知道在一个特定的分支上只运行整个工作流是可能的,但是这意味着我将有一个“测试”工作流和一个“部署”工作流。

这听起来像是一个解决方案,但它们是并行的。在理想的情况下,测试将首先运行,并且只有当测试成功时,才会启动部署作业。当使用两个单独的工作流时,情况就不是这样了。

我怎样才能做到这一点呢?是否可以在特定的分支上运行作业?


当前回答

虽然你目前不能在作业级别拥有条件,但你可以在步骤级别拥有条件-请参阅GitHub动作的上下文和表达式语法。

要获得分支名称,目前的解决方案是检查GITHUB_REF环境变量-参见默认环境变量和这个问题的详细信息。

把它们放在一起——如果你决定在最后一个链接中使用公认的答案,你的工作流程可能是这样的:

jobs:

 test:
  runs-on: ubuntu-latest
  steps:
  - name: Run tests
    run: ./my-tests.sh

 deploy:
  runs-on: ubuntu-latest
  needs: test
  steps:
  - name: Extract branch name
    shell: bash
    run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
    id: extract_branch
  - name: Deploy
    run: ./deploy.sh
    if: steps.extract_branch.outputs.branch == 'master'

如果你宁愿把所有的东西都保存在工作流文件中,而不是分开的脚本,你可以在给定的工作中的每个步骤中添加If。


我希望这只是一个临时的解决方案,工作条件将在测试结束前添加。

其他回答

对于步骤或作业,您也可以使用github。Ref_name,它是触发工作流运行的分支或标记名称。

name: my workflow
on: push
jobs:
  if: github.ref_name == 'main'
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Execute tests
        run: exit 0

有关github上下文的更多信息请查看这里。

大多数答案都为单个分支提供了解决方案。要限制作业在任何特定的分支集上运行,可以使用if条件和多个分离操作符(||);但这太啰嗦了,不尊重DRY原则。

使用contains函数可以较少重复地归档相同的内容。

使用包含:

contains('
  refs/heads/dev
  refs/heads/staging
  refs/heads/production
', github.ref)

相比使用多个||:

github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/staging' || github.ref == 'refs/heads/production' || …

完整的例子:

---
on: push
jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Run tests
      run: …

  deployment:
    name: Deployment
    runs-on: ubuntu-latest
    needs: [test]
    if:
      contains('
        refs/heads/dev
        refs/heads/staging
        refs/heads/production
      ', github.ref)
    steps:
    - uses: actions/checkout@v2
    - name: Deploy
      run: …

下面是我为只应该在特定分支上运行的步骤所做的工作。

- name: Publish Image
  # Develop branch only
  if: github.ref == 'refs/heads/develop'
  run: |
    ... publish commands ...

虽然你目前不能在作业级别拥有条件,但你可以在步骤级别拥有条件-请参阅GitHub动作的上下文和表达式语法。

要获得分支名称,目前的解决方案是检查GITHUB_REF环境变量-参见默认环境变量和这个问题的详细信息。

把它们放在一起——如果你决定在最后一个链接中使用公认的答案,你的工作流程可能是这样的:

jobs:

 test:
  runs-on: ubuntu-latest
  steps:
  - name: Run tests
    run: ./my-tests.sh

 deploy:
  runs-on: ubuntu-latest
  needs: test
  steps:
  - name: Extract branch name
    shell: bash
    run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF##*/})"
    id: extract_branch
  - name: Deploy
    run: ./deploy.sh
    if: steps.extract_branch.outputs.branch == 'master'

如果你宁愿把所有的东西都保存在工作流文件中,而不是分开的脚本,你可以在给定的工作中的每个步骤中添加If。


我希望这只是一个临时的解决方案,工作条件将在测试结束前添加。

以下是我在一份工作中的经验:

当PR目标分支机构是下列分支之一时:

if: contains(github.base_ref, 'staging')
  || contains(github.base_ref, 'production')

当pull请求的源分支是其中之一时:

if: contains(github.head_ref, 'feature')
  || contains(github.head_ref, 'release')