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=
请问该如何修复?我哪里操作错了?
错误原因与修复方案
核心问题
- 预渲染与环境变量的时序冲突:你用
${{ env.COMMIT_SHA }}这种模板语法读取环境变量时,GitHub会在步骤执行前就完成渲染,而你是在前面的步骤中才设置这些变量,导致读取到的是初始定义的空值。 - PowerShell写入环境变量的语法错误:用
echo >> $GITHUB_ENV在PowerShell中会有兼容性问题,应该用PowerShell原生的文件写入命令。 - 未打标签判断逻辑错误:初始
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
相关产品推荐
相关产品推荐

