在Github Actions中读取JSON文件

33
我想读取一个 JSON 文件,并在 Github Actions YAML 文件中使用一个字符串属性。我该怎么做?(我需要的是 package.json 的版本号)

你的工作流程中想要读取这个文件的哪一部分? - smac89
当然,这是有限制的,但如果你需要版本,你可以使用这个链接:https://github.com/marketplace/actions/ga-project-version - EuberDeveloper
这真的会做到这一点,哈哈 - exoRift
10个回答

44

使用内置的fromJson(value)(请参见此处:https://docs.github.com/en/actions/learn-github-actions/expressions#fromjson

读取文件取决于您使用的shell。这是一个sh的示例:

name: Test linux job
on:
  push

jobs:
  testJob:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - id: set_var
        run: |
          content=`cat ./path/to/package.json`
          # the following lines are only required for multi line json
          content="${content//'%'/'%25'}"
          content="${content//$'\n'/'%0A'}"
          content="${content//$'\r'/'%0D'}"
          # end of optional handling for multi line json
          echo "::set-output name=packageJson::$content"
      - run: |
          echo "${{fromJson(steps.set_var.outputs.packageJson).version}}"


多行 JSON 处理请参考 https://github.com/orgs/community/discussions/26288#discussioncomment-3251220
关于 set-env / set-output 多行处理的 GitHub 问题:https://github.com/actions/toolkit/issues/403

2
如何在使用fromJson后访问对象的属性?echo result.property或$result.property或${result.property}或${{result.property}}? - michael
迈克尔的评论被作为一个单独的问题在这里提出:https://stackoverflow.com/questions/68557487/access-to-the-object-s-property-created-from-the-json-in-the-github-actions - riQQ
你能提供适用于多行JSON和矩阵转换的PowerShell替代方案吗? - wehelpdox
由于我不关心保留换行符,所以我做了类似于 cat package.json | tr '\n\r' ' ' 的事情,尽管这并不能正确解决编码百分号的问题。 - Kimball Robinson
您还可以使用 jq 快速获取 JSON 数据:cat package.json | jq '.version' - Kimball Robinson
直到我将 \r 的替换放在 \n 替换之前,这才对我起作用。 - The Geek

17

使用多行环境变量

- run: |
    echo 'PACKAGE_JSON<<EOF' >> $GITHUB_ENV
    cat ./package.json >> $GITHUB_ENV
    echo 'EOF' >> $GITHUB_ENV
- run: |
    echo '${{ fromJson(env.PACKAGE_JSON).version }}'

这样可以避免任何需要转义的情况。

使用您的代码原样会导致我的YAML lint出现问题:隐式键需要在单行上 - Reinsbrain
1
@Reinsbrain 在复制和粘贴后,某些内容没有对齐。增加另一个缩进为我修复了这个错误。 - Chiel

11
下面是一个示例,来自于官方GHA文档,其中包含两个更改:
  1. 从文件(./your.json)加载 json。
  2. 删除换行符(来源)。
  3. 使用fromJson解析输出并设置矩阵变量。
name: build
on: push
jobs:
  job1:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
    - id: set-matrix
      run: |
        JSON=$(cat ./your.json)
        echo "::set-output name=matrix::${JSON//'%'/'%25'}"

  job2:
    needs: job1
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{fromJson(needs.job1.outputs.matrix)}}
    steps:
    - run: build

如果我不使用矩阵,如何访问由fromJson创建的属性或对象? - michael
1
任何使用 GITHUB_OUTPUT 的更新都是很棒的。 - TheJeff
@TheJeff 这个答案可能是你需要的:https://dev59.com/J1IG5IYBdhLWcg3w_nNR#76393558 - ganjim

10

受 @dastrobu 的回答启发,可以将键/值添加到 $GITHUB_ENV,并使用 jq 将 package.json 转换/压缩为一行:

- run: echo "PACKAGE_JSON=$(jq -c . < package.json)" >> $GITHUB_ENV
- run: echo '${{ fromJson(env.PACKAGE_JSON).version }}'

8

您可以轻松使用Script操作来实现此功能。

