GitHub Actions 工作流产物 #

工作流产物(outputs)允许在作业间传递数据。本节详细介绍如何定义和使用outputs。

Outputs概述 #

什么是Outputs? #

Outputs是作业或步骤产生的输出值:

  • 跨步骤共享数据
  • 跨作业共享数据
  • 传递构建信息
  • 实现工作流通信

Outputs类型 #

类型 作用域 用途
步骤输出 当前作业 步骤间传递数据
作业输出 整个工作流 作业间传递数据

步骤输出 #

设置输出 #

yaml
steps:
  - id: set-output
    name: Set output
    run: echo "name=value" >> $GITHUB_OUTPUT

多个输出 #

yaml
steps:
  - id: set-outputs
    name: Set multiple outputs
    run: |
      echo "name=John" >> $GITHUB_OUTPUT
      echo "age=30" >> $GITHUB_OUTPUT
      echo "city=New York" >> $GITHUB_OUTPUT

使用输出 #

yaml
steps:
  - id: set-value
    run: echo "result=success" >> $GITHUB_OUTPUT

  - name: Use output
    run: echo "Result is ${{ steps.set-value.outputs.result }}"

多行输出 #

yaml
steps:
  - id: multiline
    run: |
      {
        echo "content<<EOF"
        echo "Line 1"
        echo "Line 2"
        echo "Line 3"
        echo "EOF"
      } >> $GITHUB_OUTPUT

  - name: Use multiline
    run: |
      echo "${{ steps.multiline.outputs.content }}"

JSON输出 #

yaml
steps:
  - id: json
    run: |
      echo 'data={"name":"test","value":123}' >> $GITHUB_OUTPUT

  - name: Use JSON
    run: |
      echo "Name: ${{ fromJson(steps.json.outputs.data).name }}"
      echo "Value: ${{ fromJson(steps.json.outputs.data).value }}"

作业输出 #

定义作业输出 #

yaml
jobs:
  build:
    outputs:
      version: ${{ steps.version.outputs.value }}
      artifact: ${{ steps.artifact.outputs.path }}
    runs-on: ubuntu-latest
    steps:
      - id: version
        run: echo "value=1.0.0" >> $GITHUB_OUTPUT
      - id: artifact
        run: echo "path=dist/" >> $GITHUB_OUTPUT

使用作业输出 #

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

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Use output
        run: echo "Deploying version ${{ needs.build.outputs.version }}"

实际应用示例 #

版本管理 #

