GitHub Actions 上下文与表达式 #

上下文和表达式是GitHub Actions中访问运行时信息和实现动态配置的核心机制。本节详细介绍上下文访问和表达式语法。

上下文概述 #

什么是上下文? #

上下文是包含运行时信息的对象,可以在工作流中访问:

  • 仓库信息
  • 工作流信息
  • 作业信息
  • 步骤信息
  • 运行器信息

访问语法 #

yaml
${{ context.property }}
${{ context.property.nested }}

可用上下文 #

github上下文 #

yaml
steps:
  - name: Display github context
    run: |
      echo "Repository: ${{ github.repository }}"
      echo "Repository Owner: ${{ github.repository_owner }}"
      echo "Workflow: ${{ github.workflow }}"
      echo "Workflow Ref: ${{ github.workflow_ref }}"
      echo "Workflow SHA: ${{ github.workflow_sha }}"
      echo "Run ID: ${{ github.run_id }}"
      echo "Run Number: ${{ github.run_number }}"
      echo "Run Attempt: ${{ github.run_attempt }}"
      echo "Event Name: ${{ github.event_name }}"
      echo "Event Path: ${{ github.event_path }}"
      echo "SHA: ${{ github.sha }}"
      echo "Ref: ${{ github.ref }}"
      echo "Ref Name: ${{ github.ref_name }}"
      echo "Ref Type: ${{ github.ref_type }}"
      echo "Actor: ${{ github.actor }}"
      echo "Actor ID: ${{ github.actor_id }}"
      echo "Triggering Actor: ${{ github.triggering_actor }}"
      echo "Job: ${{ github.job }}"
      echo "Action: ${{ github.action }}"
      echo "Action Path: ${{ github.action_path }}"
      echo "Action Repository: ${{ github.action_repository }}"
      echo "Action Ref: ${{ github.action_ref }}"
      echo "Token: ${{ github.token }}"
      echo "Workspace: ${{ github.workspace }}"
      echo "Event: ${{ github.event }}"
      echo "Server URL: ${{ github.server_url }}"
      echo "API URL: ${{ github.api_url }}"
      echo "GraphQL URL: ${{ github.graphql_url }}"

env上下文 #

yaml
env:
  MY_VAR: value

steps:
  - name: Use env context
    run: echo "${{ env.MY_VAR }}"

job上下文 #

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      status: ${{ job.status }}
    steps:
      - name: Job info
        run: |
          echo "Job Status: ${{ job.status }}"
          echo "Job Container: ${{ job.container }}"
          echo "Job Services: ${{ job.services }}"

steps上下文 #

yaml
steps:
  - id: step1
    name: First step
    run: echo "result=success" >> $GITHUB_OUTPUT

  - name: Use steps context
    run: |
      echo "Step 1 Result: ${{ steps.step1.outputs.result }}"
      echo "Step 1 Outcome: ${{ steps.step1.outcome }}"
      echo "Step 1 Conclusion: ${{ steps.step1.conclusion }}"

runner上下文 #

yaml
steps:
  - name: Runner info
    run: |
      echo "OS: ${{ runner.os }}"
      echo "Arch: ${{ runner.arch }}"
      echo "Name: ${{ runner.name }}"
      echo "Tool Cache: ${{ runner.tool_cache }}"
      echo "Temp: ${{ runner.temp }}"
      echo "Debug: ${{ runner.debug }}"

secrets上下文 #

yaml
steps:
  - name: Use secrets
    env:
      API_KEY: ${{ secrets.API_KEY }}
    run: echo "Using secret"

needs上下文 #

yaml
jobs:
  build:
    outputs:
      version: ${{ steps.version.outputs.value }}
    steps:
      - id: version
        run: echo "value=1.0.0" >> $GITHUB_OUTPUT

  deploy:
    needs: build
    steps:
      - name: Use needs context
        run: |
          echo "Build Version: ${{ needs.build.outputs.version }}"
          echo "Build Result: ${{ needs.build.result }}"

inputs上下文 #

yaml
on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment'
        required: true

jobs:
  deploy:
    steps:
      - name: Use inputs context
        run: echo "Environment: ${{ inputs.environment }}"

vars上下文 #

yaml
steps:
  - name: Use vars context
    run: echo "Custom var: ${{ vars.MY_VAR }}"

表达式语法 #

基本语法 #

yaml
${{ expression }}

字面量 #

yaml
# 字符串
${{ 'hello' }}
${{ "hello" }}

# 数字
${{ 42 }}
${{ 3.14 }}

# 布尔值
${{ true }}
${{ false }}

# null
${{ null }}

运算符 #

比较运算符 #

运算符 描述
== 等于
!= 不等于
< 小于
> 大于
<= 小于等于
>= 大于等于
yaml
if: github.ref == 'refs/heads/main'
if: github.run_number > 10
if: env.NODE_VERSION != '16'

逻辑运算符 #

运算符 描述
&&
||
!
yaml
if: github.ref == 'refs/heads/main' && success()
if: github.event_name == 'push' || github.event_name == 'pull_request'
if: !failure()

函数 #

状态函数 #

函数 描述
success() 前面步骤都成功
failure() 前面有步骤失败
cancelled() 工作流被取消
always() 总是执行
yaml
steps:
  - name: On success
    if: success()
    run: echo "Success"

  - name: On failure
    if: failure()
    run: echo "Failed"

  - name: Always
    if: always()
    run: echo "Always runs"