- name: "Read JSON"
        uses: actions/github-script@v6
        id: check-env
        with:
          result-encoding: string
          script: |
            try {
              const fs = require('fs')
              const jsonString = fs.readFileSync('./dir/file.json')
              var apps = JSON.parse(jsonString)
            } catch(err) {
              core.error("Error while reading or parsing the JSON")
              core.setFailed(err)
            }

5
on: [push, pull_request] 
name: Build
jobs:
  build:
    name: Example
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with: 
          path: './'      
      - run: |
          echo "`jq '.base_config[0].value="Alpha-21"' config.json `" > config.json
          echo "`jq '.base_config[1].value="1.2.14"' config.json`" > config.json
          echo "`jq '.base_config[2].value="29/12/2020"' config.json `" > config.json
     
      - uses: EndBug/add-and-commit@v6
        with:
          message: 'Add the version and date'
          add: '*.json --force'
          cwd: './' 
          token: ${{ secrets.TOKEN }} 

3
Jq是默认安装的应用程序的一部分吗? - Macindows
7
@Macindows 是的,根据 https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-README.md(搜索“jq”)所述。 - Bjorn Lu

2

我曾经使用过这个方法从JSON数据中获取值。希望这能帮到你。

  - name: fetch the json value
    run: |
         githubjson=`cat $GITHUB_EVENT_PATH`
         echo $githubjson
         number=`echo $(jq -r '.number' <<< "$githubjson")`
         PRTitle=`echo $(jq -r '.pull_request.title' <<< "$githubjson")`
         PRUrl=`echo $(jq -r '.pull_request.html_url' <<< "$githubjson")`
         PRBody=`echo $(jq -r '.pull_request.body' <<< "$githubjson")`

2

简而言之

如果您:

  1. 有一个多行的JSON文件
  2. 正在使用自托管服务器上的GitHub-Actions
  3. 需要读取JSON文件以决定要在哪个自托管服务器上执行作业。
  4. 试图在多个作业之间共享JSON文件的内容。

代码片段在结尾处。

--

我有一个相对复杂的情况,我们使用了几个自托管的 GitHub runner。我需要从一个大型配置 JSON 文件中读取一个字段,以决定其余作业应在哪个平台上运行。

因此,下面的代码从名为 configure 的作业开始,该作业从存储库中的 config.json 文件中读取并将其设置为输出,依赖于此的下一个作业可以从输出中读取。

我尝试了这里和this post中的大多数答案,并结合了有效的答案,所以感谢所有这些人的评论。

jobs:
  configure:
    runs-on: ubuntu-latest # at first we still don't know which self-hosted server, so we just use ubuntu latest and read the JSON file
    outputs: # here we use the outputs from steps, and set outputs for the job `configure`
      config: ${{ steps.read-json.outputs.config }}
      platform: ${{ steps.get-attribute.outputs.platform }}
    steps:
      - name: Checkout to repository
        uses: actions/checkout@v3  
      - name: Read JSON file # this puts the whole JSON file in the read-json step output
        id: read-json
        run: | # to read multi-line JSON file and not bother with escaping
          echo "config<<EOF" >> $GITHUB_OUTPUT
          cat ./config.json >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
      
      - name: Add platform in output # for simpler use, you can add a single field in the output as well.
        id: read-attribute
        run: echo "platform=${{fromJson(steps.read-json.outputs.config).platform}}" >> "$GITHUB_OUTPUT"

  job2:
    needs: configure
    runs-on: ${{needs.configure.outputs.platform}}

    steps:
      - name: Log JSON file
        run: echo "${{needs.configure.outputs.config}}"
      - name: Log an attribute in JSON file
        run: echo "${{fromJson(needs.configure.outputs.config).attribute}}"
      

0

使用PowerShell:

- name: Read json
  id: read-json
  shell: pwsh
  run: |
    $json = Get-Content yourfile.json | ConvertFrom-Json
    echo "::set-output name=prop::$(echo $json.prop)"

- run: echo ${{ steps.read-json.outputs.prop}}

0

set-output 和 save-state 已被弃用。从2023年6月1日开始,通过stdout使用 save-state 或 set-output 命令的工作流将会失败并显示错误。阅读更多


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接