Github Actions 无法使用 --arg 识别 jq

问题描述 投票:0回答:1

我的工作流程如下所示:

name: Site - Build and Deploy FTP

on:
  push:
    branches: main
    paths:
      - 'src/Site/Site/**'
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/[email protected]
      
      - name: Setup .NET Core
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '6.0.x'
          include-prerelease: true
          
      - name: Install dependencies
        working-directory: src/Site/Site
        run: dotnet restore
        
      - name: Build with dotnet
        working-directory: src/Site/Site
        run: dotnet build --configuration Release
        
      - name: Publish
        working-directory: src/Site/Site
        run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp
        
      #substitute production appsettings entries to temp json file
      - name: App Settings Variable Substitution
        shell: bash
        run: | 
           cat ${{env.DOTNET_ROOT}}/myapp/appsettings.json | jq --arg my_secret ${{secrets.SQL_CONNECTION_STRING}} --arg email_secret ${{secrets.EMAIL_PASSWORD}} '.Config.SiteDb = $my_secret | .Config.EmailPassword = $email_secret' > newfile.json

直到两周前它才开始在替代应用程序设置步骤上失败。奇怪的是我没有改变工作流程中的任何内容。另外,我对项目的另一部分有一个几乎相同的工作流程,每次都会成功(.yml 文件中的唯一区别是它在不同的项目上运行,并从自己的 appsettings.json 文件中替换出不同的设置。)它将失败并显示 127 错误代码,但 cat 命令会将 appsettings.json 文件写入控制台,因此它可以正确找到该文件,因此它一定是 jq 命令有问题。

我尝试删除 --arg 选项和替换过滤器,并将其替换为“jq '.'”,并且成功了。然后,我尝试执行“jq '.Config.SiteDb = 5 | .Config.EmailPassword = 9'”,结果成功了。所以看起来 --arg 的某些东西弄乱了这个特定的跑步者?

github-actions jq
1个回答
0
投票

当您在 Github Actions 的 shell 脚本中展开这样的变量时,它们会被 shell 完全解释,就像您输入了这些字符一样。

      #substitute production appsettings entries to temp json file
      - name: App Settings Variable Substitution
        shell: bash
        run: | 
           cat ${{env.DOTNET_ROOT}}/myapp/appsettings.json | jq --arg my_secret ${{secrets.SQL_CONNECTION_STRING}} --arg email_secret ${{secrets.EMAIL_PASSWORD}} '.Config.SiteDb = $my_secret | .Config.EmailPassword = $email_secret' > newfile.json

这意味着变量中可能被 shell 解释的任何字符都会导致问题:

  • 空格会导致有多个参数而不是一个。
  • 引号字符可能被 shell 视为引用块的开始或结束而不是它们本身,并从根本上改变了该行其余部分的解释。
  • 反斜杠可能被视为转义字符。
  • >
    <
    可能被视为重定向。
  • |
    可以被视为管道步骤。
  • ...还有更多。

您的示例的行为会有所不同,具体取决于密码中恰好包含哪些字符。

如果你可以保证字符串不包含单引号和换行符,你可以用单引号括起来。

在大多数情况下,更好的选择是引入环境变量。所以,尝试这样的事情:

      #substitute production appsettings entries to temp json file
      - name: App Settings Variable Substitution
        shell: bash
        run: | 
           cat ${{env.DOTNET_ROOT}}/myapp/appsettings.json | jq --arg my_secret "$SQL_CONNECTION_STRING" --arg email_secret "$EMAIL_PASSWORD" '.Config.SiteDb = $my_secret | .Config.EmailPassword = $email_secret' > newfile.json
        env:
          SQL_CONNECTION_STRING: ${{secrets.SQL_CONNECTION_STRING}}
          EMAIL_PASSWORD: ${{secrets.EMAIL_PASSWORD}}

这次,扩展是由 shell 完成的,而不是由 GHA 完成的,因此它不会将字符串的内容重新解释为 shell 字符。

这样做的一个缺点是环境变量对于 shell 中启动的每个进程都是可见的。如果这是不可接受的,您可以使用 bash 的

export -n VARIABLENAME
来启动脚本,从环境中删除这些变量,同时将它们保留为 shell 变量。

© www.soinside.com 2019 - 2024. All rights reserved.