CHAPTER 2 : How Does Actions Work❓
在第一章中,您高度了解了GitHub操作的整体框架和价值。
在本章中,我们将深入研究组成GitHub操作的部分,以及它们如何一起工作,意味着什么启动它们,当它们运行时发生什么,等等。
提醒一下,在GitHub操作的世界中,操作可以参考以下内容:
• 为响应事件而执行自动工作流的整个系统。
• 实现单个操作的代码和相关部分的实际单元。
根据GitHub建议的惯例,本书将使用GitHub Actions或 Actions(大写“a”)来引用 system 和 actions(小写“a”)来引用代码单元。
为了更好地理解操作环境,我将向您提供整体流流程如何工作的概述。这包括可以启动自动生成的事件类型,以及在自动化执行过程中所涉及的组件的高级概述。在本章中,我将提供一些简单的示例代码。这将让您深入地了解流程是如何工作的。
An Overview
在高级级别中,GitHub操作流如下:
1.某些触发事件发生在GitHub存储库中。此事件通常与一个唯一的SHA1(安全哈希算法1)值和一个解析为SHA1值(a ref)的Git引用关联,例如一个分支。但它也可能是GitHub中的一个事件,而不是对引用的更新。一个例子是提取请求或正在更新的问题。
2.在存储库中搜索一个专门的目录(.github/工作流),以查找被编码为响应事件类型的工作流文件。许多事件还可以包括额外的限定符。例如,只有当在名为main的分支上发生推送操作时,才能设置为触发工作流。
3.识别相应的工作流,并触发匹配的工作流的新运行。
工作流对象是这里的关键部分。GitHub操作工作流是一组代码,它定义了要执行的序列和一组步骤,类似于脚本或程序。该文件本身必须以YAML格式进行编码,并存储在
工作流文件具有特定的语法。一个工作流包含一个或多个jobs
。每项工作都可以很简单,也可以根据需要也很复杂。一旦一个工作流被启动,这些作业就会开始执行。默认情况下,它们会并行运行。
反过来,工作也是由各种步骤组成的。步骤可以运行shell命令或调用预定义的GitHub操作。
作业中的所有步骤都将在运行器上执行。
runner是一个服务器(虚拟的或物理的)或容器,用来了解如何与GitHub操作交互。
稍后我将详细介绍这些项目,但图2-1说明了基本设计。
如果这看起来很熟悉,那可能是因为它是一个CI模式。
一些更改会被自动检测到,并触发一组自动化流程来运行和响应该更改。
在GitHub操作中,表明需要启动工作的更改是触发事件(又名触发器)。
Triggering Workflows
事件触发工作流。
如果存在GitHub操作工作流,并且触发事件与工作流中指定的开始条件相匹配,那么它们将作为工作开始发生的信号。
我们可以用以下几种不同的方式来定义一个事件:
• 一个人或一个进程在GitHub存储库中执行一些操作。
• 会发生匹配的外部触发器,即来自GitHub外部的事件。
• 计划设置为在特定时间或间隔运行工作流。
• 工作流是手动启动的,无需先执行操作。
我将在第3章和第8章中更深入地介绍这些不同的类型,但是从GitHub存储库中的操作中触发的事件可能是最常见的类型。
这类事件的一个例子是GitHub的拉出请求。
如果您或一个进程启动了一个拉请求,则会触发一个相应的拉请求事件。
还有一个针对代码推送的推送事件。
在GitHub中,您可以执行大量的公共操作,它们可以作为工作流的触发器。
还有多种方法来管理工作流何时对触发器作出反应。
要理解这一点,这里是第一个需要熟悉的工作流语法——on子句。
on关键字和后面的行定义了工作流将匹配并开始执行的类型的测试。
一些基本的触发器类型和每个语法的简单示例:
工作流可以响应单个事件,例如当推送发生时:
on: push
工作流可以响应一个列表(多个事件):
on: [push, pull_request]
工作流可以使用限定符响应事件类型,如分支、标记或文件路径:
on:push:branches:- main - 'rel/v*'tags:- v1.*- beta paths:- '**.ts'
工作流可以按特定的计划或时间间隔执行(使用标准cron语法):
on:scheduled:- cron: '30 5,15 * * *'
❗@interval Syntax
不支持诸如 @daily, @hourly 等这样的语法。
工作流可以响应特定的手动事件(稍后将详细介绍这些事件):
on: [workflow-dispatch, repository-dispatch]
可以从其他工作流中调用该工作流(称为重用事件):
on: workflow_call
工作流可以响应webhook events
-- 也就是说,当web钩子执行并发送有效负载时。
(有关网络挂钩中的事件和付费负荷的更多详细信息,请参阅相关文档。)
工作流可以响应GitHub项目上的常见活动,例如向GitHub问题添加注释:
on: issue_comment
❗仅在工作流文件存在于默认分支上时触发的事件
请注意,只有当工作流文件(.github/workflows中的YAML文件)位于默认分支(通常是main分支)时,不常见事件的子集才会触发工作流运行。
对于这些事件,如果您只在一个非默认分支上有工作流文件,并且您触发了通常会导致工作流运行的活动,则什么也不会发生。
您可以从另一个分支触发该事件。
但是,对于这些特殊情况,工作流文件必须存在于默认分支上,而不管触发器实际发生在哪个分支上。
当您试图在不同的分支中开发工作流并在执行拉请求之前证明它时,这可能会出现棘手的情况。要查看一个事件是否只能为存储库中的默认分支触发,请访问文档并检查说明部分,“只有当工作流文件在默认分支上时,此事件才会触发工作流运行。”
决定如何触发您的工作流程是使用GitHub操作实现功能的第一步。
要完成这个图片,您需要了解更多关于组成工作流的其他部分。
我在第一章中简要地提到了这些内容,但我将在下一节中解释更多关于它们的内容。
Components
我在这里使用组件作为一个综合术语(不是正式术语),表示GitHub操作定义的用于构建和执行工作流的主要部分。
为了简单起见,我将对每一个都做一个简短的调查,以帮助您从更高的层次上理解它们。
步骤是您在使用GitHub操作时所处理的基本执行单元。
它们包括对预定义操作的调用或要在运行器上运行的shell
命令。
任何shell
命令都可以通过run
子句来执行。
任何预定义的动作都可以通过uses
子句来引入。
步骤关键字表示要按顺序运行的一系列步骤的开始。
下面的代码列表显示了一个工作流中的三个基本步骤的示例。
这些步骤会检查出一组代码,根据特定的版本建立一个go环境,并在源文件上运行go进程。
在YAML语法中,-
字符表示步骤的开始位置。
uses
子句表示此步骤调用一个预先定义的操作。
with
子句用于指定要传递给操作的参数/参数。
而run
子句表示要在shell中运行的命令。
请注意,步骤也可以有一个与它们关联的name:
steps:
-
uses: actions/checkout@v3
-
name: setup Go version
uses: actions/setup-go@v2
with:
go-version: '1.14.0' -
run: go run helloworld.go
运行器是用来执行工作流代码的物理或虚拟计算机或容器。
它们可以是由GitHub提供和托管的系统(并在它们的控制范围内运行),也可以是您设置、托管主机和控制的实例。
在任何一种情况下,系统都被配置为理解如何与GitHub操作框架交互。
这意味着它们可以与GitHub交互,以访问工作流和预定义的操作、执行步骤和报告结果。
在工作流文件中,仅通过运行子句为作业定义运行器。(跑步者在第五章中有更详细的讨论。)
runs-on: ubuntu-latest
作业将聚合步骤,并定义要在哪个运行器上执行它们。
单个工作的目标通常是实现整体工作流程中的一个特定目标。
例如,可以是实现CI/CD管道的工作流,用于构建CI/CD管道的作业、测试和打包。
除了运行器的定义之外,工作流中的作业就像编程语言中的函数或程序。
它由一系列要运行的单独命令和/或要调用的预定义操作组成。
这类似于编程语言中的函数或过程是由单独的代码行和/或对其他函数或过程的调用组成的。
作业的结果显示在GitHub操作界面中。成功或失败将显示在作业的级别,而不是各个步骤。
在决定你想要任何个人工作做多少工作时,保持这种成功/失败的状态是有帮助的。
当考虑您想要知道多少关于工作流执行中的成功或失败的细节时,这也很有帮助。
如果您需要在顶层显示更详细的成功或失败报告,您可能希望在作业中放置更少的步骤。
或者,如果您需要详细说明一组步骤的成功还是失败,您可以在作业中添加更多的步骤。
基于前面显示的步骤和运行者,下一个列表显示了一个简单的作业,它执行检查和设置并执行构建:
jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v3- name: setup Go version'uses: actions/setup-go@v2with:go-version: '1.14.0'- run: go run helloworld.go
一个工作流就像一个管道。
在较高的级别上,它首先定义了它将响应的输入(事件)的类型,以及在什么条件下它将对它们作出响应。
这是我们在前面的事件部分中讨论到的。
如果事件和条件匹配,则响应是执行工作流中执行一系列作业,然后依次执行每个作业的步骤。
整个流程就像一个连续的集成过程,因为它会对一种特定的变化做出响应,并启动一个自动化的工作序列。
下一个列表显示了一个简单的用于处理Go程序的工作流的示例:
请注意,此工作流是用YAML格式编写的。
我将逐行分解这个文件中正在发生的事情,例如:
第1行:工作流文件被分配了一个名称。
第3行:这是在关于事件的部分中讨论的on标识符。
第4-6行:当对此GitHub存储库中的分支主节点执行推送操作时,就会触发此工作流。
第8行:这将启动工作流的作业部分。
第9行:此工作流中有一个作业,名为build。
第10行:此作业将在一个由GitHub托管的运行器系统上执行,并提供了一个标准的ubuntu操作系统映像。
第11行:这将启动此作业的一系列步骤。
第12行:第一步是通过拉入一个预定义的动作来完成的。注意引用的方式。actions/checkout@v3
指的是github.com之后的相对路径,所以这实际上意味着它将run/use
在github.com/actions/checkout
上定义的操作。还要注意,这是此步骤中唯一的一行--不需要将参数传递给此操作,因为它假定它正在从此存储库中签出源代码,因为它在此存储库中。
第13行:这一行开头的连字符表示这是第二步的开始。这一行给这个新的步骤起了一个名称。
第14行:同样的步骤是另一个预定义的操作来设置围棋环境。
第15-16行:设置执行操作需要一个参数-要使用的Go版本。该参数通过a with子句作为输入传递给该操作。
第17行:这是另一个步骤,简单地运行run关键字指示的命令。该命令是对存储库中的一个示例文件执行go run
命令。
提醒一下,为了找到、匹配事件条件并自动执行,这段代码需要存储在gitthub存储库中的YAML文件中:.github/workflows
。
【eg
】,您可以将前面的代码保存在
如果您将.github/workflows/simple-go-build.yml文件和相应的地狱世界。
将文件推送到GitHub存储库,您可以看到工作流会立即运行。
这是因为工作流中(push到main)设置的事件条件将匹配。
因此,工作流一旦被推送,就会被触发和执行。
从这里,您可以选择一个工作流的运行,并查看作为工作流的一部分运行的作业及其状态。
图2-3显示了从我们的sim- ple工作流中执行作业的执行情况。
在后面的章节中,您将看到如何使用此接口来深入了解在执行各种步骤时发生的情况,以及如何在操作运行时使用该接口调试问题。
Conclusion
操作可以引用实现操作的代码、将定义和运行这些操作作为工作流的一部分的自动环境,或者两者都可以引用。
在本章中,我将重点了解工作流、它的组件以及它的执行方式。
工作流就像软件管道一样。
可以在触发事件发生时(如连续集成)来启动它们,并聚合一个或多个作业以完成其整体任务。
每个工作反过来聚合一个或多个步骤来完成更小的工作单位。
在单个作业中执行这些步骤会导致作业的成功/失败结果,该结果会反馈为整个工作流的成功/失败。
现在您已经对GitHub操作中的工作流如何工作有了基本的了解,第3章将让您对单个操作如何工作有了类似的理解。