包含函数 #

yaml
# contains
if: contains(github.ref, 'release')

# startsWith
if: startsWith(github.ref, 'refs/tags/')

# endsWith
if: endsWith(github.ref, '.js')

格式化函数 #

yaml
# format
run: echo "${{ format('Hello {0} {1}', 'World', '!') }}"

# join
run: echo "${{ join(matrix.os, ', ') }}"

# toJSON
run: echo "${{ toJSON(github.event) }}"

# fromJSON
run: echo "${{ fromJSON(env.MY_JSON).name }}"

类型转换 #

yaml
# toString
run: echo "${{ toString(42) }}"

# toNumber
run: echo "${{ toNumber('42') }}"

其他函数 #

yaml
# hashFiles
if: hashFiles('**/package-lock.json') != ''

# getenv
run: echo "${{ getenv('HOME') }}"

# interpolate
run: echo "${{ interpolate('${{ env.VAR }}') }}"

条件表达式 #

基本条件 #

yaml
jobs:
  deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying"

组合条件 #

yaml
jobs:
  deploy:
    if: github.ref == 'refs/heads/main' && success()
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying"

使用上下文 #

yaml
jobs:
  deploy:
    if: github.event_name == 'push' && github.event.created == true
    runs-on: ubuntu-latest
    steps:
      - run: echo "New branch created"

使用矩阵 #

yaml
jobs:
  test:
    strategy:
      matrix:
        node: [16, 18, 20]
    runs-on: ubuntu-latest
    steps:
      - name: Only Node 20
        if: matrix.node == '20'
        run: echo "Node 20"

动态配置 #

动态环境变量 #

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    env:
      ENVIRONMENT: ${{ github.ref_name }}
      VERSION: ${{ github.sha }}
    steps:
      - run: |
          echo "Environment: $ENVIRONMENT"
          echo "Version: $VERSION"

动态矩阵 #

yaml
jobs:
  test:
    strategy:
      matrix:
        include: ${{ fromJSON(needs.setup.outputs.matrix) }}

动态分支 #

yaml
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ github.ref_name == 'main' && 'production' || 'staging' }}
    steps:
      - run: echo "Deploying"

表达式示例 #

分支判断 #

yaml
jobs:
  deploy:
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Production deployment"

事件判断 #

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Push event
        if: github.event_name == 'push'
        run: echo "Push event"

      - name: PR event
        if: github.event_name == 'pull_request'
        run: echo "Pull request event"

路径判断 #

yaml
jobs:
  build:
    if: contains(github.event.head_commit.modified, 'src/')
    runs-on: ubuntu-latest
    steps:
      - run: echo "Source files changed"

标签判断 #

yaml
jobs:
  release:
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - run: echo "Release from tag"

矩阵条件 #

yaml
jobs:
  test:
    strategy:
      matrix:
        node: [16, 18, 20]
        os: [ubuntu-latest, windows-latest]
        exclude:
          - node: 16
            os: windows-latest
    runs-on: ${{ matrix.os }}
    steps:
      - name: Coverage report
        if: matrix.node == '20' && matrix.os == 'ubuntu-latest'
        run: npm run coverage

作业依赖条件 #

yaml
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Building"

  test:
    needs: build
    if: success()
    runs-on: ubuntu-latest
    steps:
      - run: echo "Testing"

  deploy:
    needs: [build, test]
    if: success() && github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying"

三元表达式 #

yaml
env:
  ENVIRONMENT: ${{ github.ref == 'refs/heads/main' && 'production' || 'staging' }}

复杂表达式 #

yaml
jobs:
  deploy:
    if: |
      github.event_name == 'push' &&
      github.ref == 'refs/heads/main' &&
      !contains(github.event.head_commit.message, '[skip deploy]')
    runs-on: ubuntu-latest
    steps:
      - run: echo "Deploying"

最佳实践 #

1. 使用有意义的变量名 #

yaml
env:
  IS_MAIN_BRANCH: ${{ github.ref == 'refs/heads/main' }}
  IS_PRODUCTION: ${{ github.event.inputs.environment == 'production' }}

2. 简化复杂表达式 #

yaml
# 使用环境变量简化
env:
  SHOULD_DEPLOY: ${{ github.ref == 'refs/heads/main' && success() }}

jobs:
  deploy:
    if: env.SHOULD_DEPLOY == 'true'

3. 使用JSON处理复杂数据 #

yaml
steps:
  - name: Parse JSON
    id: parse
    run: |
      echo "data=$(cat config.json | jq -c .)" >> $GITHUB_OUTPUT

  - name: Use parsed data
    run: |
      echo "Name: ${{ fromJSON(steps.parse.outputs.data).name }}"

4. 使用上下文而非环境变量 #

yaml
# 推荐
if: github.ref == 'refs/heads/main'

# 也可以
if: env.GITHUB_REF == 'refs/heads/main'

下一步学习 #

小结 #

  • 上下文提供运行时信息访问
  • 表达式用于动态计算值
  • 使用 ${{ }} 语法访问上下文和表达式
  • 支持比较、逻辑运算符和函数
  • 条件表达式控制执行流程
  • 使用函数处理复杂数据
  • 简化复杂表达式提高可读性
最后更新:2026-03-28