wea*_*dan 5 github github-actions
我是GitHub Actions的新手,有2个工作-一个运行我的测试,另一个将我的项目部署到服务器上。
显然,我希望测试可以在每个分支上运行,但是部署应该仅在将某些内容推入主程序时进行。
我正在努力寻找一种在特定分支上运行作业的方法。我知道有可能只在特定分支上运行整个工作流程,但这意味着我将拥有一个“测试”工作流程和一个“部署”工作流程。
这听起来像是一个解决方案,但是它们将并行运行。在理想情况下,测试将首先运行,并且只有在测试成功的情况下,部署工作才能开始。使用2个单独的工作流时不是这种情况。
我将如何实现这一目标?是否可以在特定分支上运行作业?
小智 32
我知道可以只在特定分支上运行整个工作流程,但这意味着我将有一个“测试”工作流程和一个“部署”工作流程。
这听起来像是一个解决方案,但是它们将并行运行。在理想的情况下,测试将首先运行,只有成功后,部署作业才会开始。使用两个单独的工作流程时,情况并非如此。
您现在可以使用该事件workflow_run来实现该部分the tests would run first, and only if they succeed, then the deploy job would start(继续阅读以了解如何操作):
文档页面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/workflows/tests.yml
name: My tests workflow
on:
push:
branches:
- master
pull_request: {}
jobs:
test:
# ... your implementation to run your tests
Run Code Online (Sandbox Code Playgroud)
工作流程<your_repo>/.github/workflows/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
Run Code Online (Sandbox Code Playgroud)
bra*_*adj 23
这是我为只应在特定分支上运行的步骤所做的工作。
- name: Publish Image
# Develop branch only
if: github.ref == 'refs/heads/develop'
run: |
... publish commands ...
Run Code Online (Sandbox Code Playgroud)
goe*_*tzc 22
大多数的答案提供了一个解决一个单一的分支。要限制作业在任何特定的分支集上运行,您可以使用if带有多个析取 ( ||) 运算符的条件来实现;但这太冗长了,不尊重DRY 原则。
使用该contains功能可以以更少的重复进行存档。
使用contains:
contains('
refs/heads/dev
refs/heads/staging
refs/heads/production
', github.ref)
Run Code Online (Sandbox Code Playgroud)
与使用多个相比||:
github.ref == 'refs/heads/dev' || 'refs/heads/staging' || github.ref == 'refs/heads/production' || …
Run Code Online (Sandbox Code Playgroud)
完整示例:
---
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: …
Run Code Online (Sandbox Code Playgroud)
lon*_*mer 13
虽然这个讨论很老了,但最近我遇到了同样的问题,只是做了一些补充。if条件来检查分支是否main有效,但是如果有人推送他们的分支并更新工作流 yml 文件以删除if条件怎么办?部署作业将在其分支未经审查或合并的情况下被触发main,并且可能会破坏生产环境。这可能是开源项目中的一个问题。
我在任何地方都找不到这个问题的答案,所以想分享我的发现。我希望这是适合它的线程。
为了确保除了特定分支之外不会触发作业,可以使用环境。部署作业很可能有一些 api 密钥来连接到可能存储在机密中的目标服务器。我们不应该将它们存储在存储库内可全局访问的存储库机密中,而应该将它们存储在各自的环境中。
环境的官方文档包含示例脚本的详细说明,但在这里分享一个简单的示例。假设我们只想在main更新时运行生产部署
production环境Selected Branches在下拉列表中选择Deployment Branches并添加main图案在工作流程 yml 中,我们只需要添加环境信息environment: production,如下所示(使用 @peterevans 答案中的脚本)
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/main'
environment: production
steps:
- name: Deploy app
run: exit 0
Run Code Online (Sandbox Code Playgroud)
环境信息指示必须从何处读取机密。如果当前分支名称与提供的模式不匹配,Selected Branches则作业将立即失败并出现错误。由于我们有一个条件只能在 上运行此操作main,因此通常这不会打扰我们,因为无论如何都会在其他分支上跳过此作业。但是,如果有人错误地或恶意地修改了 yml 文件并在推送分支之前删除了条件,他们就会收到错误。因此,我们的系统至少免受这里的威胁。
希望这可以帮助任何有同样疑问的人。
对于步骤或作业,您还可以使用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
Run Code Online (Sandbox Code Playgroud)
有关 github 上下文的更多信息请查看此处。
在最近的更新中,您现在可以将if条件设置为job水平。请参阅此处的文档。https://help.github.com/cn/articles/workflow-syntax-for-github-actions#jobsjob_idif
我测试了此工作流程,该工作流程可test在每次推送时运行该作业,但仅deploy在master分支上运行。
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
Run Code Online (Sandbox Code Playgroud)
接下来是我的原始答案,如果您希望拥有单独的工作流程,还可以使用其他解决方案。
除以外的每个分支都将运行第一个工作流程master。在此工作流程中,您仅运行测试。
on:
push:
branches:
- '*'
- '!master'
Run Code Online (Sandbox Code Playgroud)
第二个工作流只master运行一次,如果测试成功通过,则运行您的测试并部署。
on:
push:
branches:
- master
Run Code Online (Sandbox Code Playgroud)
以下内容对我在工作中有用:
if: contains(github.base_ref, 'staging')
|| contains(github.base_ref, 'production')
Run Code Online (Sandbox Code Playgroud)
if: contains(github.head_ref, 'feature')
|| contains(github.head_ref, 'release')
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
406 次 |
| 最近记录: |