使用环境变量自定义工作流

已完成

在本单元中,你将了解如何在 GitHub Actions 工作流中使用变量、上下文和自定义脚本配置和管理特定于环境的行为。

若要实现此过程,你将了解如何:

  • 使用默认和自定义环境变量。
  • 访问工作流中的上下文信息。
  • 在不同的工作流范围内设置环境变量。
  • 将自定义脚本与 run 关键字一起使用。
  • 为部署应用环境保护。

默认环境变量和上下文

在 GitHub Actions 工作流中,可以使用多个默认环境变量,但只能在执行作业的运行程序内使用。 这些默认变量区分大小写,并且指的是系统和当前用户的配置值。 建议使用这些默认环境变量(而非使用硬编码文件路径)来引用文件系统。 要使用默认环境变量,请指定 $,后跟环境变量的名称。

jobs:
  prod-check:
    steps:
      - run: echo "Deploying to production server on branch $GITHUB_REF"

除默认环境变量外,还可以使用已定义的变量作为上下文。 上下文与默认变量的相似之处在于它们均可提供环境信息的访问权限,但两者之间仍然存在一些重要差异。 尽管默认环境变量只能在运行程序内使用,但可以在工作流中的任何时间点使用上下文变量。 例如,借助上下文变量,可以运行 if 语句,以在执行运行器之前评估表达式。

name: CI
on: push
jobs:
  prod-check:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying to production server on branch $GITHUB_REF"

此示例使用 github.ref 上下文来检查触发工作流的分支。 如果分支是 main,则执行运行程序并打印“部署到分支$GITHUB_REF 上的生产服务器”。运行程序中使用默认环境变量 $GITHUB_REF 来引用分支。 请注意,默认环境变量全部采用大写形式,而上下文变量则全部采用小写形式。

工作流中可用的上下文信息

使用上下文访问有关工作流运行、变量、运行程序环境、作业和步骤的信息。 每个上下文都是一个对象,其中包含可以是其他对象或字符串的属性。 可用的上下文包括githubenvvarsjobjobsstepsrunnersecretsstrategymatrixneedsinputs

下表列出了工作流上下文和说明:

上下文 DESCRIPTION
github 有关工作流运行的信息。 有关详细信息,请参阅 github 上下文
env 包含你在工作流、作业或步骤中设置的变量。 有关详细信息,请参阅 env 上下文
vars 包含你在存储库、组织或环境级别设置的变量。 有关详细信息,请参阅 vars 上下文
job 有关当前运行的作业的信息。 有关详细信息,请参阅 job 上下文
jobs 仅对于可重用工作流,包含可重用工作流中作业的输出。 有关详细信息,请参阅 jobs 上下文
steps 有关当前作业中运行的步骤的信息。 有关详细信息,请参阅 steps 上下文
runner 有关运行当前作业的运行器的信息。 有关详细信息,请参阅 runner 上下文
secrets 包含可用于工作流运行的机密的名称和值。 有关详细信息,请参阅 secrets 上下文
strategy 有关当前作业的矩阵执行策略的信息。 有关详细信息,请参阅 strategy 上下文
matrix 包含适用于当前作业的工作流中定义的矩阵属性。 有关详细信息,请参阅 matrix 上下文
needs 包含定义为当前作业依赖项的所有作业的输出。 有关详细信息,请参阅 needs 上下文
inputs 包含可重用或手动触发的工作流的输入。 有关详细信息,请参阅 inputs 上下文

不同的上下文在工作流运行中会在不同时间可用。 例如,只能在作业中的特定位置使用 secrets 上下文。 此外,可以使用某些函数(如 hashFiles 函数)仅在特定位置使用。

下表列出了工作流中每个上下文和特殊函数的限制。 列出的上下文仅适用于指示的工作流键。 无法在任何其他位置使用它们。 可以在任意位置使用函数,除非它在下表中列出。

