githubgithub-actionsgithub-cli

How can I store the output of a jq process to a github cli environment variable


I have a jq process that looks at the values of a JSON file, checks a few things, and then determines if the current object is available to perform something against. The problem I have right now is that I can get it to go through all of the items, but when it stores the "available" elements to my variable, it stores them as a , comma separated list, but it won't store to my GitHub CLI Environment variable.

Here is what I have for my GitHub job:

      - name: Process Pull Requests
        id: process-prs
        run: |
          CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
          echo "Current Time: $CURRENT_TIME"
          
          # Process each PR
          READY_FOR_RELEASE_PRs=$(
            jq -c '.' pr_list.json | while read -r pr; do
              PR_NUMBER=$(echo "$pr" | jq -r '.number')
              UPDATED_AT=$(echo "$pr" | jq -r '.updatedAt')
  
              # Check if the PR was updated more than an hour ago
              UPDATED_AT_TIMESTAMP=$(date -d "$UPDATED_AT" +%s)
              CURRENT_TIMESTAMP=$(date -u +%s)
              DIFF_IN_SECS=$((CURRENT_TIMESTAMP - UPDATED_AT_TIMESTAMP))
  
              if [ "$DIFF_IN_SECS" -lt 3600 ]; then
                continue
              fi
            
              # Get our merge state status so we know if we can apply tags to it.
              REVIEW_DECISION=$(gh pr view "$PR_NUMBER" --json reviewDecision --jq .reviewDecision)
              # echo "Review Decision: $REVIEW_DECISION"
            
              # Check to make sure that the PR isn't blocked from being merged.
              if [ "$REVIEW_DECISION" = "APPROVED" ]; then
                # echo "PR #$PR_NUMBER meets criteria for 'Ready for Release'."
                # prs+=("$PR_NUMBER")
                # echo "Ready for Release PRs Array: ${prs[@]}"
                # echo "READY_PRS=${READY_PRS}${READY_PRS:+,}$PR_NUMBER" >> $GITHUB_ENV
                echo "$PR_NUMBER,"
              fi
            done
          )

          # Output the list of PRs ready for release
          echo "Ready for Release PRs: $READY_FOR_RELEASE_PRs"
          echo "ready_prs=${READY_FOR_RELEASE_PRs[@]}" >> $GITHUB_ENV

I have tried several things, all that I can't quite remember, but I'm hoping to achieve either a) an array of elements I can loop through in my next part of the job; or b) a comma-separated set of values. Here is the next step in the process:

      - name: Add "Ready for Release" Label
        if: ${{ env.ready_prs != '' }}
        run: |
          echo "Ready for Release PRs: ${{ env.ready_prs }}"
          for PR_NUMBER in ${{ env.ready_prs }}; do
            echo "Adding 'Ready for Release' label to PR #$PR_NUMBER"
          done

--- UPDATE ---

I have updated the code to look at the right variables, since the first one was mistyped. Here is what I am getting:

Ready for Release PRs: 3307,
3176,
Error: Unable to process file command 'env' successfully.
Error: Invalid format '3176,'

So, for the result I am getting, it is

3307,
3176,

What I am expecting to get would be

3307,3306

These are pull request ID's that I need to parse through in the next part of the job.


Solution

  • Change:

    echo "$PR_NUMBER,"
    

    to

    echo -n "$PR_NUMBER,"
    

    to not add that newline at the end. That'll make it one single line instead of a multiline one. That should work for your use case. But, you need to take care of that trailing comma. I believe you can handle that easily.

    Apart from that, the step where you're processing doesn't seem to handle a CSV value. You need to update that as well.

    However, this can be done with gh and jq only.

    Here's an example with CSV (live):

    gh pr list \
      --json number,updatedAt,reviewDecision \
      --jq 'map(select(now - (.updatedAt | fromdate) > 3600 and .reviewDecision == "APPROVED") | .number) | @csv'
    

    For this sample JSON:

    [
      {
        "number": 357,
        "reviewDecision": "APPROVED",
        "updatedAt": "2025-01-14T23:26:30Z"
      },
      {
        "number": 354,
        "reviewDecision": "",
        "updatedAt": "2024-12-20T22:43:01Z"
      },
      {
        "number": 342,
        "reviewDecision": "",
        "updatedAt": "2025-01-06T04:35:49Z"
      },
      {
        "number": 341,
        "reviewDecision": "",
        "updatedAt": "2024-12-19T07:36:12Z"
      },
      {
        "number": 336,
        "reviewDecision": "",
        "updatedAt": "2024-12-20T15:25:57Z"
      },
      {
        "number": 283,
        "reviewDecision": "",
        "updatedAt": "2024-11-12T13:49:23Z"
      },
      {
        "number": 263,
        "reviewDecision": "APPROVED",
        "updatedAt": "2025-01-14T09:51:00Z"
      }
    ]
    

    the output is:

    "357,263"
    

    For the loop, you may use space-separated values i.e. use join(" ") instead of @csv:

    gh pr list \
      --json number,updatedAt,reviewDecision \
      --jq 'map(select(now - (.updatedAt | fromdate) > 3600 and .reviewDecision == "APPROVED") | .number) | join(" ")'
    

    Output:

    "357 263"
    

    If need be, you may remove the surrounding double quotes with:

    tr -d '"'