Skip to content

Commit 4a248ae

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

File tree

3 files changed

+127
-13
lines changed

3 files changed

+127
-13
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: 94 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,46 @@
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"
1519
fi
16-
curl -H "$AUTHORIZATION_HEADER" -q -s -L "$releases_url" -o "$releases"
20+
curl -D "$headers_file" -H "$AUTHORIZATION_HEADER" -q -s -L "$releases_url" -o "$releases"
21+
response_code=$(get_response_code)
22+
type=$(get_content_type "$headers_file")
23+
if [ $response_code -eq 404 ]; then
24+
if [ -n "$version" ]; then
25+
curl -D "$headers_file" -H "$AUTHORIZATION_HEADER" -q -s -L "$releases_url_base" -o "/dev/null"
26+
releases_response_code=$(get_response_code)
27+
if [ $releases_response_code -eq 404 ]; then
28+
releases_is_404=1
29+
fi
30+
else
31+
releases_is_404=1
32+
fi
33+
if [ -n "$releases_is_404" ]; then
34+
if [ -n "$token_is_not_gh_token" ]; then
35+
hint="If the repository $b $repo $b is private, then the provided $b token $b does not have access to the repository"
36+
else
37+
hint="If the repository $b $repo $b is private, then provide a $b token $b"
38+
fi
39+
hint="$hint. Otherwise, the repository either does not exist or has been deleted. Check with the repository owner for more information."
40+
else
41+
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."
42+
fi
43+
fi
44+
validate_response_code "$response_code" "$releases" "$releases_url"
1745
}
1846

1947
find_artifact() {
@@ -80,24 +108,73 @@ set_up_auth() {
80108
fi
81109
}
82110

83-
get_content_length() {
111+
get_header_value() {
84112
perl -e '
85113
my $headers_file=shift;
86-
my $length;
114+
my $value;
87115
{
88116
open(my $headers, q(<), $headers_file);
89117
local $/="\r\n";
90118
while (<$headers>) {
91119
chomp;
92-
next unless m/^content-length:\s+(\d+)$/i;
93-
$length=$1;
120+
next unless m/^$ENV{header}:\s+(.*)$/i;
121+
$value=$1;
94122
}
95123
close $headers;
96124
}
97-
print $length;
125+
print $value;
98126
' "$1"
99127
}
100128

129+
get_content_length() {
130+
header='content-length' get_header_value "$1"
131+
}
132+
133+
get_content_type() {
134+
header='content-type' get_header_value "$1"
135+
}
136+
137+
validate_response_code() {
138+
case "$1" in
139+
2*)
140+
return
141+
;;
142+
401)
143+
title='Bad credentials'
144+
if [ -z "$hint" ]; then
145+
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."
146+
fi
147+
;;
148+
404)
149+
title='Server reported resource not found'
150+
;;
151+
*)
152+
title=Unexpected http response code
153+
;;
154+
esac
155+
(
156+
echo "## $title ($b $1 $b)"
157+
if [ -n "$hint" ]; then
158+
echo "$hint"
159+
fi
160+
echo
161+
echo "$b $3 $b:"
162+
echo
163+
case "$type" in
164+
*json*)
165+
type=json;;
166+
*html*)
167+
type=html;;
168+
*)
169+
type=''
170+
esac
171+
echo '```'"$type"
172+
head -c 10240 "$2"
173+
echo '```'
174+
) | tee -a "$GITHUB_STEP_SUMMARY" >&2
175+
exit 1
176+
}
177+
101178
validate_file_length() {
102179
perl -e '
103180
my $artifact=$ENV{artifact};
@@ -121,13 +198,18 @@ shasum() {
121198
' "$1"
122199
}
123200

201+
get_response_code() {
202+
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"
203+
}
204+
124205
download_artifact() {
125206
temp_file=$(mktemp)
126-
headers_file=$(mktemp)
127207
curl -D "$headers_file" -H "$AUTHORIZATION_HEADER" -o "$temp_file" -q -s -L "$artifact"
208+
response_code=$(get_response_code)
128209
content_length=$(get_content_length "$headers_file")
129210
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"
211+
echo "Downloaded $artifact - status: $response_code; content-length: $content_length; shasum256: $(shasum "$temp_file"); $request_id"
212+
validate_response_code "$response_code" "$temp_file" "$artifact"
131213
content_length="$content_length" artifact="$artifact" temp_file="$temp_file" validate_file_length
132214

133215
echo "url=$artifact" >> "$GITHUB_OUTPUT"
@@ -224,7 +306,7 @@ maybe_extract_artifact() {
224306
fi
225307
}
226308

227-
maybe_trace
309+
setup
228310
set_up_auth
229311
list_releases
230312
select_artifact

0 commit comments

Comments
 (0)