工作流密钥 上下文 特殊函数
run-name githubinputsvars 没有
concurrency githubinputsvars 没有
env githubsecretsinputsvars 没有
jobs.<job_id>.concurrency githubneedsstrategymatrixinputsvars 没有
jobs.<job_id>.container githubneedsstrategymatrixvarsinputs 没有
jobs.<job_id>.container.credentials githubneedsstrategymatrixenvvarssecretsinputs 没有
jobs.<job_id>.container.env.<env_id> githubneedsstrategymatrixjobrunnerenvvarssecretsinputs 没有
jobs.<job_id>.container.image githubneedsstrategymatrixvarsinputs 没有
jobs.<job_id>.continue-on-error githubneedsstrategyvarsmatrixinputs 没有
jobs.<job_id>.defaults.run githubneedsstrategymatrixenvvarsinputs 没有
jobs.<job_id>.env githubneedsstrategymatrixvarssecretsinputs 没有
jobs.<job_id>.environment githubneedsstrategymatrixvarsinputs 没有
jobs.<job_id>.environment.url githubneedsstrategymatrixjobrunnerenvvarsstepsinputs 没有
jobs.<job_id>.if githubneedsvarsinputs alwayscanceledsuccessfailure
jobs.<job_id>.name githubneedsstrategymatrixvarsinputs 没有
jobs.<job_id>.outputs.<output_id> githubneedsstrategymatrixjobrunnerenvvarssecretsstepsinputs 没有
jobs.<job_id>.runs-on githubneedsstrategymatrixvarsinputs 没有
jobs.<job_id>.secrets.<secrets_id> githubneedsstrategymatrixsecretsinputsvars 没有
jobs.<job_id>.services githubneedsstrategymatrixvarsinputs 没有
jobs.<job_id>.services.<service_id>.credentials githubneedsstrategymatrixenvvarssecretsinputs 没有
jobs.<job_id>.services.<service_id>.env.<env_id> githubneedsstrategymatrixjobrunnerenvvarssecretsinputs 没有
jobs.<job_id>.steps.continue-on-error githubneedsstrategymatrixjobrunnerenvvarssecretsstepsinputs hashFiles
jobs.<job_id>.steps.env githubneedsstrategymatrixjobrunnerenvvarssecretsstepsinputs hashFiles
jobs.<job_id>.steps.if githubneedsstrategymatrixjobrunnerenvvarsstepsinputs alwayscanceledsuccessfailurehashFiles
jobs.<job_id>.steps.name githubneedsstrategymatrixjobrunnerenvvarssecretsstepsinputs hashFiles
jobs.<job_id>.steps.run githubneedsstrategymatrixjobrunnerenvvarssecretsstepsinputs hashFiles
jobs.<job_id>.steps.timeout-minutes githubneedsstrategymatrixjobrunnerenvvarssecretsstepsinputs hashFiles
jobs.<job_id>.steps.with githubneedsstrategymatrixjobrunner、env、varssecretsstepsinputs hashFiles
jobs.<job_id>.steps.working-directory githubneedsstrategymatrixjobrunner、env、varssecretsstepsinputs hashFiles
jobs.<job_id>.strategy github、需求、varsinputs 没有
jobs.<job_id>.timeout-minutes githubneedsstrategymatrixvarsinputs 没有
jobs.<job_id>.with.<with_id> githubneedsstrategymatrixinputsvars 没有
on.workflow_call.inputs.<inputs_id>.default githubinputsvars 没有
on.workflow_call.outputs.<output_id>.value github作业,varsinputs 没有

自定义环境变量

与使用默认环境变量类似,可以在工作流文件中使用自定义环境变量。 若要创建自定义变量,需要使用 env 上下文在工作流文件中对其进行定义。 如果要在运行器内使用环境变量的值,则可以使用运行器操作系统的常规方法来读取环境变量。

name: CI
on: push
jobs:
  prod-check:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Nice work, $First_Name. Deploying to production server on branch $GITHUB_REF"
        env:
          First_Name: Mona

在工作流中设置自定义环境变量

可以在工作流文件的顶层使用 env 来定义适用于整个工作流的环境变量。 使用 jobs.<job_id>.env 限定工作流中作业的内容。 可以使用 jobs.<job_id>.steps[*].env 在作业的特定步骤中限定环境变量的范围。

下面是一个示例,其中显示了工作流文件中的所有三种方案:

name: Greeting on variable day

on:
  workflow_dispatch

env:
  DAY_OF_WEEK: Monday

jobs:
  greeting_job:
    runs-on: ubuntu-latest
    env:
      Greeting: Hello
    steps:
      - name: "Say Hello Mona it's Monday"
        run: echo "$Greeting $First_Name. Today is $DAY_OF_WEEK!"
        env:
          First_Name: Mona

在工作流中使用默认上下文

GitHub 平台设置默认环境变量。 它们未在工作流中定义,但你可以在相应上下文的工作流中使用默认环境变量。 除了CI,大多数变量都以GITHUB_*RUNNER_*开头。 无法覆盖后两种类型。 此外,这些默认变量具有一个相应的且类似命名的上下文属性。 例如,一 RUNNER_* 系列默认变量具有匹配的 runner.*上下文属性。

下面是通过应用以下方法访问工作流中的默认变量的示例:

on: workflow_dispatch

jobs:
  if-Windows-else:
    runs-on: macos-latest
    steps:
      - name: condition 1
        if: runner.os == 'Windows'
        run: echo "The operating system on the runner is $env:RUNNER_OS."
      - name: condition 2
        if: runner.os != 'Windows'
        run: echo "The operating system on the runner is not Windows, it's $RUNNER_OS."

有关详细信息,请参阅默认环境变量

将自定义环境变量传递到工作流

可以将自定义环境变量从工作流作业的一个步骤传递到作业中的后续步骤。 在作业的一个步骤中生成值,并将该值分配给现有或新的环境变量。 接下来,将变量/值对写入GITHUB_ENV环境文件。 可以在操作或者工作流作业的 shell 命令中使用run关键字来使用环境文件。

创建或更新环境变量的步骤无权访问新值,但作业中的所有后续步骤都具有访问权限。

下面是一个示例:

steps:
  - name: Set the value
    id: step_one
    run: |
      echo "action_state=yellow" >> "$GITHUB_ENV"
  - name: Use the value
    id: step_two
    run: |
      printf '%s\n' "$action_state" # This will output 'yellow'