yaml
jobs:
  setup:
    outputs:
      version: ${{ steps.version.outputs.value }}
      should-deploy: ${{ steps.check.outputs.deploy }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - id: version
        run: |
          if [ "${{ github.ref_type }}" == "tag" ]; then
            echo "value=${{ github.ref_name }}" >> $GITHUB_OUTPUT
          else
            echo "value=$(git describe --tags --always)" >> $GITHUB_OUTPUT
          fi
      
      - id: check
        run: |
          if [ "${{ github.ref }}" == "refs/heads/main" ]; then
            echo "deploy=true" >> $GITHUB_OUTPUT
          else
            echo "deploy=false" >> $GITHUB_OUTPUT
          fi

  build:
    needs: setup
    runs-on: ubuntu-latest
    steps:
      - name: Build version
        run: echo "Building version ${{ needs.setup.outputs.version }}"

  deploy:
    needs: [setup, build]
    if: needs.setup.outputs.should-deploy == 'true'
    runs-on: ubuntu-latest
    steps:
      - name: Deploy
        run: echo "Deploying version ${{ needs.setup.outputs.version }}"

动态矩阵 #

yaml
jobs:
  setup:
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    runs-on: ubuntu-latest
    steps:
      - id: set-matrix
        run: |
          if [ "${{ github.ref }}" == "refs/heads/main" ]; then
            echo 'matrix={"include":[{"node":"16"},{"node":"18"},{"node":"20"}]}' >> $GITHUB_OUTPUT
          else
            echo 'matrix={"include":[{"node":"20"}]}' >> $GITHUB_OUTPUT
          fi

  test:
    needs: setup
    strategy:
      matrix: ${{ fromJSON(needs.setup.outputs.matrix) }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}

构建信息 #

yaml
jobs:
  build:
    outputs:
      artifact-name: ${{ steps.build.outputs.name }}
      artifact-size: ${{ steps.build.outputs.size }}
      artifact-hash: ${{ steps.build.outputs.hash }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run build
      
      - id: build
        run: |
          name="build-${{ github.sha }}"
          size=$(du -sb dist/ | cut -f1)
          hash=$(find dist/ -type f -exec sha256sum {} \; | sha256sum | cut -d' ' -f1)
          
          echo "name=$name" >> $GITHUB_OUTPUT
          echo "size=$size" >> $GITHUB_OUTPUT
          echo "hash=$hash" >> $GITHUB_OUTPUT

  report:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - name: Report
        run: |
          echo "## Build Report" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          echo "- **Name**: ${{ needs.build.outputs.artifact-name }}" >> $GITHUB_STEP_SUMMARY
          echo "- **Size**: ${{ needs.build.outputs.artifact-size }} bytes" >> $GITHUB_STEP_SUMMARY
          echo "- **Hash**: ${{ needs.build.outputs.artifact-hash }}" >> $GITHUB_STEP_SUMMARY

环境选择 #

yaml
jobs:
  detect:
    outputs:
      environment: ${{ steps.detect.outputs.env }}
    runs-on: ubuntu-latest
    steps:
      - id: detect
        run: |
          if [ "${{ github.ref }}" == "refs/heads/main" ]; then
            echo "env=production" >> $GITHUB_OUTPUT
          elif [ "${{ github.ref }}" == "refs/heads/develop" ]; then
            echo "env=staging" >> $GITHUB_OUTPUT
          else
            echo "env=development" >> $GITHUB_OUTPUT
          fi

  deploy:
    needs: detect
    runs-on: ubuntu-latest
    environment: ${{ needs.detect.outputs.environment }}
    steps:
      - name: Deploy
        run: echo "Deploying to ${{ needs.detect.outputs.environment }}"

变更检测 #

yaml
jobs:
  changes:
    outputs:
      frontend: ${{ steps.filter.outputs.frontend }}
      backend: ${{ steps.filter.outputs.backend }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dorny/paths-filter@v3
        id: filter
        with:
          filters: |
            frontend:
              - 'frontend/**'
            backend:
              - 'backend/**'

  build-frontend:
    needs: changes
    if: needs.changes.outputs.frontend == 'true'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Building frontend"

  build-backend:
    needs: changes
    if: needs.changes.outputs.backend == 'true'
    runs-on: ubuntu-latest
    steps:
      - run: echo "Building backend"

输出限制 #

大小限制 #

  • 单个输出值最大1MB
  • 总输出大小有限制

类型限制 #

  • 只支持字符串
  • 复杂类型需要JSON序列化

最佳实践 #

1. 使用有意义的名称 #

yaml
outputs:
  build-version: ${{ steps.version.outputs.value }}
  artifact-path: ${{ steps.artifact.outputs.path }}

2. 验证输出 #

yaml
steps:
  - name: Validate output
    run: |
      if [ -z "${{ steps.set-output.outputs.result }}" ]; then
        echo "Output is empty"
        exit 1
      fi

3. 使用JSON传递复杂数据 #

yaml
steps:
  - id: set-data
    run: |
      echo 'data={"items":["a","b","c"],"count":3}' >> $GITHUB_OUTPUT

  - name: Use data
    run: |
      items=$(echo '${{ steps.set-data.outputs.data }}' | jq -r '.items[]')
      echo "$items"

4. 文档化输出 #

yaml
outputs:
  version:
    description: 'Application version'
    value: ${{ steps.version.outputs.value }

下一步学习 #

小结 #

  • Outputs用于数据传递
  • 步骤输出用于步骤间通信
  • 作业输出用于作业间通信
  • 使用GITHUB_OUTPUT设置输出
  • 复杂数据使用JSON序列化
  • 注意输出大小限制
最后更新:2026-03-28