Skip to content

Commit f085651

Browse files
mhuckapavoljuhas
andauthored
Improve reporting of errors & efficiency of pr-size-labeler (#7288)
* Surface curl errors Errors in the invocation of `curl` were not being reported. Added `-f` flag to `curl`, return status checking, and printing the response body in case of errors. * Use echo, not return * Adjust style of variable references to match existing code * Fix a couple of mistakes and improve DRYness - `cat` should have been `echo` - remove debugging setting - refactor a few lines in api_call() * Get rid of token parameter for workflow_dispatch I never seem to need it. * Add option to set Bash tracing This approach is a simple way to debug all shell scripts and commands. * Speed up git checkouts by making them sparse * Clean up temporary files created in jq_stdin And make sure it still returns the jq status code. * Rewrite api_call to output response from the server when call fails Write error response to stderr as stdout may be captured by the caller. Use `cat` for outputting response as `echo` may translate escape sequences. Make sure api_call returns the curl status code. * Terminate early if api_call returns error status Avoid using `cmd <<<"$(api_call args)"` expressions which ignore `api_call` failure. * Do not discard stderr from api_call This is where it sends diagnostics if any. * Switch to a PAT instead of GITHUB_TOKEN Once again, got bitten by the fact that adding labels to an issue doesn't work with `GITHUB_TOKEN` C.f. https://docs.github.com/en/rest/issues/labels?apiVersion=2022-11-28#add-labels-to-an-issue * Add comments to explain some non-obvious parts This is for future readers. * Take out pipe Per [review comments by @Pavol](#7288 (comment)), it is not doing what I thought it was doing. Plus, we don't really need the final output step. * Go back to using pull_request_target & GITHUB_TOKEN --------- Co-authored-by: Pavol Juhas <juhas@google.com>
1 parent 4fa82fb commit f085651

File tree

2 files changed

+42
-22
lines changed

2 files changed

+42
-22
lines changed

.github/workflows/pr-labeler.yaml

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ run-name: >-
2525
Label pull request ${{github.event.pull_request.number}} by ${{github.actor}}
2626
2727
on:
28-
pull_request:
28+
# Note: do not copy-paste this workflow with `pull_request_target` left as-is.
29+
# Its use here is a special case where security implications are understood.
30+
# Workflows should normally use `pull_request` instead.
31+
pull_request_target:
2932
types:
3033
- opened
3134
- synchronize
@@ -37,9 +40,9 @@ on:
3740
description: 'The PR number of the PR to label:'
3841
type: string
3942
required: true
40-
token:
41-
description: 'Token to use for authentication:'
42-
type: string
43+
trace:
44+
description: 'Turn on shell script debugging'
45+
type: boolean
4346

4447
# Declare default permissions as read only.
4548
permissions: read-all
@@ -55,23 +58,19 @@ jobs:
5558
pull-requests: write
5659
env:
5760
PR_NUMBER: ${{inputs.pr-number || github.event.pull_request.number}}
61+
# The next var is used by Bash. We add 'xtrace' to the options if this run
62+
# is a workflow_dispatch invocation and the user set the 'trace' option.
63+
SHELLOPTS: ${{inputs.trace && 'xtrace' || '' }}
5864
steps:
5965
- name: Check out a copy of the git repository
6066
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
67+
with:
68+
sparse-checkout: |
69+
./dev_tools/ci/size-labeler.sh
6170
6271
- name: Label the PR with a size label
6372
id: label
6473
continue-on-error: true
6574
env:
66-
GITHUB_TOKEN: ${{inputs.token || github.token}}
67-
run: ./dev_tools/ci/size-labeler.sh |& tee action.out
68-
69-
- name: Detect and report errors in labeler action
70-
if: steps.label.outcome == 'failure' || steps.label.outcome == 'error'
71-
run: |
72-
{
73-
echo "<h4>‼️ Failed to label PR ${PR_NUMBER}</h4>"
74-
echo "<pre>"
75-
cat action.out
76-
echo "</pre>"
77-
} >> "$GITHUB_STEP_SUMMARY"
75+
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
76+
run: ./dev_tools/ci/size-labeler.sh

dev_tools/ci/size-labeler.sh

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,12 @@ function jq_stdin() {
5959
local infile
6060
infile="$(mktemp)"
6161
readonly infile
62+
local jq_status=0
6263

6364
cat >"${infile}"
64-
jq_file "$@" "${infile}"
65+
jq_file "$@" "${infile}" || jq_status="${?}"
66+
rm "${infile}"
67+
return "${jq_status}"
6568
}
6669

6770
function jq_file() {
@@ -81,22 +84,38 @@ function jq_file() {
8184
function api_call() {
8285
local -r endpoint="${1// /%20}" # love that our label names have spaces...
8386
local -r uri="https://api.github.com/repos/${GITHUB_REPOSITORY}"
87+
local response
88+
local curl_status=0
8489
info "Calling: ${uri}/${endpoint}"
85-
curl -sSL \
90+
response="$(curl -sSL \
91+
--fail-with-body \
92+
--connect-timeout 10 --max-time 20 \
8693
-H "Authorization: token ${GITHUB_TOKEN}" \
8794
-H "Accept: application/vnd.github.v3.json" \
8895
-H "X-GitHub-Api-Version:2022-11-28" \
8996
-H "Content-Type: application/json" \
9097
"${@:2}" \
9198
"${uri}/${endpoint}"
99+
)" || curl_status="${?}"
100+
if [[ -n "${response}" ]]; then
101+
cat <<<"${response}"
102+
fi
103+
if (( curl_status )); then
104+
error "GitHub API call failed (curl exit $curl_status) for ${uri}/${endpoint}"
105+
error "Response body:"
106+
cat >&2 <<<"${response}"
107+
fi
108+
return "${curl_status}"
92109
}
93110

94111
function compute_changes() {
95112
local -r pr="$1"
96113

114+
local response
97115
local change_info
98116
local -r keys_filter='with_entries(select([.key] | inside(["changes", "filename"])))'
99-
change_info="$(jq_stdin "map(${keys_filter})" <<<"$(api_call "pulls/${pr}/files")")"
117+
response="$(api_call "pulls/${pr}/files")"
118+
change_info="$(jq_stdin "map(${keys_filter})" <<<"${response}")"
100119

101120
local files total_changes
102121
readarray -t files < <(jq_stdin -c '.[]' <<<"${change_info}")
@@ -131,8 +150,10 @@ function get_size_label() {
131150
function prune_stale_labels() {
132151
local -r pr="$1"
133152
local -r size_label="$2"
153+
local response
134154
local existing_labels
135-
existing_labels="$(jq_stdin -r '.labels[] | .name' <<<"$(api_call "pulls/${pr}")")"
155+
response="$(api_call "pulls/${pr}")"
156+
existing_labels="$(jq_stdin -r '.labels[] | .name' <<<"${response}")"
136157
readarray -t existing_labels <<<"${existing_labels}"
137158

138159
local correctly_labeled=false
@@ -147,7 +168,7 @@ function prune_stale_labels() {
147168
# If there is another size label, we need to remove it
148169
if [[ -v "LIMITS[${label}]" ]]; then
149170
info "Label '${label}' is stale, removing it."
150-
api_call "issues/${pr}/labels/${label}" -X DELETE &>/dev/null
171+
api_call "issues/${pr}/labels/${label}" -X DELETE >/dev/null
151172
continue
152173
fi
153174
info "Label '${label}' is unknown, leaving it."
@@ -194,7 +215,7 @@ function main() {
194215
correctly_labeled="$(prune_stale_labels "$PR_NUMBER" "${size_label}")"
195216

196217
if [[ "${correctly_labeled}" != true ]]; then
197-
api_call "issues/$PR_NUMBER/labels" -X POST -d "{\"labels\":[\"${size_label}\"]}" &>/dev/null
218+
api_call "issues/$PR_NUMBER/labels" -X POST -d "{\"labels\":[\"${size_label}\"]}" >/dev/null
198219
info "Added label '${size_label}'"
199220
fi
200221
}

0 commit comments

Comments
 (0)