菜单

步骤系统

相关源文件

目的与范围

act 中的步骤系统负责执行 GitHub Actions 配置中定义的各个工作流步骤。本页面涵盖了步骤模型、执行生命周期、环境处理以及 act 支持的不同步骤类型。有关不同操作类型(Docker、JavaScript、复合)的具体处理信息,请参阅操作

步骤模型和类型

在 GitHub Actions 中,步骤是作业中的基本工作单元。act 代码库使用 Step 结构体表示步骤

来源:pkg/model/workflow.go568-595

步骤属性

字段描述
ID步骤的唯一标识符
姓名用于显示的人类可读名称
Uses操作引用(例如,actions/checkout@v2
Run要执行的命令(针对运行步骤)
Shell用于运行命令的 Shell
WorkingDirectory运行步骤的目录
Env步骤特定的环境变量
With操作的输入参数
RawContinueOnError步骤失败时是否继续
TimeoutMinutes最大执行时间

来源:pkg/model/workflow.go568-583

步骤类型

步骤根据其配置被分为不同类型

类型由 Type() 方法确定,该方法检查 UsesRun 字段

  • StepTypeRun:具有 run 属性但没有 uses
  • StepTypeUsesDockerURL:直接使用 Docker 镜像,通过 uses: docker://...
  • StepTypeUsesActionLocal:通过 uses: ./path 引用本地操作
  • StepTypeUsesActionRemote:通过 uses: owner/repo@ref 引用 GitHub 操作
  • StepTypeReusableWorkflowLocal:引用本地工作流
  • StepTypeReusableWorkflowRemote:引用远程工作流

来源:pkg/model/workflow.go644-711

步骤执行接口

步骤执行通过 step 接口管理,该接口定义了所有步骤实现必须提供的核心方法

该接口定义了三个执行阶段

  • pre():主执行前的准备工作
  • main():主要步骤执行
  • post():主执行后的清理工作

来源:pkg/runner/step.go18-28

步骤执行生命周期

步骤在执行过程中会经历不同的阶段,由 runStepExecutor 函数管理

来源:pkg/runner/step.go65-200

关键阶段详情

  1. 评估 If 条件:

    • 评估步骤的 if 表达式以确定步骤是否应该运行
    • 如果为 false,则跳过该步骤并标记为 skipped 状态
  2. 设置环境:

    • 环境变量从多个来源合并
    • 变量通过表达式评估进行插值
  3. 命令文件准备:

    • 为 GitHub Actions 文件命令创建文件
      • GITHUB_OUTPUT:用于捕获步骤输出
      • GITHUB_STATE:用于保存状态
      • GITHUB_PATH:用于修改 PATH
      • GITHUB_ENV:用于设置环境变量
      • GITHUB_STEP_SUMMARY:用于步骤摘要信息
  4. 执行步骤:

    • 带超时监控地运行步骤实现
  5. 处理结果:

    • 成功:将步骤标记为成功
    • 失败:检查 continue-on-error 设置
    • 处理命令文件以更新环境、状态、输出和路径

来源:pkg/runner/step.go114-128 pkg/runner/step.go178-194

环境和上下文设置

在执行之前,步骤需要进行适当的环境设置。这由 setupEnv 函数处理

环境层级确保变量被正确覆盖

  1. 来自运行上下文的基本环境
  2. 作业级别的环境变量
  3. 容器环境变量(如果适用)
  4. GitHub 上下文环境变量
  5. 步骤特定的环境变量

此外,对于操作步骤,INPUT_* 环境变量是根据 with 映射创建的,遵循 GitHub 的约定。

来源:pkg/runner/step.go230-255 pkg/runner/step.go257-280

运行步骤执行

运行步骤(使用 run 属性的步骤)通过以下过程执行

  1. Shell 选择:

    • 首先尝试步骤级别的 Shell
    • 回退到作业默认值
    • 回退到工作流默认值
    • 如果仍未定义,则根据环境选择(Linux 为 bash/sh,Windows 为 pwsh/powershell)
  2. 工作目录:

    • 同样遵循一个层级:步骤 → 作业 → 工作流
  3. 脚本创建:

    • 在脚本中插值表达式
    • 创建具有适当 Shell 语法的正确脚本文件
    • 包含必要的错误处理(例如,PowerShell 的 $ErrorActionPreference = 'stop'
  4. 执行:

    • 将脚本复制到执行环境
    • 使用适当的 Shell 命令执行

来源:pkg/runner/step_run.go32-44 pkg/runner/step_run.go101-146 pkg/runner/step_run.go164-204

条件执行

步骤可以根据先前步骤的状态有条件地执行

If 条件

if 表达式可以通过以下方式引用上一步的状态

  • success():如果所有先前的步骤成功或被跳过,则为 True
  • failure():如果任何先前的步骤失败,则为 True
  • always():始终为 True,无论先前的步骤状态如何

失败时继续

如果步骤失败但 continue-on-error 为 true

  • 该步骤的结果被标记为 failure
  • 但结论被标记为 success
  • 这允许作业继续执行

来源:pkg/runner/step.go282-298 pkg/runner/step.go300-314

步骤状态跟踪

步骤维护结果(outcome)和结论(conclusion),它们存储在 StepResult 结构中

  • 结果(Outcome):步骤执行的实际结果(成功、失败、跳过)
  • 结论(Conclusion):用于确定作业是否继续的状态(可以被 continue-on-error 覆盖)
  • 输出(Outputs):步骤产生的输出映射

这些结果存储在 RunContext 的 StepResults 映射中,以步骤 ID 为键。

来源:pkg/runner/step.go74-78 pkg/runner/step.go157-176

命令文件处理

步骤执行后,处理准备阶段创建的命令文件

每个文件都遵循 GitHub 的特定格式,并经过处理以更新执行上下文

  • GITHUB_ENV:更新后续步骤的环境变量
  • GITHUB_STATE:存储当前作业的状态
  • GITHUB_OUTPUT:设置可供其他步骤通过 steps.<step-id>.outputs.<name> 引用的输出
  • GITHUB_PATH:将目录添加到 PATH 环境变量

来源:pkg/runner/step.go53-63 pkg/runner/step.go178-194

结论

act 中的步骤系统是一个核心组件,负责处理 GitHub Actions 工作流步骤的执行生命周期。它提供了一个灵活的架构,支持不同类型的步骤,同时保持与 GitHub 执行模型的兼容性。通过仔细的环境设置、条件执行和输出处理,它使得 GitHub Actions 支持的复杂工作流能够在本地执行。

来源:pkg/model/workflow.go568-643 pkg/runner/step.go18-28