使用环境变量和项目数据自定义工作流

已完成

在本单元中,你将了解如何使用默认和自定义环境变量、使用自定义脚本、缓存依赖项以及在作业之间传递项目数据。 你还将了解如何通过 GitHub 网站和 REST API 终结点访问工作流日志。

默认环境变量和上下文

在 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 来引用分支。 请注意,默认环境变量均采用大写形式,而上下文变量均采用小写形式。

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

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

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

上下文 步骤
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 github、、needsstrategymatrix、、jobrunnerenv、vars、、secrets、、 stepsinputs hashFiles
jobs.<job_id>.steps.working-directory github、、needsstrategymatrix、、jobrunnerenv、vars、、secrets、、 stepsinputs hashFiles
jobs.<job_id>.strategy github、需求、 vars、、 inputs 没有
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 限定工作流中作业的内容。 可以使用 <a0/a0> 在作业中的特定步骤中限定环境变量的范围。

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

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环境文件。 可以使用关键字在作或工作流作业 run 中的 shell 命令中使用环境文件。

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

下面是一个示例:

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

使用缓存操作缓存依赖项

生成工作流时,通常需要重复使用相同的输出或将依赖项从一个运行下载到另一个运行。 你可以缓存这些依赖项,以便更快、更高效地运行工作流,而不是反复下载这些依赖项。 缓存依赖项减少了在工作流中运行某些步骤所需的时间,因为 GitHub 托管的运行程序上的作业每次都会在干净的虚拟环境中启动。

要缓存作业的依赖项,请使用 GitHub 的 cache 操作。 此操作会检索你提供的唯一密钥发现的缓存。 该操作会在查找缓存后,将缓存的文件检索到你配置的路径。 若要使用该 cache 作,需要设置几个特定的参数:

参数 步骤 必选
Key 指保存和搜索缓存时创建的密钥标识符。
Path 指运行器上用于缓存或搜索的文件路径。
Restore-keys 如果未找到所需的缓存密钥,则包含要缓存的替代现有密钥。
steps:
  - uses: actions/checkout@v2

  - name: Cache NPM dependencies
    uses: actions/cache@v2
    with:
      path: ~/.npm
      key: ${{ runner.os }}-npm-cache-${{ hashFiles('**/package-lock.json') }}
      restore-keys: |
        ${{ runner.os }}-npm-cache-

在以上示例中,path 被设置为 ~/.npm,且 key 包含运行器的操作系统和 package-lock.json 文件的 SHA-256 哈希。 在使用 npm-cache 回退并有多重缓存时,以 ID 作为密钥前缀(在此示例中 restore-keys)非常有用。

在作业间传递项目数据

与在工作流中缓存依赖项的想法类似,可以在同一工作流内的作业之间传递数据。 可以使用和upload-artifact作传递数据download-artifact。 依赖于前一作业的项目的作业必须等待前一作业成功完成才能运行。 如果有一系列作业需要根据从早期作业上传的项目按顺序运行,则此方法非常有用。 例如,job_2 需要 job_1,方法是使用 needs: job_1 语法。

name: Share data between jobs
on: push
jobs:
  job_1:
    name: Upload File
    runs-on: ubuntu-latest
    steps:
      - run: echo "Hello World" > file.txt
      - uses: actions/upload-artifact@v2
        with:
          name: file
          path: file.txt

  job_2:
    name: Download File
    runs-on: ubuntu-latest
    needs: job_1
    steps:
      - uses: actions/download-artifact@v2
        with:
          name: file
      - run: cat file.txt

此示例有两个作业。 job_1 在文件中写入一些文本 file.txt 。 然后它使用 actions/upload-artifact@v2 操作上传此项目并存储数据,以便将来在工作流中使用。 job_2 要求使用 job_1 语法完成 needs: job_1。 然后它使用 actions/download-artifact@v2 操作下载该项目,然后输出 file.txt 的内容。

在工作流中启用步骤调试日志记录

在某些情况下,默认工作流日志无法提供足够的详细信息,无法诊断特定工作流运行、作业或步骤失败的原因。 在这些方案中,可以为两个选项启用更多调试日志记录: 运行步骤。 通过设置两个需要 admin 访问存储库的存储库 true机密来启用此诊断日志记录。

  • 若要启用运行诊断日志记录,请将包含工作流的存储库中的机密设置为 ACTIONS_RUNNER_DEBUGtrue
  • 若要启用步骤诊断日志记录,请将包含工作流的存储库中的 ACTIONS_STEP_DEBUG 密码设置为 true

访问 GitHub 中的工作流日志

当你考虑成功的自动化时,你的目标是花最少的时间查看自动化内容,以便你可以专注于相关的内容。 但有时事情没有按计划进行,你需要回顾所发生的事情。 调试过程可能会令人沮丧。

GitHub 具有明确的结构化布局,可帮助你在作业之间快速移动,同时保留当前调试步骤的上下文。

若要查看 GitHub 中运行的工作流日志:

  1. 在存储库中,转到“ ”选项卡。
  2. 在左窗格中,选择工作流。
  3. 在工作流运行列表中,选择运行。
  4. “作业”下,选择作业。
  5. 阅读日志输出。

如果在工作流中运行了多个运行,可以在选择工作流后选择 状态 筛选器,并将其设置为 “失败 ”,以仅显示该工作流中失败的运行。

从 REST API 访问工作流日志

除了通过 GitHub 查看日志之外,还可以使用 GitHub REST API 查看工作流运行的日志、重新运行工作流,甚至取消工作流运行。 若要使用 API 查看工作流运行的日志,请向日志终结点发送 GET 请求。 请记住,拥有存储库读取权限的任何人员均可使用此终结点。 如果存储库为专用,则必须使用具有 repo 作用域的访问令牌。

例如, GET 查看特定工作流运行日志的请求遵循以下路径:

GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs

确定何时使用 GitHub 应用中的安装令牌

在帐户上安装 GitHub 应用时,可以使用 REST 和 GraphQL API 请求将其作为应用安装 installation access token 进行身份验证。 此步骤允许应用访问安装拥有的资源,前提是应用被授予了所需的存储库访问权限和权限。 应用安装发出的 REST 或 GraphQL API 请求归因于应用。

在以下示例中,将 INSTALLATION_ACCESS_TOKEN 替换为安装访问令牌:

curl --request GET \
--url "https://api.github.com/meta" \
--header "Accept: application/vnd.github+json" \
--header "Authorization: Bearer INSTALLATION_ACCESS_TOKEN" \
--header "X-GitHub-Api-Version: 2022-11-28"

还可以使用安装访问令牌对基于 HTTP 的 Git 访问进行身份验证。 应用必须具有 Contents 存储库权限。 然后可以使用安装访问令牌作为 HTTP 密码。

将示例中的安装访问令牌替换为 TOKEN

git clone https://x-access-token:TOKEN@github.com/owner/repo.git