Chapter 03

环境变量、Secrets 与上下文对象

安全管理敏感信息,灵活使用上下文数据,掌握 GitHub Actions 的表达式语法

环境变量(env)的三个层级

层级优先级:Step > Job > Workflow

name: 环境变量示例

env:                           # Workflow 级别(最低优先级)
  APP_NAME: "my-app"
  NODE_ENV: "production"

jobs:
  build:
    runs-on: ubuntu-latest
    env:                       # Job 级别(覆盖 Workflow 级别)
      BUILD_MODE: "release"
      NODE_ENV: "staging"     # 覆盖了 workflow 级别的 production

    steps:
      - name: 打印变量
        env:                   # Step 级别(最高优先级)
          NODE_ENV: "test"    # 此步骤内覆盖 staging
        run: |
          echo "APP_NAME: $APP_NAME"        # my-app
          echo "BUILD_MODE: $BUILD_MODE"    # release
          echo "NODE_ENV: $NODE_ENV"        # test(step级覆盖)

      - name: 动态设置环境变量
        run: |
          # 将变量写入 GITHUB_ENV,后续步骤可使用
          echo "BUILD_TIME=$(date -u +%Y%m%d%H%M%S)" >> $GITHUB_ENV
          echo "GIT_HASH=$(git rev-parse --short HEAD)" >> $GITHUB_ENV

      - name: 使用动态变量
        run: echo "构建时间: $BUILD_TIME, Commit: $GIT_HASH"

Secrets 安全管理

配置 Secrets

在 GitHub 仓库中设置 Secrets:Settings → Secrets and variables → Actions → New repository secret。Secrets 的值一旦保存,任何人(包括仓库管理员)都无法再次查看,只能使用或删除。

Secrets 的三个层级

Repository Secrets
仓库级别的 Secrets,只有该仓库的 Workflow 可以访问。适合单个项目专用的 API 密钥、部署凭证。
Environment Secrets
环境级别的 Secrets(需要在 job 中声明 environment),可以为 staging 和 production 环境配置不同的值,并设置审批保护规则。
Organization Secrets
组织级别的 Secrets,可以在组织内的多个仓库中共享。适合公司公共服务的凭证(如通知服务、监控平台)。
steps:
  # 在 env 中注入 Secret(推荐方式)
  - name: 部署到 AWS
    env:
      AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
      AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    run: aws s3 sync ./dist s3://my-bucket

  # 直接作为参数(某些 Action 要求)
  - uses: docker/login-action@v3
    with:
      username: ${{ secrets.DOCKER_USERNAME }}
      password: ${{ secrets.DOCKER_PASSWORD }}

  # GITHUB_TOKEN:自动生成,无需手动创建
  - name: 创建 Release
    uses: actions/create-release@v1
    env:
      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Secrets 安全规则

上下文对象(Context)

最常用的上下文

github 上下文
关于 Workflow 运行和触发事件的信息。包含:github.sha(当前提交哈希)、github.ref_name(分支/标签名)、github.actor(触发者)、github.event_name(事件类型)、github.repository(仓库全名)。
runner 上下文
Runner 环境信息。runner.os(Linux/Windows/macOS)、runner.arch(X64/ARM64)、runner.temp(临时目录路径)。
steps 上下文
访问同 Job 中其他步骤的输出和状态。steps.STEP_ID.outputs.KEY(步骤输出)、steps.STEP_ID.outcome(success/failure/skipped/cancelled)。
needs 上下文
访问依赖 Job 的输出。needs.JOB_ID.outputs.KEY
vars 上下文
访问仓库/环境/组织的变量(非敏感配置值,可在 UI 中查看)。vars.APP_NAME

表达式语法 ${{ }}

条件与函数

