You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Github Actions环境变量验证输出为空的问题排查与修复

问题描述

我用以下GitHub工作流构建项目并获取Git Commit SHA与标签:

name: proj-build

on: [workflow_call, workflow_dispatch]

env:
  # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
  BUILD_TYPE: Release
  CYGWIN_HOME: C:\cygwin64
  PERL_HOME: C:\strawberry-perl\perl
  CMAKE_BUILD_ARTIFACT_NAME: artifact-build
  COMMIT_SHA: ''
  TAG_NAME: ''

jobs:
  build-cmake:
    runs-on: [ self-hosted, Windows ]
    timeout-minutes: 500
    steps:
    # Authenticate for accessing repos in the organization
    - name: Setup git
      uses: myorg/common-actions/setup-git@master
      id: setup-git
      with:
        app-id: ${{ vars.IRA_APP_ID }}
        private-key: ${{ secrets.IRA_PRIVATE_KEY }}

    - name: Checkout proj repo
      uses: actions/checkout@v4
      with:
        token: ${{ steps.setup-git.outputs.token }}
        fetch-tags: 'true'
        fetch-depth: 0
        path: myproj

    - name: Get Commit SHA
      id: get-sha
      shell: pwsh
      run: |
        Write-Output "SHA=${{ github.sha }}"
        echo "COMMIT_SHA=${{ github.sha }}" >> $GITHUB_ENV

    - name: Get Tag
      id: get-tag
      shell: pwsh
      continue-on-error: true
      if: startsWith(github.ref, 'refs/tags/')
      run: |
        Write-Output "TAG=${{ github.ref }}"
        $tagName = "${{ github.ref }}" -replace 'refs/tags/', ''
        Write-Output "tagName=$tagName"
        echo "TAG_NAME=$tagName" >> $GITHUB_ENV

    - name: Handle untagged commits
      shell: pwsh
      if: env.TAG_NAME == ''
      run: echo "TAG_NAME=none" >> $GITHUB_ENV

    - name: Verify commit & tag info in the environment
      id: set-outputs
      shell: pwsh
      run: |
        Write-Output "COMMIT_SHA=${{ env.COMMIT_SHA }}"
        Write-Output "TAG_NAME=${{ env.TAG_NAME }}"

    - name: Listing contents of repo directory before CMake build
      shell: powershell
      run: |
        cd ${{ github.workspace }}\myproj\.github\workflows\
        . ./get-contents.ps1
        Write-Output "Getting the contents of the myproj repo directory before CMake build..."
        Get-Directory-Contents -Path ${{ github.workspace }}\myproj

    - name: Build myproj
      shell: cmd
      run: |
        set PATH=%PATH%;%CYGWIN_HOME%
        cd ${{ github.workspace }}\myproj
        cmake -S . -B build
        cmake --build build --target install

    - name: Listing contents of repo directory after CMake build
      shell: powershell
      run: |
        cd ${{ github.workspace }}\myproj\.github\workflows\
        . ./get-contents.ps1
        Write-Output "Getting the contents of the myproj repo directory after CMake build..."
        Get-Directory-Contents -Path ${{ github.workspace }}\myproj
    
    - name: Creating an info file for build directory
      shell: powershell
      run: |
        tree ${{ github.workspace }}\myproj\build | `
          Out-File -FilePath ${{ github.workspace }}\myproj\build\build.info -Append -Encoding utf8; `
          Get-ChildItem ${{ github.workspace }}\myproj\build -Recurse | `
          Measure-Object -Property Length -Sum | ForEach-Object { 'Total Size: {0} MB' -f ($_.Sum / 1MB) } | `
          Out-File -FilePath ${{ github.workspace }}\myproj\build\build.info -Append -Encoding utf8

    - name: Save environment variables to file
      shell: cmd
      run: |
        echo COMMIT_SHA=${{ env.COMMIT_SHA }}
        echo TAG_NAME=${{ env.TAG_NAME }}
        echo COMMIT_SHA=${{ env.COMMIT_SHA }} > ${{ github.workspace }}\myproj\build\environment.info
        echo TAG_NAME=${{ env.TAG_NAME }} >> ${{ github.workspace }}\myproj\build\environment.info
        echo %COMMIT_SHA%
        echo %TAG_NAME%

    - name: Upload Artifact
      if: always()
      uses: actions/upload-artifact@v4
      with:
        name: ${{ env.CMAKE_BUILD_ARTIFACT_NAME }}
        retention-days: 2
        path: |
            ${{ github.workspace }}\myproj\build

