Skip to content

Commit d38ede8

Browse files
authored
Add retry logic and logging to install-gh-aw.sh for transient API failures (#6216)
1 parent 3614bbd commit d38ede8

File tree

2 files changed

+82
-25
lines changed

2 files changed

+82
-25
lines changed

install-gh-aw.sh

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
# Script to download and install gh-aw binary for the current OS and architecture
44
# Supports: Linux, macOS (Darwin), FreeBSD, Windows (Git Bash/MSYS/Cygwin)
55
# Usage: ./install-gh-aw.sh [version]
6-
# If no version is specified, it will use the latest release
6+
# If no version is specified, it will fetch and use the latest release
7+
# Example: ./install-gh-aw.sh v1.0.0
78

89
set -e # Exit on any error
910

@@ -109,48 +110,72 @@ print_info "Detected OS: $OS -> $OS_NAME"
109110
print_info "Detected architecture: $ARCH -> $ARCH_NAME"
110111
print_info "Platform: $PLATFORM"
111112

112-
# Function to fetch release data with fallback for invalid token
113+
# Function to fetch release data with fallback for invalid token and retry logic
113114
fetch_release_data() {
114115
local url=$1
116+
local max_retries=3
117+
local retry_delay=2
115118
local use_auth=false
116-
local curl_args=("-s" "-f")
117119

118120
# Try with authentication if GH_TOKEN is set
119121
if [ -n "$GH_TOKEN" ]; then
120122
use_auth=true
121-
curl_args+=("-H" "Authorization: Bearer $GH_TOKEN")
122123
fi
123124

124-
# Make the API call
125-
local response
126-
response=$(curl "${curl_args[@]}" "$url" 2>/dev/null)
127-
local exit_code=$?
128-
129-
# If the call failed and we used authentication, try again without it
130-
if [ $exit_code -ne 0 ] && [ "$use_auth" = true ]; then
131-
print_warning "API call with GH_TOKEN failed. Retrying without authentication..."
132-
print_warning "Your GH_TOKEN may be incompatible (typically SSO) with this request."
133-
response=$(curl -s -f "$url" 2>/dev/null)
134-
exit_code=$?
135-
fi
136-
137-
if [ $exit_code -ne 0 ]; then
138-
return 1
139-
fi
125+
# Retry loop
126+
for attempt in $(seq 1 $max_retries); do
127+
local curl_args=("-s" "-f")
128+
129+
# Add auth header if using authentication
130+
if [ "$use_auth" = true ]; then
131+
curl_args+=("-H" "Authorization: Bearer $GH_TOKEN")
132+
fi
133+
134+
print_info "Fetching release data (attempt $attempt/$max_retries)..." >&2
135+
136+
# Make the API call
137+
local response
138+
response=$(curl "${curl_args[@]}" "$url" 2>/dev/null)
139+
local exit_code=$?
140+
141+
# Success
142+
if [ $exit_code -eq 0 ] && [ -n "$response" ]; then
143+
echo "$response"
144+
return 0
145+
fi
146+
147+
# If this was the first attempt with auth and it failed, try without auth
148+
if [ "$attempt" -eq 1 ] && [ "$use_auth" = true ]; then
149+
print_warning "API call with GH_TOKEN failed. Retrying without authentication..." >&2
150+
print_warning "Your GH_TOKEN may be incompatible (typically SSO) with this request." >&2
151+
use_auth=false
152+
# Don't count this as a retry attempt, just switch auth mode
153+
continue
154+
fi
155+
156+
# If we haven't exhausted retries, wait and try again
157+
if [ "$attempt" -lt "$max_retries" ]; then
158+
print_warning "Fetch attempt $attempt failed (exit code: $exit_code). Retrying in ${retry_delay}s..." >&2
159+
sleep $retry_delay
160+
retry_delay=$((retry_delay * 2))
161+
else
162+
print_error "Failed to fetch release data after $max_retries attempts" >&2
163+
fi
164+
done
140165

141-
echo "$response"
142-
return 0
166+
return 1
143167
}
144168

145169
# Get version (use provided version or fetch latest)
146170
VERSION=${1:-""}
147171
REPO="githubnext/gh-aw"
148172

149173
if [ -z "$VERSION" ]; then
150-
print_info "Fetching latest release information..."
174+
print_info "No version specified, fetching latest release information from GitHub..."
151175

152176
if ! LATEST_RELEASE=$(fetch_release_data "https://api.github.com/repos/$REPO/releases/latest"); then
153-
print_error "Failed to fetch latest release information"
177+
print_error "Failed to fetch latest release information from GitHub API"
178+
print_info "You can specify a version directly: ./install-gh-aw.sh v1.0.0"
154179
exit 1
155180
fi
156181

@@ -206,7 +231,7 @@ for attempt in $(seq 1 $MAX_RETRIES); do
206231
print_success "Binary downloaded successfully"
207232
break
208233
else
209-
if [ $attempt -eq $MAX_RETRIES ]; then
234+
if [ "$attempt" -eq "$MAX_RETRIES" ]; then
210235
print_error "Failed to download binary from $DOWNLOAD_URL after $MAX_RETRIES attempts"
211236
print_info "Please check if the version and platform combination exists in the releases."
212237
exit 1

scripts/test-install-script.sh

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,38 @@ else
232232
exit 1
233233
fi
234234

235+
# Verify the function has retry logic with max_retries
236+
if grep -q 'local max_retries=3' "$PROJECT_ROOT/install-gh-aw.sh"; then
237+
echo " ✓ PASS: Function has max_retries=3 variable"
238+
else
239+
echo " ✗ FAIL: Function does not have max_retries variable"
240+
exit 1
241+
fi
242+
243+
# Verify the function has retry loop
244+
if grep -q 'for attempt in $(seq 1 $max_retries)' "$PROJECT_ROOT/install-gh-aw.sh"; then
245+
echo " ✓ PASS: Function has retry loop"
246+
else
247+
echo " ✗ FAIL: Function does not have retry loop"
248+
exit 1
249+
fi
250+
251+
# Verify the function logs fetch attempts
252+
if grep -q 'Fetching release data (attempt' "$PROJECT_ROOT/install-gh-aw.sh"; then
253+
echo " ✓ PASS: Function logs fetch attempts"
254+
else
255+
echo " ✗ FAIL: Function does not log fetch attempts"
256+
exit 1
257+
fi
258+
259+
# Verify the function has exponential backoff for retries
260+
if grep -q 'retry_delay=\$((retry_delay \* 2))' "$PROJECT_ROOT/install-gh-aw.sh"; then
261+
echo " ✓ PASS: Function has exponential backoff for retries"
262+
else
263+
echo " ✗ FAIL: Function does not have exponential backoff"
264+
exit 1
265+
fi
266+
235267
# Test 9: Verify retry logic for downloads
236268
echo ""
237269
echo "Test 9: Verify download retry logic"

0 commit comments

Comments
 (0)