Skip to content

Commit 326d74b

Browse files
authored
Merge pull request #375 from ublue-os/copilot/fix-9401fe32-0925-4340-ab7f-e5d4079ba9e3
Implement comprehensive GitHub API error handling for changelog synchronization
2 parents e45a93a + c2a6e51 commit 326d74b

File tree

5 files changed

+960
-220
lines changed

5 files changed

+960
-220
lines changed

.github/workflows/sync-bluefin-releases.yml

Lines changed: 155 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -28,89 +28,115 @@ jobs:
2828
run: |
2929
echo "Fetching latest releases from all Bluefin repositories..."
3030
31+
# Source GitHub API utilities for enhanced error handling
32+
source scripts/github_api_utils.sh
33+
34+
# Set environment variables for enhanced logging
35+
export VERBOSE_MODE=true
36+
37+
# Perform API health check first
38+
if ! api_health_check; then
39+
log_error "GitHub API health check failed. Cannot proceed."
40+
exit 1
41+
fi
42+
3143
# Initialize status tracking
3244
REPOSITORIES_ACCESSED=""
3345
REPOSITORIES_FAILED=""
3446
3547
# Fetch all releases from ublue-os/bluefin to find latest stable and GTS
36-
echo "Fetching all releases from ublue-os/bluefin..."
37-
BLUEFIN_RELEASES=$(curl -s -H "Accept: application/vnd.github.v3+json" \
38-
"https://api.github.com/repos/ublue-os/bluefin/releases")
39-
40-
# Check if request was successful
41-
if echo "$BLUEFIN_RELEASES" | jq -e 'if type == "object" and has("message") then .message else empty end' > /dev/null; then
42-
echo "Warning: Failed to fetch bluefin releases"
43-
echo "API Response: $BLUEFIN_RELEASES"
48+
log_info "Fetching all releases from ublue-os/bluefin..."
49+
50+
if ! validate_repository_access "ublue-os/bluefin"; then
51+
log_error "Cannot access ublue-os/bluefin repository"
4452
REPOSITORIES_FAILED="$REPOSITORIES_FAILED ublue-os/bluefin"
53+
suggest_error_resolution $? "ublue-os/bluefin"
4554
else
4655
REPOSITORIES_ACCESSED="$REPOSITORIES_ACCESSED ublue-os/bluefin"
4756
48-
# Find latest stable release (tag contains 'stable')
49-
BLUEFIN_STABLE_RELEASE=$(echo "$BLUEFIN_RELEASES" | jq -r '[.[] | select(.tag_name | test("stable")) | select(.prerelease == false)] | .[0]')
50-
if [[ "$BLUEFIN_STABLE_RELEASE" != "null" ]]; then
51-
BLUEFIN_STABLE_TAG=$(echo "$BLUEFIN_STABLE_RELEASE" | jq -r '.tag_name')
52-
BLUEFIN_STABLE_URL=$(echo "$BLUEFIN_STABLE_RELEASE" | jq -r '.html_url')
53-
BLUEFIN_STABLE_DATE=$(echo "$BLUEFIN_STABLE_RELEASE" | jq -r '.published_at')
54-
55-
echo "Latest stable release found: $BLUEFIN_STABLE_TAG"
56-
echo "Stable release URL: $BLUEFIN_STABLE_URL"
57+
# Fetch releases with enhanced error handling
58+
if BLUEFIN_RELEASES=$(github_api_call "repos/ublue-os/bluefin/releases"); then
59+
log_info "Successfully fetched releases from ublue-os/bluefin"
5760
58-
# Save stable release data
59-
echo "bluefin_stable_tag=$BLUEFIN_STABLE_TAG" >> $GITHUB_OUTPUT
60-
echo "bluefin_stable_url=$BLUEFIN_STABLE_URL" >> $GITHUB_OUTPUT
61-
echo "bluefin_stable_date=$BLUEFIN_STABLE_DATE" >> $GITHUB_OUTPUT
62-
echo "bluefin_stable_available=true" >> $GITHUB_OUTPUT
63-
else
64-
echo "No stable releases found"
65-
echo "bluefin_stable_available=false" >> $GITHUB_OUTPUT
66-
fi
67-
68-
# Find latest GTS release (tag contains 'gts')
69-
BLUEFIN_GTS_RELEASE=$(echo "$BLUEFIN_RELEASES" | jq -r '[.[] | select(.tag_name | test("gts"))] | .[0]')
70-
if [[ "$BLUEFIN_GTS_RELEASE" != "null" ]]; then
71-
BLUEFIN_GTS_TAG=$(echo "$BLUEFIN_GTS_RELEASE" | jq -r '.tag_name')
72-
BLUEFIN_GTS_URL=$(echo "$BLUEFIN_GTS_RELEASE" | jq -r '.html_url')
73-
BLUEFIN_GTS_DATE=$(echo "$BLUEFIN_GTS_RELEASE" | jq -r '.published_at')
74-
75-
echo "Latest GTS release found: $BLUEFIN_GTS_TAG"
76-
echo "GTS release URL: $BLUEFIN_GTS_URL"
61+
# Find latest stable release (tag contains 'stable')
62+
BLUEFIN_STABLE_RELEASE=$(echo "$BLUEFIN_RELEASES" | jq -r '[.[] | select(.tag_name | test("stable")) | select(.prerelease == false)] | .[0]')
63+
if [[ "$BLUEFIN_STABLE_RELEASE" != "null" ]]; then
64+
BLUEFIN_STABLE_TAG=$(echo "$BLUEFIN_STABLE_RELEASE" | jq -r '.tag_name')
65+
BLUEFIN_STABLE_URL=$(echo "$BLUEFIN_STABLE_RELEASE" | jq -r '.html_url')
66+
BLUEFIN_STABLE_DATE=$(echo "$BLUEFIN_STABLE_RELEASE" | jq -r '.published_at')
67+
68+
log_info "Latest stable release found: $BLUEFIN_STABLE_TAG"
69+
log_verbose "Stable release URL: $BLUEFIN_STABLE_URL"
70+
71+
# Save stable release data
72+
echo "bluefin_stable_tag=$BLUEFIN_STABLE_TAG" >> $GITHUB_OUTPUT
73+
echo "bluefin_stable_url=$BLUEFIN_STABLE_URL" >> $GITHUB_OUTPUT
74+
echo "bluefin_stable_date=$BLUEFIN_STABLE_DATE" >> $GITHUB_OUTPUT
75+
echo "bluefin_stable_available=true" >> $GITHUB_OUTPUT
76+
else
77+
log_warn "No stable releases found"
78+
echo "bluefin_stable_available=false" >> $GITHUB_OUTPUT
79+
fi
7780
78-
# Save GTS release data
79-
echo "bluefin_gts_tag=$BLUEFIN_GTS_TAG" >> $GITHUB_OUTPUT
80-
echo "bluefin_gts_url=$BLUEFIN_GTS_URL" >> $GITHUB_OUTPUT
81-
echo "bluefin_gts_date=$BLUEFIN_GTS_DATE" >> $GITHUB_OUTPUT
82-
echo "bluefin_gts_available=true" >> $GITHUB_OUTPUT
81+
# Find latest GTS release (tag contains 'gts')
82+
BLUEFIN_GTS_RELEASE=$(echo "$BLUEFIN_RELEASES" | jq -r '[.[] | select(.tag_name | test("gts"))] | .[0]')
83+
if [[ "$BLUEFIN_GTS_RELEASE" != "null" ]]; then
84+
BLUEFIN_GTS_TAG=$(echo "$BLUEFIN_GTS_RELEASE" | jq -r '.tag_name')
85+
BLUEFIN_GTS_URL=$(echo "$BLUEFIN_GTS_RELEASE" | jq -r '.html_url')
86+
BLUEFIN_GTS_DATE=$(echo "$BLUEFIN_GTS_RELEASE" | jq -r '.published_at')
87+
88+
log_info "Latest GTS release found: $BLUEFIN_GTS_TAG"
89+
log_verbose "GTS release URL: $BLUEFIN_GTS_URL"
90+
91+
# Save GTS release data
92+
echo "bluefin_gts_tag=$BLUEFIN_GTS_TAG" >> $GITHUB_OUTPUT
93+
echo "bluefin_gts_url=$BLUEFIN_GTS_URL" >> $GITHUB_OUTPUT
94+
echo "bluefin_gts_date=$BLUEFIN_GTS_DATE" >> $GITHUB_OUTPUT
95+
echo "bluefin_gts_available=true" >> $GITHUB_OUTPUT
96+
else
97+
log_warn "No GTS releases found"
98+
echo "bluefin_gts_available=false" >> $GITHUB_OUTPUT
99+
fi
83100
else
84-
echo "No GTS releases found"
85-
echo "bluefin_gts_available=false" >> $GITHUB_OUTPUT
101+
local exit_code=$?
102+
log_error "Failed to fetch releases from ublue-os/bluefin"
103+
REPOSITORIES_FAILED="$REPOSITORIES_FAILED ublue-os/bluefin"
104+
suggest_error_resolution $exit_code "ublue-os/bluefin"
86105
fi
87106
fi
88107
89108
# Try to fetch the latest release from ublue-os/bluefin-lts
90-
echo "Fetching latest release from ublue-os/bluefin-lts..."
91-
BLUEFIN_LTS_RELEASE=$(curl -s -H "Accept: application/vnd.github.v3+json" \
92-
"https://api.github.com/repos/ublue-os/bluefin-lts/releases/latest")
93-
94-
# Check if LTS request was successful
95-
if echo "$BLUEFIN_LTS_RELEASE" | jq -e 'if type == "object" and has("message") then .message else empty end' > /dev/null; then
96-
echo "Warning: Failed to fetch latest bluefin-lts release"
97-
echo "API Response: $BLUEFIN_LTS_RELEASE"
109+
log_info "Fetching latest release from ublue-os/bluefin-lts..."
110+
111+
if ! validate_repository_access "ublue-os/bluefin-lts"; then
112+
log_error "Cannot access ublue-os/bluefin-lts repository"
98113
REPOSITORIES_FAILED="$REPOSITORIES_FAILED ublue-os/bluefin-lts"
99114
echo "bluefin_lts_available=false" >> $GITHUB_OUTPUT
115+
suggest_error_resolution $? "ublue-os/bluefin-lts"
100116
else
101-
# Extract bluefin-lts release information
102-
BLUEFIN_LTS_TAG=$(echo "$BLUEFIN_LTS_RELEASE" | jq -r '.tag_name')
103-
BLUEFIN_LTS_URL=$(echo "$BLUEFIN_LTS_RELEASE" | jq -r '.html_url')
104-
BLUEFIN_LTS_DATE=$(echo "$BLUEFIN_LTS_RELEASE" | jq -r '.published_at')
105-
106-
echo "Latest bluefin-lts release found: $BLUEFIN_LTS_TAG"
107117
REPOSITORIES_ACCESSED="$REPOSITORIES_ACCESSED ublue-os/bluefin-lts"
108118
109-
# Save LTS release data
110-
echo "bluefin_lts_tag=$BLUEFIN_LTS_TAG" >> $GITHUB_OUTPUT
111-
echo "bluefin_lts_url=$BLUEFIN_LTS_URL" >> $GITHUB_OUTPUT
112-
echo "bluefin_lts_date=$BLUEFIN_LTS_DATE" >> $GITHUB_OUTPUT
113-
echo "bluefin_lts_available=true" >> $GITHUB_OUTPUT
119+
# Fetch latest release with enhanced error handling
120+
if BLUEFIN_LTS_RELEASE=$(github_api_call "repos/ublue-os/bluefin-lts/releases/latest"); then
121+
# Extract bluefin-lts release information
122+
BLUEFIN_LTS_TAG=$(echo "$BLUEFIN_LTS_RELEASE" | jq -r '.tag_name')
123+
BLUEFIN_LTS_URL=$(echo "$BLUEFIN_LTS_RELEASE" | jq -r '.html_url')
124+
BLUEFIN_LTS_DATE=$(echo "$BLUEFIN_LTS_RELEASE" | jq -r '.published_at')
125+
126+
log_info "Latest bluefin-lts release found: $BLUEFIN_LTS_TAG"
127+
128+
# Save LTS release data
129+
echo "bluefin_lts_tag=$BLUEFIN_LTS_TAG" >> $GITHUB_OUTPUT
130+
echo "bluefin_lts_url=$BLUEFIN_LTS_URL" >> $GITHUB_OUTPUT
131+
echo "bluefin_lts_date=$BLUEFIN_LTS_DATE" >> $GITHUB_OUTPUT
132+
echo "bluefin_lts_available=true" >> $GITHUB_OUTPUT
133+
else
134+
local exit_code=$?
135+
log_error "Failed to fetch latest bluefin-lts release"
136+
REPOSITORIES_FAILED="$REPOSITORIES_FAILED ublue-os/bluefin-lts"
137+
echo "bluefin_lts_available=false" >> $GITHUB_OUTPUT
138+
suggest_error_resolution $exit_code "ublue-os/bluefin-lts"
139+
fi
114140
fi
115141
116142
# Output summary
@@ -119,17 +145,29 @@ jobs:
119145
120146
# Check if at least one repository was accessible
121147
if [[ -z "$REPOSITORIES_ACCESSED" ]]; then
122-
echo "Error: No releases could be fetched from any repository"
148+
log_error "No releases could be fetched from any repository"
149+
log_error "All repositories failed to respond. This may be due to:"
150+
echo " • GitHub API outages or rate limiting"
151+
echo " • Authentication issues"
152+
echo " • Network connectivity problems"
153+
echo " • Repository access permissions"
154+
suggest_error_resolution $ERROR_REPOSITORY_ACCESS
123155
exit 1
124156
fi
125157
126-
echo "Repository access summary:"
127-
echo "Accessible repositories:$REPOSITORIES_ACCESSED"
128-
echo "Failed repositories:$REPOSITORIES_FAILED"
158+
log_info "Repository access summary:"
159+
log_info "✅ Accessible repositories:$REPOSITORIES_ACCESSED"
160+
if [[ -n "$REPOSITORIES_FAILED" ]]; then
161+
log_warn "❌ Failed repositories:$REPOSITORIES_FAILED"
162+
fi
129163
130164
- name: Process available releases
131165
id: process_releases
132166
run: |
167+
# Source GitHub API utilities for enhanced error handling
168+
source scripts/github_api_utils.sh
169+
export VERBOSE_MODE=true
170+
133171
# Initialize tracking
134172
FILES_CREATED=()
135173
FILES_SKIPPED=()
@@ -143,7 +181,7 @@ jobs:
143181
local release_url="$3"
144182
local release_date="$4"
145183
146-
echo "Processing release: $release_tag from $source_repo"
184+
log_info "Processing release: $release_tag from $source_repo"
147185
TOTAL_PROCESSED=$((TOTAL_PROCESSED + 1))
148186
149187
# Determine the correct author based on release type
@@ -156,42 +194,43 @@ jobs:
156194
author="bluefin-release-bot"
157195
fi
158196
159-
echo "Using author: $author for release type"
160-
161-
# Get detailed release data
162-
RELEASE_DATA=$(curl -s -H "Accept: application/vnd.github.v3+json" \
163-
"https://api.github.com/repos/$source_repo/releases/tags/$release_tag")
164-
165-
if echo "$RELEASE_DATA" | jq -e 'if type == "object" and has("message") then .message else empty end' > /dev/null; then
166-
echo "Warning: Could not fetch detailed data for $release_tag from $source_repo"
167-
PROCESSING_ERRORS+=("$source_repo:$release_tag - API access error")
168-
return 1
169-
fi
170-
171-
# Extract detailed release information
172-
RELEASE_NAME=$(echo "$RELEASE_DATA" | jq -r '.name // .tag_name')
173-
RELEASE_BODY=$(echo "$RELEASE_DATA" | jq -r '.body // ""')
174-
175-
# Save release body for processing
176-
echo "$RELEASE_BODY" > "/tmp/release_body_${source_repo//\//_}_${release_tag}.md"
177-
178-
# Process this release using existing logic from original workflow
179-
output=$(./scripts/process_single_release.sh "$source_repo" "$release_tag" "$release_url" "$release_date" "$RELEASE_NAME" "$RELEASE_BODY" "false" "$author" 2>&1)
180-
local result=$?
197+
log_verbose "Using author: $author for release type"
181198
182-
echo "$output"
183-
184-
if [[ $result -eq 0 ]]; then
185-
if echo "$output" | grep -q "SKIPPED:"; then
186-
FILES_SKIPPED+=("$source_repo:$release_tag")
187-
echo "⏭️ Skipped $release_tag (file already exists)"
188-
else
189-
FILES_CREATED+=("$source_repo:$release_tag")
190-
echo "✅ Successfully created changelog for $release_tag"
191-
fi
199+
# Get detailed release data with enhanced error handling
200+
if RELEASE_DATA=$(fetch_release_by_tag "$source_repo" "$release_tag"); then
201+
log_verbose "Successfully fetched detailed release data"
202+
203+
# Extract detailed release information
204+
RELEASE_NAME=$(echo "$RELEASE_DATA" | jq -r '.name // .tag_name')
205+
RELEASE_BODY=$(echo "$RELEASE_DATA" | jq -r '.body // ""')
206+
207+
# Save release body for processing
208+
echo "$RELEASE_BODY" > "/tmp/release_body_${source_repo//\//_}_${release_tag}.md"
209+
210+
# Process this release using existing logic
211+
output=$(./scripts/process_single_release.sh "$source_repo" "$release_tag" "$release_url" "$release_date" "$RELEASE_NAME" "$RELEASE_BODY" "false" "$author" 2>&1)
212+
local result=$?
213+
214+
echo "$output"
215+
216+
if [[ $result -eq 0 ]]; then
217+
if echo "$output" | grep -q "SKIPPED:"; then
218+
FILES_SKIPPED+=("$source_repo:$release_tag")
219+
log_info "⏭️ Skipped $release_tag (file already exists)"
220+
else
221+
FILES_CREATED+=("$source_repo:$release_tag")
222+
log_info "✅ Successfully created changelog for $release_tag"
223+
fi
224+
else
225+
PROCESSING_ERRORS+=("$source_repo:$release_tag - Processing error ($result)")
226+
log_error "❌ Error processing $release_tag (exit code: $result)"
227+
fi
192228
else
193-
PROCESSING_ERRORS+=("$source_repo:$release_tag - Processing error ($result)")
194-
echo "❌ Error processing $release_tag (exit code: $result)"
229+
local exit_code=$?
230+
log_error "Could not fetch detailed data for $release_tag from $source_repo"
231+
PROCESSING_ERRORS+=("$source_repo:$release_tag - API access error (code: $exit_code)")
232+
suggest_error_resolution $exit_code "$source_repo"
233+
return 1
195234
fi
196235
}
197236
@@ -223,7 +262,7 @@ jobs:
223262
"${{ steps.fetch_latest_releases.outputs.bluefin_lts_date }}"
224263
fi
225264
else
226-
echo "Processing single release from repository dispatch..."
265+
log_info "Processing single release from repository dispatch..."
227266
228267
# Handle repository_dispatch (single release)
229268
RELEASE_TAG="${{ github.event.client_payload.tag_name }}"
@@ -236,14 +275,10 @@ jobs:
236275
SOURCE_REPO="ublue-os/bluefin"
237276
fi
238277
239-
# For repository_dispatch, we need to get the release date
240-
RELEASE_DATA=$(curl -s -H "Accept: application/vnd.github.v3+json" \
241-
"https://api.github.com/repos/$SOURCE_REPO/releases/tags/$RELEASE_TAG")
278+
log_info "Repository dispatch for $SOURCE_REPO:$RELEASE_TAG"
242279
243-
if echo "$RELEASE_DATA" | jq -e 'if type == "object" and has("message") then .message else empty end' > /dev/null; then
244-
echo "Error: Release not found for tag $RELEASE_TAG in $SOURCE_REPO"
245-
PROCESSING_ERRORS+=("$SOURCE_REPO:$RELEASE_TAG - Release not found")
246-
else
280+
# For repository_dispatch, we need to get the release date using enhanced error handling
281+
if RELEASE_DATA=$(fetch_release_by_tag "$SOURCE_REPO" "$RELEASE_TAG"); then
247282
RELEASE_DATE=$(echo "$RELEASE_DATA" | jq -r '.published_at')
248283
249284
# Determine the correct author based on release type
@@ -256,12 +291,13 @@ jobs:
256291
AUTHOR="bluefin-release-bot"
257292
fi
258293
259-
echo "Using author: $AUTHOR for repository dispatch release"
294+
log_verbose "Using author: $AUTHOR for repository dispatch release"
260295
261-
# Call process_single_release with author parameter
296+
# Extract release details
262297
RELEASE_NAME=$(echo "$RELEASE_DATA" | jq -r '.name // .tag_name')
263298
RELEASE_BODY=$(echo "$RELEASE_DATA" | jq -r '.body // ""')
264299
300+
# Process the release
265301
output=$(./scripts/process_single_release.sh "$SOURCE_REPO" "$RELEASE_TAG" "$RELEASE_URL" "$RELEASE_DATE" "$RELEASE_NAME" "$RELEASE_BODY" "false" "$AUTHOR" 2>&1)
266302
local result=$?
267303
@@ -270,15 +306,20 @@ jobs:
270306
if [[ $result -eq 0 ]]; then
271307
if echo "$output" | grep -q "SKIPPED:"; then
272308
FILES_SKIPPED+=("$SOURCE_REPO:$RELEASE_TAG")
273-
echo "⏭️ Skipped $RELEASE_TAG (file already exists)"
309+
log_info "⏭️ Skipped $RELEASE_TAG (file already exists)"
274310
else
275311
FILES_CREATED+=("$SOURCE_REPO:$RELEASE_TAG")
276-
echo "✅ Successfully created changelog for $RELEASE_TAG"
312+
log_info "✅ Successfully created changelog for $RELEASE_TAG"
277313
fi
278314
else
279315
PROCESSING_ERRORS+=("$SOURCE_REPO:$RELEASE_TAG - Processing error ($result)")
280-
echo "❌ Error processing $RELEASE_TAG (exit code: $result)"
316+
log_error "❌ Error processing $RELEASE_TAG (exit code: $result)"
281317
fi
318+
else
319+
local exit_code=$?
320+
log_error "Release not found for tag $RELEASE_TAG in $SOURCE_REPO"
321+
PROCESSING_ERRORS+=("$SOURCE_REPO:$RELEASE_TAG - Release not found (code: $exit_code)")
322+
suggest_error_resolution $exit_code "$SOURCE_REPO"
282323
fi
283324
fi
284325

0 commit comments

Comments
 (0)