如何在 GitHub Actions 中的 push 事件中跳过作业?

45

使用Travis CI,我们可以在提交的末尾添加后缀来跳过特定提交的构建。这在Travis CI中有描述。当我只编辑与代码无关的 README.md 文件且不需要触发预先构建时,我发现此功能非常实用。

[skip ci]

如何使用Github Actions跳过由on: push事件触发的作业?

name: Maven Build
on: [push]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Check-out project
      uses: actions/checkout@v1
    - name: Set up JDK 11.0.3
      uses: actions/setup-java@v1
      with:
        java-version: 11.0.3
    - name: Build with Maven
      run: mvn -B package --file pom.xml

答案摘要:

非常感谢所有提供各种解决方法的回答者。我相信每个人都需要针对其问题的起源和CI方法略微不同的东西。以下是答案列表,以供快速导航:

所有回答都值得点赞!如果您喜欢我的问题,那您应该双倍喜欢这些答案。


https://github.com/fkirc/skip-duplicate-actions 是一个简单的第三方解决方案,用于当 GitHub 的原生解决方案不够强大或灵活时使用。 - Mike76
2
新的(2021年2月)[skip ci]提交信息策略也很有趣:https://dev59.com/m1IH5IYBdhLWcg3weum6#66114678 - VonC
@VonC:这是一个很棒的功能!您本可以在此处回答。我已经在我的问题总结中链接了您的答案,因为我发现它非常有帮助。谢谢! - Nikolas Charalambidis
@NikolasCharalambidis 不是的:它基于提交消息,而你的问题更多是基于文件的,如果我没有弄错的话。 - VonC
这有点混乱。在Travis-CI中,我使用了基于提交的方法(我没有找到更好的方法)来跳过README.md文件的CI提交。这就是为什么我认为你的答案在那里很相关。 - Nikolas Charalambidis
4个回答

64

更新:请查看Helmisek的答案,该答案指出Github现在已经内置了跳过CI功能

仅当您想要跳过某些作业/步骤时,我的回答才有意义。


您可以尝试以下内容:

name: Maven Build
on: [push]

jobs:
  build:
    if: "!contains(github.event.commits[0].message, '[skip ci]')"
    runs-on: ubuntu-latest

    steps:
    - name: Check-out project
      uses: actions/checkout@v1
    - name: Set up JDK 11.0.3
      uses: actions/setup-java@v1
      with:
        java-version: 11.0.3
    - name: Build with Maven
      run: mvn -B package --file pom.xml

