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

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

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

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

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


当前回答

在最近的更新中,您现在可以将if条件放在工作级别。请在这里查看文档。https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idif

我测试了这个工作流,它在每次推送时运行作业测试,但只在主分支上运行部署。

name: my workflow
on: push
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Execute tests
        run: exit 0
  deploy:
    runs-on: ubuntu-latest
    needs: test
    if: github.ref == 'refs/heads/master'
    steps:
      - name: Deploy app
        run: exit 0

以下是我最初的答案,如果您喜欢有单独的工作流,则可以选择另一种解决方案。

第一个工作流运行于除master之外的每个分支。在此工作流中只运行测试。

on:
  push:
    branches:
      - '*'
      - '!master'

第二个工作流仅为master运行,如果测试成功通过,则运行您的测试和部署。

on:
  push:
    branches:
      - master

其他回答

2022

下面的工作流程只在主分支的推送中运行:

name: Distribute to Firebase

on:
  push:
    branches: [ main ]
jobs:
...

大多数答案都为单个分支提供了解决方案。要限制作业在任何特定的分支集上运行,可以使用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: …

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

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

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

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

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

2021年更新

我知道有可能只在特定的工作流上运行整个工作流 分支,然而,这意味着我将有一个“测试”工作流和一个 “部署”的工作流。 这听起来像是一个解决方案,但它们是并行的。在一个 理想的情况是,测试将首先运行,并且只有在他们成功的情况下 deploy作业将启动。当使用两个单独的时候,情况就不是这样了 工作流。

现在,您可以使用事件workflow_run来实现测试首先运行的部分,并且只有当测试成功时,才会启动部署作业(请继续阅读以了解如何执行):

workflow_run的文档页面

https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#workflow_run

请求或完成工作流运行时发生此事件 的完成结果允许您执行工作流 另一个工作流。不管结果如何,都会触发工作流运行 前面的工作流。 例如,如果您的pull_request工作流生成构建工件, 您可以创建一个新的工作流,使用workflow_run来分析 结果,并向原始拉请求添加注释。

现在,考虑OP的初始问题:

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

现在这个问题可以这样解决:

下面的设置正在工作,几分钟前,我刚刚在我的一个存储库中实现了相同的逻辑

工作流< your_repo > / .github /工作流/ tests.yml

name: My tests workflow

on:
  push:
    branches:
      - master
  pull_request: {}

jobs:
  test:

    # ... your implementation to run your tests

工作流< your_repo > / .github /工作流/ deploy.yml

name: My deploy workflow

on:
  workflow_run:
    workflows: My tests workflow # Reuse the name of your tests workflow
    branches: master
    types: completed

jobs:
  deploy:
    # `if` required because a workflow run is triggered regardless of
    # the result of the previous workflow (see the documentation page)
    if: ${{ github.event.workflow_run.conclusion == 'success' }}

    # ... your implementation to deploy your project

您需要将这两个脚本添加到工作流中

//main.yml
name: main
on:
  push:
    branches:
      - main


//size.yml     
name: size
on:
  pull_request:
    branches:
      - main