@@ -129,18 +129,22 @@ jobs:
129129
130130 # Fetch the Copilot setup tree from Cratis/AI once; reused for every repo.
131131 ai_copilot_files=""
132- ai_tree_raw=$(gh api "repos/Cratis/AI/git/trees/main?recursive=1" 2>/dev/null || true)
132+ ai_tree_error=$(mktemp)
133+ ai_tree_raw=$(gh api "repos/Cratis/AI/git/trees/main?recursive=1" 2>"$ai_tree_error" || true)
133134 if [ -n "$ai_tree_raw" ]; then
134135 ai_copilot_files=$(echo "$ai_tree_raw" | jq -c \
135136 '[.tree[] | select(.type == "blob") |
136137 select(.path | test("^\\.github/(copilot-instructions\\.md$|instructions/|agents/|skills/|prompts/)")) |
137138 {path: .path, sha: .sha}]' 2>/dev/null || true)
138139 fi
139140 if [ -z "$ai_copilot_files" ] || [ "$ai_copilot_files" = "[]" ]; then
141+ ai_tree_api_error=$(cat "$ai_tree_error" 2>/dev/null || true)
140142 echo "⚠ No Copilot setup files found in Cratis/AI; second commit will be skipped"
143+ [ -n "$ai_tree_api_error" ] && echo " API error: $ai_tree_api_error"
141144 else
142145 echo "✓ Found $(echo "$ai_copilot_files" | jq 'length') Copilot setup file(s) in Cratis/AI"
143146 fi
147+ rm -f "$ai_tree_error"
144148
145149 echo "$repos" | jq -r '.[]' | while read -r repo; do
146150 # Skip this repository (Workflows) — it holds the reusable workflows
@@ -154,39 +158,59 @@ jobs:
154158 # ----------------------------------------------------------------
155159 # 1. Get default branch and HEAD SHA
156160 # ----------------------------------------------------------------
161+ repo_info_error=$(mktemp)
157162 default_branch=$(gh api "repos/Cratis/$repo" \
158- --jq '.default_branch' 2>/dev/null || true)
163+ --jq '.default_branch' 2>"$repo_info_error" || true)
159164 if [ -z "$default_branch" ]; then
165+ repo_info_api_error=$(cat "$repo_info_error" 2>/dev/null || true)
160166 echo " ⚠ Could not get default branch for $repo, skipping"
167+ [ -n "$repo_info_api_error" ] && echo " API error: $repo_info_api_error"
168+ rm -f "$repo_info_error"
161169 continue
162170 fi
171+ rm -f "$repo_info_error"
163172
173+ head_sha_error=$(mktemp)
164174 head_sha=$(gh api "repos/Cratis/$repo/git/ref/heads/$default_branch" \
165- --jq '.object.sha' 2>/dev/null || true)
175+ --jq '.object.sha' 2>"$head_sha_error" || true)
166176 if [ -z "$head_sha" ]; then
177+ head_sha_api_error=$(cat "$head_sha_error" 2>/dev/null || true)
167178 echo " ⚠ Could not get HEAD SHA for $repo ($default_branch branch not found), skipping"
179+ [ -n "$head_sha_api_error" ] && echo " API error: $head_sha_api_error"
180+ rm -f "$head_sha_error"
168181 continue
169182 fi
183+ rm -f "$head_sha_error"
170184
171185 # ----------------------------------------------------------------
172186 # 2. Get the commit's tree SHA
173187 # ----------------------------------------------------------------
188+ tree_sha_error=$(mktemp)
174189 tree_sha=$(gh api "repos/Cratis/$repo/git/commits/$head_sha" \
175- --jq '.tree.sha' 2>/dev/null || true)
190+ --jq '.tree.sha' 2>"$tree_sha_error" || true)
176191 if [ -z "$tree_sha" ]; then
192+ tree_sha_api_error=$(cat "$tree_sha_error" 2>/dev/null || true)
177193 echo " ⚠ Could not get tree SHA for $repo, skipping"
194+ [ -n "$tree_sha_api_error" ] && echo " API error: $tree_sha_api_error"
195+ rm -f "$tree_sha_error"
178196 continue
179197 fi
198+ rm -f "$tree_sha_error"
180199
181200 # ----------------------------------------------------------------
182201 # 3. Get the full recursive tree to find instruction files to delete
183202 # ----------------------------------------------------------------
203+ subtree_error=$(mktemp)
184204 subtree=$(gh api "repos/Cratis/$repo/git/trees/$tree_sha?recursive=1" \
185- 2>/dev/null || true)
205+ 2>"$subtree_error" || true)
186206 if [ -z "$subtree" ]; then
207+ subtree_api_error=$(cat "$subtree_error" 2>/dev/null || true)
187208 echo " ⚠ Could not get tree for $repo, skipping"
209+ [ -n "$subtree_api_error" ] && echo " API error: $subtree_api_error"
210+ rm -f "$subtree_error"
188211 continue
189212 fi
213+ rm -f "$subtree_error"
190214
191215 # ----------------------------------------------------------------
192216 # 4. Create blobs for the two workflow files
@@ -343,28 +367,38 @@ jobs:
343367 [ -z "$ai_path" ] && continue
344368
345369 # Fetch blob content from Cratis/AI (returned as base64 by the API)
370+ ai_blob_error=$(mktemp)
346371 ai_blob_content=$(gh api "repos/Cratis/AI/git/blobs/$ai_sha" \
347- --jq '.content' 2>/dev/null || true)
372+ --jq '.content' 2>"$ai_blob_error" || true)
348373
349374 if [ -z "$ai_blob_content" ]; then
375+ ai_blob_api_error=$(cat "$ai_blob_error" 2>/dev/null || true)
350376 echo " ⚠ Could not fetch blob for $ai_path from Cratis/AI; skipping second commit"
377+ [ -n "$ai_blob_api_error" ] && echo " API error: $ai_blob_api_error"
378+ rm -f "$ai_blob_error"
351379 ai_copy_failed=true
352380 break
353381 fi
382+ rm -f "$ai_blob_error"
354383
355384 # Strip embedded newlines that the API inserts into base64 output
356385 clean_ai_b64=$(echo "$ai_blob_content" | tr -d '\n')
357386
387+ target_blob_error=$(mktemp)
358388 target_blob_sha=$(gh api -X POST "repos/Cratis/$repo/git/blobs" \
359389 -f "content=$clean_ai_b64" \
360390 -f encoding=base64 \
361- --jq '.sha' 2>/dev/null || true)
391+ --jq '.sha' 2>"$target_blob_error" || true)
362392
363393 if [ -z "$target_blob_sha" ]; then
394+ target_blob_api_error=$(cat "$target_blob_error" 2>/dev/null || true)
364395 echo " ⚠ Could not create blob for $ai_path in $repo; skipping second commit"
396+ [ -n "$target_blob_api_error" ] && echo " API error: $target_blob_api_error"
397+ rm -f "$target_blob_error"
365398 ai_copy_failed=true
366399 break
367400 fi
401+ rm -f "$target_blob_error"
368402
369403 ai_second_tree_json=$(echo "$ai_second_tree_json" | jq \
370404 --arg p "$ai_path" \
@@ -373,28 +407,36 @@ jobs:
373407 done <<< "$(echo "$ai_copilot_files" | jq -r '.[] | .path + " " + .sha' 2>/dev/null || true)"
374408
375409 if [ "$ai_copy_failed" = "false" ]; then
410+ ai_second_tree_error=$(mktemp)
376411 ai_second_tree_sha=$(echo "$ai_second_tree_json" | \
377412 gh api -X POST "repos/Cratis/$repo/git/trees" \
378- --input - --jq '.sha' 2>/dev/null || true)
413+ --input - --jq '.sha' 2>"$ai_second_tree_error" || true)
379414
380415 if [ -z "$ai_second_tree_sha" ]; then
416+ ai_second_tree_api_error=$(cat "$ai_second_tree_error" 2>/dev/null || true)
381417 echo " ⚠ Could not create second tree for $repo; branch will use first commit only"
418+ [ -n "$ai_second_tree_api_error" ] && echo " API error: $ai_second_tree_api_error"
382419 else
420+ ai_second_commit_error=$(mktemp)
383421 ai_second_commit_sha=$(jq -n \
384422 --arg msg "Add initial Copilot setup from Cratis/AI" \
385423 --arg tree "$ai_second_tree_sha" \
386424 --arg parent "$new_commit_sha" \
387425 '{"message": $msg, "tree": $tree, "parents": [$parent]}' | \
388426 gh api -X POST "repos/Cratis/$repo/git/commits" \
389- --input - --jq '.sha' 2>/dev/null || true)
427+ --input - --jq '.sha' 2>"$ai_second_commit_error" || true)
390428
391429 if [ -z "$ai_second_commit_sha" ]; then
430+ ai_second_commit_api_error=$(cat "$ai_second_commit_error" 2>/dev/null || true)
392431 echo " ⚠ Could not create second commit for $repo; branch will use first commit only"
432+ [ -n "$ai_second_commit_api_error" ] && echo " API error: $ai_second_commit_api_error"
393433 else
394434 echo " ✓ Added Copilot setup from Cratis/AI (second commit)"
395435 new_commit_sha="$ai_second_commit_sha"
396436 fi
437+ rm -f "$ai_second_commit_error"
397438 fi
439+ rm -f "$ai_second_tree_error"
398440 fi
399441 fi
400442
0 commit comments