7
如果:"!contains(toJSON(github.event.commits.*.message),'[skip-ci]')" - Michał Miszczyszyn
这个答案非常有用,特别是当特定的提交不应该触发CI流水线时。感谢回答,点赞。 - Nikolas Charalambidis
你能给出一个git commit命令的例子,使得该操作被跳过吗? - Azamat Abdullaev
github.event似乎不再有commits[]列表,但似乎有:commits(作为一个数字)和commits_url(即https://api.github.com/repos/<org>/<repo>/pulls/<pr-num>/commits)用于PR推送事件。我猜现在应该使用API来获取提交记录。 - undefined

46
截至现在(2021年2月),Github Actions默认支持这种行为,无需进行解析等操作来处理默认情况。
参见:

Github Actions: 使用[skip ci]跳过pull request和push workflows

Github Actions现在支持通过查找提交消息中的一些常见关键字来跳过push和pull_request工作流程。

如果你的push或PR的HEAD提交中包含字符串[skip ci][ci skip][no ci][skip actions][actions skip],则触发push或pull_request事件的工作流将被跳过。

链接:Github Actions更新日志,2021年2月

4
我刚试过它,效果还不错。例如 chore: build script update [skip ci],它就被跳过了。 - Helmisek

40

我感受到那个盒子里有巨大的能量。我必须了解这些力量,我想看看它。git commit -m "更新workflow.yml以跳过对自述更改的运行[跳过ci]" - mts

2
Git 2.27 (Q2 2020) 采用了另一种方法:用户可以指定要构建哪些分支,而不是始终通过 Actions 在 GitHub 上构建所有分支。
请参见 Jeff King(peff)于 2020 年 5 月 7 日提交的 e76eec3 提交记录。 (由 Junio C Hamano(gitster)于 2020 年 5 月 13 日在提交记录 dd4a287 中合并。)

ci:允许GitHub Actions的每个分支进行配置

Signed-off-by: Jeff King

根据个人开发者的工作流程,我们的GitHub Actions CI作业在每个分支上运行可能会很方便,也可能会很烦人。

例如,如果您有许多未完成的工作进展分支,并经常对其进行变基,则会收到许多不感兴趣的失败报告(更不用说浪费CPU了)。

此提交添加了一个新作业,该作业检查存储库中的特殊分支的CI配置,然后运行它在那里找到的shell脚本来决定是否跳过其余的测试

如果缺少该分支或脚本,则默认将继续为所有引用运行测试。

已经讨论了一些替代方案:

其中一种选择是在提交本身中携带有关是否应进行测试的信息,可以在树本身中(更改工作流程YAML文件)或提交消息中("[skip ci]"标志或类似标志)中实现。但是这些使用起来很令人沮丧且容易出错:

  • 您必须手动将它们应用于要标记的每个分支
  • 很容易泄漏到其他工作流程中,例如通过电子邮件发送补丁

我们也可以尝试从分支名称中获取一些信息。 但是,这会导致关于默认值应该是“关闭”还是“开启”的争论,并且覆盖仍然变得有些笨拙。
如果我们默认为“开启”,则必须记住适当命名分支以跳过CI。
如果为“关闭”,则必须扭曲分支名称或使用额外的refspec重复推送。

相比之下,此提交的解决方案让您指定配置一次并忘记它,而所有数据都在其自己的ref中,可以由各个分支进行更改,而无需触及主树。

在列表讨论中出现了一些设计决策。 我在此总结一下:

  • 我们可以使用GitHub的API检索配置引用,而不是真正的checkout(然后只通过一些javascript操作它)。
    无论哪种方式,我们仍然必须从它的虚拟机上旋转并通过网络与GitHub联系,因此速度不会快多少。
    我选择使用shell来保持与其他工具的相似性(实际上可以在任何您想要的语言中实现allow-refs)。 这也使得您可以在本地测试脚本,并在正常的git.git树的上下文中修改它。

  • 我们可以将众所周知的refname保留在refs/heads/之外,以避免混乱的分支命名空间。 但是这使操作变得笨拙。
    相比之下,您只需"git checkout ci-config"即可进行更改。

  • 我们可以假设ci/config/allow-refs.sample

    <code>#!/bin/sh
    #
    # Sample script for enabling/disabling GitHub Actions CI runs on
    # particular refs. By default, CI is run for all branches pushed to
    # GitHub. You can override this by dropping the ".sample" from the script,
    # editing it, committing, and pushing the result to the "ci-config" branch of
    # your repository:
    #
    #   git checkout -b ci-config
    #   cp allow-refs.sample allow-refs
    #   $EDITOR allow-refs
    #   git commit -am "implement my ci preferences"
    #   git push
    #
    # This script will then be run when any refs are pushed to that repository. It
    # gets the fully qualified refname as the first argument, and should exit with
    # success only for refs for which you want to run CI.
    
    case "$1" in
    # allow one-off tests by pushing to "for-ci" or "for-ci/mybranch"
    refs/heads/for-ci*) true ;;
    # always build your integration branch
    refs/heads/my-integration-branch) true ;;
    # don't build any other branches or tags
    *) false ;;
    esac
    </code>

    所有与.github/workflows相关的操作都需要:

    • 检出特殊分支和其中的特殊脚本:

    即:

    git -c protocol.version=2 clone \
      --no-tags \
      --single-branch \
      -b ci-config \
      --depth 1 \
      --no-checkout \
      --filter=blob:none \
      https://github.com/${{ github.repository }} config-repo \
    && \
    cd config-repo \
    && \
    git checkout HEAD -- ci/config
    
    • 检查推送的分支是否被授权:

    即:

    enabled=yes
    if test -x config-repo/ci/config/allow-ref &&
             ! config-repo/ci/config/allow-ref '${{ github.ref }}'
    then
      enabled=no
    fi
    

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