我希望把.info文件里的环境变量作为工件上传给后续工作流使用,但“验证环境中的提交和标签信息”与“将环境变量保存到文件”步骤输出为空:

COMMIT_SHA=
TAG_NAME=

请问该如何修复?我哪里操作错了?


错误原因与修复方案

核心问题

  1. 预渲染与环境变量的时序冲突:你用${{ env.COMMIT_SHA }}这种模板语法读取环境变量时,GitHub会在步骤执行前就完成渲染,而你是在前面的步骤中才设置这些变量,导致读取到的是初始定义的空值。
  2. PowerShell写入环境变量的语法错误:用echo >> $GITHUB_ENV在PowerShell中会有兼容性问题,应该用PowerShell原生的文件写入命令。
  3. 未打标签判断逻辑错误:初始TAG_NAME就是空字符串,导致Handle untagged commits步骤会无条件触发,覆盖前面可能设置的标签值。

具体修复步骤

1. 删除env中的初始空值定义

先移除env里的COMMIT_SHA: ''和TAG_NAME: '',避免预渲染时读取到空值:

env:
  BUILD_TYPE: Release
  CYGWIN_HOME: C:\cygwin64
  PERL_HOME: C:\strawberry-perl\perl
  CMAKE_BUILD_ARTIFACT_NAME: artifact-build
  # 删掉以下两行
  # COMMIT_SHA: ''
  # TAG_NAME: ''

2. 修正PowerShell写入环境变量的方式

改用Add-Content命令写入$GITHUB_ENV,同时设置步骤输出方便后续引用:

- name: Get Commit SHA
  id: get-sha
  shell: pwsh
  run: |
    $sha = "${{ github.sha }}"
    Write-Output "SHA=$sha"
    Add-Content -Path $env:GITHUB_ENV -Value "COMMIT_SHA=$sha"
    Write-Output "::set-output name=sha::$sha"

- name: Get Tag
  id: get-tag
  shell: pwsh
  continue-on-error: true
  if: startsWith(github.ref, 'refs/tags/')
  run: |
    $ref = "${{ github.ref }}"
    $tagName = $ref -replace 'refs/tags/', ''
    Write-Output "TAG=$ref"
    Write-Output "tagName=$tagName"
    Add-Content -Path $env:GITHUB_ENV -Value "TAG_NAME=$tagName"
    Write-Output "::set-output name=tag::$tagName"

3. 修正未打标签的判断逻辑

直接通过github.ref判断是否是标签,避免依赖环境变量的初始值:

- name: Handle untagged commits
  shell: pwsh
  if: !startsWith(github.ref, 'refs/tags/')
  run: |
    Add-Content -Path $env:GITHUB_ENV -Value "TAG_NAME=none"
    Write-Output "::set-output name=tag::none"

4. 修改验证与保存步骤的读取方式

不要用模板语法读取环境变量,直接读取当前shell的环境变量:

- name: Verify commit & tag info in the environment
  id: set-outputs
  shell: pwsh
  run: |
    $commitSha = $env:COMMIT_SHA
    $tagName = $env:TAG_NAME
    Write-Output "COMMIT_SHA=$commitSha"
    Write-Output "TAG_NAME=$tagName"
    Write-Output "::set-output name=commit_sha::$commitSha"
    Write-Output "::set-output name=tag_name::$tagName"

- name: Save environment variables to file
  shell: pwsh
  run: |
    $commitSha = $env:COMMIT_SHA
    $tagName = $env:TAG_NAME
    "COMMIT_SHA=$commitSha" | Out-File -FilePath "${{ github.workspace }}\myproj\build\environment.info" -Encoding utf8
    "TAG_NAME=$tagName" | Out-File -FilePath "${{ github.workspace }}\myproj\build\environment.info" -Append -Encoding utf8
    Write-Output "COMMIT_SHA=$commitSha"
    Write-Output "TAG_NAME=$tagName"

额外优化建议

  • 如果是workflow_call触发,github.sha可能不是你预期的提交,建议通过调用参数传递SHA和标签。
  • 也可以直接用Git命令获取SHA,避免依赖GitHub上下文:
    - name: Get Commit SHA via Git
      shell: pwsh
      working-directory: myproj
      run: |
        $sha = git rev-parse HEAD
        Add-Content -Path $env:GITHUB_ENV -Value "COMMIT_SHA=$sha"
    

内容的提问来源于stack exchange,提问作者skrowten_hermit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 17:44:56