Skip to content

Commit f4c928d

Browse files
committed
Improve curl error handling
- Validate response code - Provide hint for 404
1 parent bb0de12 commit f4c928d

File tree

3 files changed

+104
-8
lines changed

3 files changed

+104
-8
lines changed

.github/workflows/test.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,37 @@ jobs:
2424
with:
2525
path: action
2626

27+
- name: bad token
28+
id: bad-token
29+
uses: ./action
30+
continue-on-error: true
31+
with:
32+
repository: check-spelling/nonexistent-repository
33+
token: this is not a valid token
34+
35+
- name: token does not have access
36+
id: token-does-not-have-access
37+
uses: ./action
38+
continue-on-error: true
39+
with:
40+
repository: check-spelling/nonexistent-repository
41+
token: "${{ github.token }} "
42+
43+
- name: no such repository
44+
id: no-such-repository
45+
uses: ./action
46+
continue-on-error: true
47+
with:
48+
repository: check-spelling/nonexistent-repository
49+
50+
- name: no such release
51+
id: no-such-release
52+
uses: ./action
53+
continue-on-error: true
54+
with:
55+
repository: check-spelling/gh-program-downloader
56+
version: no-such-version
57+
2758
- name: crane
2859
id: crane
2960
uses: ./action

action.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ runs:
6464
$GITHUB_ACTION_PATH/gh-program-downloader
6565
env:
6666
GH_TOKEN: ${{ inputs.token }}
67+
token_is_not_gh_token: ${{ inputs.token != github.token && '1' || '' }}
6768
repo: ${{ inputs.repository }}
6869
destination: ${{ inputs.destination }}
6970
add_to_path: ${{ inputs.add-to-path }}
@@ -73,4 +74,4 @@ runs:
7374
arch: ${{ inputs.arch }}
7475
arch_re: ${{ inputs.arch-pattern }}
7576
file_re: ${{ inputs.file-re }}
76-
trace: ${{ inputs.trace }}
77+
trace: ${{ inputs.trace || (github.run_attempt > 1 && '1' || '') }}

gh-program-downloader

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,44 @@
22
set -e
33
releases=$(mktemp)
44

5-
maybe_trace() {
5+
setup() {
66
if [ -n "$trace" ]; then
77
set -x
88
fi
9+
b='`'
10+
headers_file=$(mktemp)
911
}
1012

1113
list_releases() {
12-
releases_url="https://api.github.com/repos/$repo/releases"
14+
releases_url_base="https://api.github.com/repos/$repo/releases"
1315
if [ -n "$version" ]; then
14-
releases_url="$releases_url/tags/$version"
16+
releases_url="$releases_url_base/tags/$version"
17+
else
18+
releases_url="$releases_url_base"
19+
fi
20+
curl -D "$headers_file" -H "$AUTHORIZATION_HEADER" -q -s -L "$releases_url" -o "$releases"
21+
response_code=$(get_response_code)
22+
if [ $response_code -eq 404 ]; then
23+
if [ -n "$version" ]; then
24+
curl -D "$headers_file" -H "$AUTHORIZATION_HEADER" -q -s -L "$releases_url_base" -o "/dev/null"
25+
releases_response_code=$(get_response_code)
26+
if [ $releases_response_code -eq 404 ]; then
27+
releases_is_404=1
28+
fi
29+
else
30+
releases_is_404=1
31+
fi
32+
if [ -n "$releases_is_404" ]; then
33+
if [ -n "$token_is_not_gh_token" ]; then
34+
hint="If the repository $b $repo $b is private then the provided $b token $b does not have access to the repository."
35+
else
36+
hint="If the repository $b $repo $b is private then provide a $b token $b."
37+
fi
38+
else
39+
hint="The specified version $b $version $b of $b $repo $b is missing; either it never existed or it was deleted. Check the version and the releases page."
40+
fi
1541
fi
16-
curl -H "$AUTHORIZATION_HEADER" -q -s -L "$releases_url" -o "$releases"
42+
validate_response_code "$response_code" "$releases" "$releases_url"
1743
}
1844

1945
find_artifact() {
@@ -98,6 +124,39 @@ get_content_length() {
98124
' "$1"
99125
}
100126

127+
validate_response_code() {
128+
case "$1" in
129+
2*)
130+
return
131+
;;
132+
401)
133+
title='Bad credentials'
134+
if [ -z "$hint" ]; then
135+
hint="Either the provided $b token $b was never valid for repository $b $repo $b, it was revoked/deleted, or it expired. Try replacing it."
136+
fi
137+
;;
138+
404)
139+
title='Server reported resource not found'
140+
;;
141+
*)
142+
title=Unexpected http response code
143+
;;
144+
esac
145+
(
146+
echo "## $title ($b $1 $b)"
147+
if [ -n "$hint" ]; then
148+
echo "$hint"
149+
fi
150+
echo
151+
echo "$b $3 $b:"
152+
echo
153+
echo '```'
154+
head -c 10240 "$2"
155+
echo '```'
156+
) | tee -a "$GITHUB_STEP_SUMMARY" >&2
157+
exit 1
158+
}
159+
101160
validate_file_length() {
102161
perl -e '
103162
my $artifact=$ENV{artifact};
@@ -121,13 +180,18 @@ shasum() {
121180
' "$1"
122181
}
123182

183+
get_response_code() {
184+
perl -e '$/="\r\n\r\n"; my $code = -1; while (<>) { $_ =~ s/\n.*/\n/s; next unless m!HTTP/\S+\s+(\d+)!; $code=$1;} print $code;' "$headers_file"
185+
}
186+
124187
download_artifact() {
125188
temp_file=$(mktemp)
126-
headers_file=$(mktemp)
127189
curl -D "$headers_file" -H "$AUTHORIZATION_HEADER" -o "$temp_file" -q -s -L "$artifact"
190+
response_code=$(get_response_code)
128191
content_length=$(get_content_length "$headers_file")
129192
request_id=$(grep -i ^x-github-request-id: "$headers_file" | tail -1)
130-
echo "Downloaded $artifact - content-length: $content_length; shasum256: $(shasum "$temp_file"); $request_id"
193+
echo "Downloaded $artifact - status: $response_code; content-length: $content_length; shasum256: $(shasum "$temp_file"); $request_id"
194+
validate_response_code "$response_code" "$temp_file" "$artifact"
131195
content_length="$content_length" artifact="$artifact" temp_file="$temp_file" validate_file_length
132196

133197
echo "url=$artifact" >> "$GITHUB_OUTPUT"
@@ -224,7 +288,7 @@ maybe_extract_artifact() {
224288
fi
225289
}
226290

227-
maybe_trace
291+
setup
228292
set_up_auth
229293
list_releases
230294
select_artifact

0 commit comments

Comments
 (0)