GitHub Actions工作流程优化利器
skip-duplicate-actions是一款专为GitHub Actions设计的优化工具。它可以智能跳过重复和并发工作流运行、忽略特定路径变更、取消过时运行,通过高效的回溯算法确保必要检查完成。该工具不仅节省时间和成本,还提供灵活配置,适应各类复杂工作流场景,是提升GitHub Actions效率的理想选择。
skip-duplicate-actions
提供以下功能来优化 GitHub Actions:
所有这些功能都有助于节省时间和成本,特别是对于长时间运行的工作流。 您可以选择使用其中的任意功能组合。
如果您使用功能分支,可能会看到许多重复的工作流运行。
例如,当在功能分支上执行工作流运行后,合并该功能分支时可能会再次重复执行工作流运行。
skip-duplicate-actions
可以防止这种情况发生。
跳过执行,因为完全相同的文件已在 <previous_run_URL> 中成功检查
的消息。skip-duplicate-actions
不关心您使用快进合并、变基合并还是压缩合并。
但是,如果合并产生的结果与源分支不同,那么结果工作流运行将不会被跳过。
这通常发生在合并"过时分支"的情况下。有时,即使触发了两次,您也不希望同时运行某些工作流。
因此,skip-duplicate-actions
提供以下选项,在同一工作流已经运行时跳过工作流运行:
push
和 pull_request
触发器时,或在推送提交后立即推送标签时,这可能很有用。
(已弃用,请使用 same_content_newer
代替)same_content_newer
确保至少有一个这样的工作流会运行,而 same_content
可能会跳过所有运行。在许多项目中,对于仅文档更改的情况,运行所有测试是不必要的。
因此,GitHub 本身提供了 paths-ignore 功能。
然而,GitHub 的 paths-ignore
有一些限制:
paths-ignore
无法查看先前的提交。这意味着结果取决于您推送更改的频率。paths-ignore
对于必需检查不起作用。
如果您对必需检查使用 path-ignore,那么拉取请求将永远无法合并。为了克服这些限制,skip-duplicate-actions
提供了一个更灵活的 paths_ignore
功能,使用高效的回溯算法。
paths_ignore
不会简单地查看当前提交,而是在您的提交历史中寻找成功的检查。
如果您需要在单个工作流中定义多个 paths_ignore
模式,可以使用 paths_filter
选项。
在某些项目中,只有在特定子目录发生变更时才应执行某些任务。
因此,GitHub 本身提供了 paths 功能。
然而,GitHub 的 paths
有一些限制:
paths
无法跳过工作流中的单个步骤。paths
不适用于您真正希望成功通过的必需检查。为了克服这些限制,skip-duplicate-actions
提供了一个更复杂的 paths
功能。
回溯算法不会盲目地跳过检查,而是只有在您的提交历史中找到合适的检查时才会跳过。
如果您需要在单个工作流中定义多个 paths
模式,可以使用 paths_filter
选项。
通常,工作流应该只针对最新的提交运行。
因此,当您向分支推送更改时,可以配置 skip-duplicate-actions
以取消针对过时提交运行的任何先前工作流运行。
已取消 <previous_run_URL>
的消息。paths_ignore
包含被忽略路径模式的 JSON 数组。 有关路径模式示例,请参阅备忘单。 有关支持的路径模式的详细信息,请参阅 micromatch。
示例: '["**/README.md", "**/docs/**"]'
默认值: '[]'
paths
包含路径模式的 JSON 数组。
如果非空,skip-duplicate-actions
将尝试跳过未更改这些路径的提交。
它使用与 paths_ignore
相同的语法。
示例: '["platform-specific/**"]'
默认值: '[]'
paths_filter
包含命名的 paths_ignore
/ paths
模式的 YAML 字符串。
示例:
frontend: paths_ignore: - 'frontend/docs/**' paths: - 'frontend/**' backend: paths: - 'backend/**' ### 在这里您可以选择控制/限制回溯 # 布尔值或数字(默认值:true) # 'false' 表示完全禁用回溯 # '5' 表示在回溯 5 个提交后停止 backtracking: 5
当您在一个工作流中有多个作业,并希望根据不同的 paths_ignore
/ paths
模式跳过它们时很有用。
请参阅相应的 paths_result
输出和示例配置。
cancel_others
如果为 true,则会取消来自过时提交的工作流运行。
默认值: 'false'
skip_after_successful_duplicate
如果为 true,在找到已完成的重复运行时跳过。
默认值: 'true'
do_not_skip
包含不应跳过的触发器的 JSON 数组。
可能的值有 pull_request
、push
、workflow_dispatch
、schedule
、release
、merge_group
。
默认值: '["workflow_dispatch", "schedule", "merge_group"]'
concurrent_skipping
如果同一工作流已在运行,则跳过工作流运行。
可选值:never
、same_content
、same_content_newer
、outdated_runs
、always
。
默认值: 'never'
should_skip
如果根据您配置的规则应跳过当前运行,则返回 'true'
。这应该用于评估单个步骤或整个作业。
reason
当前运行被认为可跳 过或不可跳过的原因。大致对应于输入选项。
示例: skip_after_successful_duplicate
skipped_by
返回导致当前运行被跳过的工作流运行的相关信息。
示例:
{ "id": 1709469369, "runNumber": 737, "event": "pull_request", "treeHash": "e3434bb7aeb3047d7df948f09419ac96cf03d73e", "commitHash": "4a0432e823468ecff81a978165cb35586544c795", "status": "completed", "conclusion": "success", "htmlUrl": "https://github.com/fkirc/skip-duplicate-actions/actions/runs/1709469369", "branch": "master", "repo": "fkirc/skip-duplicate-actions", "workflowId": 2640563, "createdAt": "2022-01-17T18:56:06Z" }
{}
)。paths_result
返回 paths_filter
中每个配置的过滤器的信息。
示例:
{ "frontend": { "should_skip": true, "backtrack_count": 1, "skipped_by": { // 工作流运行的相关信息 }, "backend": { "should_skip": false, "backtrack_count": 1, "matched_files": ["backend/file.txt"] }, "global": { "should_skip": false, "backtrack_count": 0 } }
global
键对应"全局" paths_ignore
和 paths
选项。matched_files
中返回匹配文件列表。skipped_by
返回值的行为与"全局" skipped_by
输出相同。backtrack_count
显示在找到适当的提交之前回溯(跳过)了多少个提交。skip-duplicate-actions
在执行路径检查之前终止(例如,当找到成功的重复运行时),则返回空对象({}
)。changed_files
一个二维数组,包含每个被追溯的提交的已更改文件列表。
示例: [["some/example/file.txt", "another/example/file.txt"], ["frontend/file.txt"]]
changed_files[0]
获取最新提交的已更改文件。也可以使用 paths_result
中的 backtrack_count
输出来处理已更改文件的列表。paths_ignore
、paths
或 paths_filter
选项之一时才返回信息。skip-duplicate-actions
在执行路径检查之前终止(例如,当找到成功的重复运行时),则返回空数组([]
)。你可以使用 skip-duplicate-actions
来跳过单个步骤或整个作业。
为了最小化对现有作业的更改,通常更容易跳过整个作业。
注意
要跳过整个作业,你应该添加一个 pre_job
作为 main_job
的前置条件。
虽然这个示例看起来代码很多,但在你的特定项目的 main_job
中只有两行额外的代码(needs
子句和 if
子句):
jobs: pre_job: # continue-on-error: true # 完成集成后取消注释 runs-on: ubuntu-latest # 将步骤输出映射到作业输出 outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} steps: - id: skip_check uses: fkirc/skip-duplicate-actions@v5 with: # 所有这些选项都是可选的,如果你对默认值满意,可以删除它们 concurrent_skipping: 'never' skip_after_successful_duplicate: 'true' paths_ignore: '["**/README.md", "**/docs/**"]' do_not_skip: '["pull_request", "workflow_dispatch", "schedule"]' main_job: needs: pre_job if: needs.pre_job.outputs.should_skip != 'true' runs-on: ubuntu-latest steps: - run: echo "运行耗时测试..." && sleep 30
以下示例演示了如何使用 if
子句和 id
跳过单个步骤。
在这个 示例中,如果 src/
或 dist/
中没有文件被更改,则该步骤将被跳过:
jobs: skip_individual_steps_job: runs-on: ubuntu-latest steps: - id: skip_check uses: fkirc/skip-duplicate-actions@v5 with: cancel_others: 'false' paths: '["src/**", "dist/**"]' - if: steps.skip_check.outputs.should_skip != 'true' run: | echo "仅在 src/ 或 dist/ 发生更改时运行..." && sleep 30 echo "执行其他操作..."
paths_filter
跳过[!警告]
如果 paths_filter 选项无法正常工作,你可以根据需要多次复制"示例 1"(详见 https://github.com/fkirc/skip-duplicate-actions/issues/326)。
如果工作流中有多个作业,并且想根据不同的 paths_ignore
/ paths
模式跳过它们,可以使用 paths_filter
选项。定义这些过滤器时,操作会在 paths_result
输出中返回相应的信息。
例如,在一个单体仓库中,你可能希望仅在相应的 "frontend/" 文件夹中的某些文件发生更改时运行与"前端"相关的作业,对"后端"也是如此。可以通过以下配置实现:
jobs: pre_job: runs-on: ubuntu-latest outputs: should_skip: ${{ steps.skip_check.outputs.should_skip }} paths_result: ${{ steps.skip_check.outputs.paths_result }} steps: - id: skip_check uses: fkirc/skip-duplicate-actions@v5 with: paths_filter: | frontend: paths_ignore: - 'frontend/docs/**' paths: - 'frontend/**' backend: paths: - 'backend/**' # 可以与"全局" 'paths_ignore' / 'paths' 选项混合使用,例如: # paths_ignore: '["**/README.md"]'
前端: 需要:pre_job # 如果'skip-duplicate-actions'在执行路径检查之前终止(例如,找到成功的重复运行时),'paths_result'会输出一个空对象('{}')。 # 可以在作业的if条件中通过首先检查"全局"'should_skip'输出的结果来轻松拦截这种情况。 如果:needs.pre_job.outputs.should_skip != 'true' && !fromJSON(needs.pre_job.outputs.paths_result).frontend.should_skip # ...
后端: # ...
## 它是如何工作的?
`skip-duplicate-actions`使用[工作流运行API](https://docs.github.com/en/rest/reference/actions#workflow-runs)来查询工作流运行。
`skip-duplicate-actions`只会查看属于当前工作流运行的同一工作流的工作流运行。
查询这些工作流运行后,它会将它们与当前工作流运行进行如下比较:
- 如果存在具有相同树哈希的工作流运行,那么我们就找到了一个重复的工作流运行。
- 如果存在正在进行的工作流运行,那么我们可以根据您的配置取消或跳过它。
## 路径跳过是如何工作的?
如上所述,`skip-duplicate-actions`提供了一个路径跳过功能,这与GitHub原生的`paths`和`paths_ignore`功能有些相似。
然而,路径跳过并不完全简单,因为存在多种执行路径跳过的选项:
### 选项1:只查看"当前"提交
这是GitHub目前正在做的事情,我们认为它是不够的,因为它对"必需"检查不起作用。
另一个问题是,结果可能高度依赖于提交的推送顺序。
### 选项2:查看拉取请求差异
PR差异易于理解,但它们只在打开PR后才起作用,而不是在推送功能分支后立即起作用。
### 选项3:查找先前提交的成功检查
这个选项由`skip-duplicate-actions`实现。
一个优点是,无论您是使用PR还是原始功能分支,它都能工作,当然它也适用于"必需"检查。
在内部,`skip-duplicate-actions`使用[Repos Commit API](https://docs.github.com/en/rest/reference/repos#get-a-commit)来执行高效的回溯算法进行路径跳过检测。
这是该算法大致的工作方式:
```mermaid
stateDiagram-v2
检查提交: 检查提交
[*] --> 检查提交: 当前提交
state 路径被忽略 <<choice>>
检查提交 --> 路径被忽略: 所有更改的文件是否都匹配"paths_ignore"?
忽略_是: 是
忽略_否: 否
路径被忽略 --> 忽略_是
路径被忽略 --> 忽略_否
state 路径被跳过 <<choice>>
忽略_否 --> 路径被跳过: 是否没有更改的文件匹配"paths"?
跳过_是: 是
跳过_否: 否
路径被跳过 --> 跳过_是: 无匹配
路径被跳过 --> 跳过_否: 有匹配
父提交: 获取父提交
忽略_是 --> 父提交
跳过_是 --> 父提交
state 成功运行 <<choice>>
父提交 --> 成功运行: 是否有此提交的成功运行?
运行_是: 是
运行_否: 否
成功运行 --> 运行_是
成功运行 --> 运行_否
运行_否 --> 检查提交: 父提交
跳过: 跳过!
运行_是 --> 跳过: (因为自此运行以来的所有更改都在被忽略或跳过的路径中)
不跳过: 不跳过!
跳过_否 --> 不跳过: (因为更改的文件需要"测试")
在https://github.com/fkirc/skip-duplicate-actions/issues/44中讨论。
如果您有注册为必需状态检查的矩阵作业,并且矩阵根据跳过检查条件运行,您可能会遇到拉取请求永远处于无法合并状态的问题,因为作业根本没有执行,因此没有报告为已跳过(Expected - Waiting for status to be reported
)。
有几种方法可以解决这个问题:
在矩阵作业的每个步骤中定义条件(if
),而不是在作业级别定义单一条件:https://github.com/fkirc/skip-duplicate-actions/issues/44
如果您希望只有在矩阵中的所有作业都成功时才将检查视为成功,可以添加一个后续作业,其唯一任务是报告矩阵的最终状态。然后,您可以将此最终作业注册为必需状态检查:
result: name: 结果 if: needs.pre_job.outputs.should_skip != 'true' && always() runs-on: ubuntu-latest needs: - pre_job - example-matrix-job steps: - name: 标记结果为失败 if: needs.example-matrix-job.result != 'success' run: exit 1
定义一个相反的工作流,如GitHub官方建议:处理跳过但必需的检查
AI辅助编程,代码自动修复
Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。
AI小说写作助手,一站式润色、改写、扩写
蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。
全能AI智能助手,随时解答生活与工作的多样问题
问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。
实时语音翻译/同声传译工具
Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。
一键生成PPT和Word,让学习生活更轻松
讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。
深度推理能力全新升级,全面对标OpenAI o1
科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。
一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型
Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。
AI助力,做PPT更简单!
咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。
选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。
专业的AI公文写作平台,公文写作神器
AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。
最新AI工具、AI资讯
独家AI资源、AI项目落地
微信扫一扫关注公众号