I am querying the github api and then using jq to parse some values from the result
- uses: octokit/[email protected]
id: get_in_progress_workflow_run
with:
route: GET /repos/myorg/myrepo/actions/runs?page=1&per_page=20
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
- name: Get waiting pull_request_id
id: get_pr_id
run: |
prId="$(echo '${{ steps.get_in_progress_workflow_run.outputs.data }}' | jq '.workflow_runs[] | first(select(.status=="in_progress")) | .pull_requests[0] | .number')";
echo "prId=$prId" >> "$GITHUB_OUTPUT";
This works fine unless the json result from the first step contains a closing parenthesis. When this happens the command substitution get's closed and I get an error about the next line of json being an unrecognized command.
line 1055: timestamp:: command not found
and line 1055
"head_commit": {
"id": "67fb50d15527690eesasdaddc4425fdda5d4e1eba8",
"tree_id": "37df61a25863dce0e3aec7a61df928f53ca64235",
"message": "message with a )",
"timestamp": "2023-01-05T20:27:05Z",
Is there any way to avoid this? I have tried stripping out the ) but I find that no matter how I try to print json from the github context into bash it errors out before I can do anything with it. And there doesn't appear to be a way to do string substitution from the github context.
For instance even just assigning the string to a variable fails with the same error
- name: Get waiting pull_request_id
id: get_pr_id
run: |
json='${{ steps.get_in_progress_workflow_run.outputs.data }}';
fails with
syntax error near unexpected token `)'
CodePudding user response:
${{ .. }}
does string interpolation before the shell gets to see anything, so any special character in there can mess up your shell script. It's also a vector for shell injection.
To fix both, set the value in the environment first, and then reference it:
- name: Get waiting pull_request_id
id: get_pr_id
env:
data: ${{ steps.get_in_progress_workflow_run.outputs.data }}
run: |
prId="$(echo "$data" | jq '
.workflow_runs[]
| first(select(.status=="in_progress"))
| .pull_requests[0].number
')"
echo "prId=$prId" >> "$GITHUB_OUTPUT"
Alternatively, you can use the GitHub CLI to make the request without an additional action, and use the --jq
parameter instead of stand-alone jq:
- name: Get waiting pull_request_id
id: get_pr_id
env:
GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }}
run: |
id=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs" \
--method GET \
--raw-field per_page=20 \
--jq '
.workflow_runs[]
| first(select(.status=="in_progress"))
| .pull_requests[0].number
')
echo "prId=$id" >> "$GITHUB_OUTPUT"