增加环境保护措施

可以为为 GitHub 存储库定义的环境添加保护规则。

若要添加环境,请在存储库中:

  1. 选择“设置”。

    包含代码、问题和 Wiki 等选项卡的 Web 界面的菜单栏;突出显示了“设置”。

  2. 在左窗格中,选择“ 环境”。

    “常规”菜单的屏幕截图,其中包含“访问”、“代码”和“自动化”、“安全性”和“集成”部分。突出显示了“环境”选项。

  3. 选择“ 新建环境 ”按钮以添加和配置环境并添加保护。

    GitHub 存储库设置页的屏幕截图,其中显示了“环境”部分,其中显示一条消息,指示不存在环境,并突出显示了“新建环境”按钮。

关于环境

使用环境描述常规部署目标,例如生产、过渡或开发。 当 GitHub Actions 工作流部署到环境时,环境会显示在存储库的主页上。 可以使用环境来要求批准作业才能继续、限制哪些分支可以触发工作流、使用自定义部署保护规则对部署进行限制,或限制对机密的访问。

工作流中的每个作业都可以引用一个环境。 为环境设置的任何保护规则都必须在将引用环境的作业发送到运行器之前传递。 只有将作业发送到运行器后,该作业才能访问环境的机密。

当工作流引用环境时,环境将显示在存储库的部署中。

环境保护规则

环境部署保护规则要求在引用环境的作业继续之前满足特定条件。 可以使用部署保护规则来要求手动批准、延迟作业或将环境限制为特定分支。 还可以创建和实施由 GitHub 应用提供支持的自定义保护规则,以使用合作伙伴系统来控制引用 GitHub 上配置环境的部署。

下面是这些保护规则的说明:

  • 必需的审阅者保护规则。 使用此规则来要求特定人员或团队批准引用环境的工作流任务。 最多可以列出六个用户或团队作为审阅者。 审阅者必须至少具有对存储库的读取权限。 只有一个必需的审阅者必须批准该作业才能继续。

    还可以阻止对部署到受保护环境的部署进行自我评审。 如果启用此设置,则启动部署的用户无法批准部署作业,即使他们是所需的审阅者也是如此。 通过启用自我审核机制,可确保有多个人员对向受保护环境的部署进行评审。

    有关审阅引用了包含必需审阅者的环境的作业的详细信息,请参阅审阅部署

  • 等待计时器投影规则。 您可以使用等待计时器保护规则在作业初始触发后,将作业延迟特定时间,然后再进行环境部署。 时间(以分钟为单位)必须是介于 1 和 43,200(30 天)之间的整数。 等待时间不计入计费时间。

  • 分支和标记保护规则。 可以使用部署分支和标记保护规则来限制用于部署到环境的分支和标记。 对于环境,有多个选项可用于部署分支和标记保护规则。

    • 没有限制 意味着可以将任何分支或标签部署到环境中。
    • “仅限受保护的分支”只允许将启用了分支保护规则的分支部署到环境。 如果未为存储库中的任何分支定义分支保护规则,则所有分支都可以部署。 “所选分支和标记”设置可确保只有与指定名称模式匹配的分支和标记才能部署到环境。
    • 如果指定 releases/* 为部署分支或标记规则,则只有名称以开头 releases/ 的分支或标记可以部署到环境。 (通配符不匹配 /。若要匹配以 release/ 开头且包含一个单独斜杠的分支或标记,请使用 release/*/*。)如果添加 main 作为分支规则,则名为 main 的分支也可以部署到环境。
  • 自定义部署保护规则。 可以创建自定义保护规则来限制部署以使用合作伙伴服务。 例如,可以使用可观测性系统、更改管理系统、代码质量系统或其他手动配置来评估就绪情况,并为部署到 GitHub 的部署提供自动审批。

    创建自定义部署保护规则并将其安装在存储库上后,可以为存储库中的任何环境启用自定义部署保护规则。

    显示用于配置 Environment1 的“设置”页的屏幕截图,其中包含审阅者、等待计时器、自定义规则和分支限制的选项。

注释

如果你有 GitHub Free、GitHub Pro 或 GitHub Team 计划,则环境部署投影规则仅适用于公共存储库;分支和标记保护规则除外。 对于具有 GitHub Pro 或 GitHub Team 计划的用户,分支和标记保护规则也可用于专用存储库。

工作流中的脚本

在上述工作流代码片段示例中,run 关键字用于打印文本字符串。 由于 run 关键字会告知作业在运行器上执行命令,因此请使用 run 关键字来运行操作或脚本。

jobs:
  example-job:
    steps:
      - run: npm install -g bats

在此示例中,使用 npm 通过关键字安装 bats 软件测试包 run 。 还可以将脚本作为操作运行。 你可以将该脚本存储在存储库中(通常在 .github/scripts/ 目录中完成),然后使用 run 关键字提供路径和 shell 类型。

jobs:
  example-job:
    steps:
      - name: Run build script
        run: ./.github/scripts/build.sh
        shell: bash