steps:
  # 条件函数
  - name: 只在 main 分支运行
    if: github.ref == 'refs/heads/main'
    run: echo "这是主分支"

  - name: 失败时通知
    if: failure()
    run: echo "流水线失败了!"

  - name: 总是执行(包括失败后)
    if: always()
    run: echo "清理临时文件"

  # 字符串函数
  - name: 使用字符串函数
    run: |
      # contains():检查是否包含子串
      if [[ "${{ github.event.head_commit.message }}" == *"[skip ci]"* ]]; then
        echo "跳过 CI"
      fi

  # 三元表达式(利用 if 语法模拟)
  - name: 设置部署环境
    run: |
      if [[ "${{ github.ref_name }}" == "main" ]]; then
        DEPLOY_ENV="production"
      else
        DEPLOY_ENV="staging"
      fi
      echo "DEPLOY_ENV=$DEPLOY_ENV" >> $GITHUB_ENV

  # toJSON():调试输出上下文
  - name: 输出 github 上下文(调试用)
    run: echo '${{ toJSON(github) }}'

内置函数速查

函数用途示例
contains(str, substr)检查包含关系contains(github.ref, 'release')
startsWith(str, prefix)检查前缀startsWith(github.ref, 'refs/tags/')
endsWith(str, suffix)检查后缀endsWith(matrix.os, 'latest')
format(str, ...)字符串格式化format('v{0}.{1}', major, minor)
join(arr, sep)数组连接join(matrix.os, ',')
toJSON(value)转 JSON 字符串toJSON(github.event)
fromJSON(str)解析 JSONfromJSON(steps.data.outputs.json)
hashFiles(pattern)文件内容哈希hashFiles('**/package-lock.json')
success()之前步骤都成功if: success()
failure()之前有步骤失败if: failure()
always()总是执行if: always()
cancelled()工作流被取消if: cancelled()

Jobs 之间传递输出(outputs)

Job 的 outputs 允许一个 Job 将计算结果传递给后续依赖 Job,是实现动态流水线的关键机制:

jobs:
  # 第一个 Job:确定版本号
  determine-version:
    runs-on: ubuntu-latest
    outputs:
      # 声明该 Job 的输出
      version: ${{ steps.semver.outputs.version }}
      is-release: ${{ steps.check-tag.outputs.is-release }}
    steps:
      - uses: actions/checkout@v4

      - name: 从 tag 提取版本号
        id: check-tag
        run: |
          if [[ "${{ github.ref }}" == refs/tags/v* ]]; then
            echo "is-release=true" >> $GITHUB_OUTPUT
            echo "tag-version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
          else
            echo "is-release=false" >> $GITHUB_OUTPUT
          fi

      - name: 计算语义化版本
        id: semver
        run: |
          VERSION="${{ steps.check-tag.outputs.tag-version || '0.0.0-dev' }}"
          echo "version=$VERSION" >> $GITHUB_OUTPUT
          echo "Computed version: $VERSION"

  # 第二个 Job:使用第一个 Job 的输出
  build:
    needs: determine-version
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: 注入版本信息
        run: |
          VERSION="${{ needs.determine-version.outputs.version }}"
          echo "Building version: $VERSION"
          echo "VERSION=$VERSION" >> $GITHUB_ENV
      - run: npm run build

  # 第三个 Job:条件触发(只在 Release 时运行)
  publish:
    needs: [determine-version, build]
    # 只有当 is-release 为 true 时才运行
    if: needs.determine-version.outputs.is-release == 'true'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Publishing v${{ needs.determine-version.outputs.version }}"

Environment(部署环境)

Environment 是 GitHub Actions 的部署环境保护机制,可以为生产环境配置手动审批和等待规则:

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    environment:
      name: staging                          # 环境名称
      url: https://staging.myapp.com         # 部署后显示的链接
    steps:
      - run: echo "部署到 staging 环境"
        env:
          # Environment Secrets 只有在声明了对应 environment 时才可访问
          API_KEY: ${{ secrets.API_KEY }}     # staging 环境的 Secret

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment:
      name: production                       # 此环境配置了"必须审批"规则
      url: https://myapp.com
    steps:
      - run: echo "部署到 production 环境"
        env:
          API_KEY: ${{ secrets.API_KEY }}     # production 环境的 Secret(不同的值)
Environment 保护规则配置

在 Settings → Environments 中为 production 环境配置:Required reviewers(必须由指定成员审批后才能部署)、Wait timer(部署前等待 N 分钟)、Deployment branches(只有特定分支可以部署到此环境)。这为生产部署提供了人工审核的保障。

本章小结

本章核心要点