Serialize desktop auto-releases and wait for prior Codemagic build#5438
Serialize desktop auto-releases and wait for prior Codemagic build#5438
Conversation
Greptile SummaryThis PR serializes the The overall approach is correct and addresses a real operational problem. However, there are three issues worth addressing:
Confidence Score: 3/5
Last reviewed commit: e052a35 |
| STATUS=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | ||
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .status' | head -n1 || true) | ||
| CONCLUSION=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | ||
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .conclusion' | head -n1 || true) |
There was a problem hiding this comment.
Missing --paginate may silently skip the wait
The gh api command for check-runs returns only the first page (30 items by default). If the target commit has more than 30 check runs, "Release OMI Desktop (Swift)" may not appear in the response. In that case STATUS will be empty, the [ -z "$STATUS" ] branch at line 51 fires, and the workflow exits 0 immediately — skipping the intended wait entirely and potentially creating a new tag before the previous build has finished.
Add --paginate to both calls (or pass per_page=100 as a query param) to ensure all check runs are considered:
| STATUS=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | |
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .status' | head -n1 || true) | |
| CONCLUSION=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | |
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .conclusion' | head -n1 || true) | |
| STATUS=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs?per_page=100" \ | |
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .status' | head -n1 || true) | |
| CONCLUSION=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs?per_page=100" \ | |
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .conclusion' | head -n1 || true) |
| if [ "$STATUS" = "completed" ]; then | ||
| exit 0 | ||
| fi |
There was a problem hiding this comment.
No check on build conclusion — proceeds even on failure
The step exits 0 (success) whenever STATUS == "completed", regardless of whether CONCLUSION is "success", "failure", or "cancelled". This means a new release will be created even if the previous Codemagic build failed or was explicitly cancelled.
If the intent is to only proceed when the prior release succeeded, check the conclusion:
| if [ "$STATUS" = "completed" ]; then | |
| exit 0 | |
| fi | |
| if [ "$STATUS" = "completed" ]; then | |
| if [ "$CONCLUSION" != "success" ]; then | |
| echo "Previous release build finished with conclusion: $CONCLUSION. Aborting." | |
| exit 1 | |
| fi | |
| exit 0 | |
| fi |
If intentionally ignoring the conclusion (e.g. "just wait for it to finish, whatever the outcome"), a comment explaining the rationale would help future maintainers.
| STATUS=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | ||
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .status' | head -n1 || true) | ||
| CONCLUSION=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | ||
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .conclusion' | head -n1 || true) | ||
|
|
||
| if [ -z "$STATUS" ]; then | ||
| echo "No Codemagic release check found for $LATEST yet; continuing." | ||
| exit 0 | ||
| fi | ||
|
|
||
| echo "Previous release build status: $STATUS (${CONCLUSION:-n/a})" | ||
|
|
||
| if [ "$STATUS" = "completed" ]; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| sleep 60 | ||
| done |
There was a problem hiding this comment.
Two separate API calls per loop iteration — consolidate for efficiency
STATUS and CONCLUSION are fetched with two independent gh api calls. This doubles the rate-limit cost and introduces a small window where a build could transition from in_progress to completed between the two requests, creating an inconsistent pair. Both fields can be retrieved in a single request by selecting them in one jq expression:
| STATUS=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | |
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .status' | head -n1 || true) | |
| CONCLUSION=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs" \ | |
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | .conclusion' | head -n1 || true) | |
| if [ -z "$STATUS" ]; then | |
| echo "No Codemagic release check found for $LATEST yet; continuing." | |
| exit 0 | |
| fi | |
| echo "Previous release build status: $STATUS (${CONCLUSION:-n/a})" | |
| if [ "$STATUS" = "completed" ]; then | |
| exit 0 | |
| fi | |
| sleep 60 | |
| done | |
| for i in {1..120}; do | |
| RESULT=$(gh api "repos/${{ github.repository }}/commits/$SHA/check-runs?per_page=100" \ | |
| --jq '.check_runs[] | select(.name=="Release OMI Desktop (Swift)") | "\(.status) \(.conclusion)"' | head -n1 || true) | |
| STATUS=$(echo "$RESULT" | awk '{print $1}') | |
| CONCLUSION=$(echo "$RESULT" | awk '{print $2}') | |
| if [ -z "$STATUS" ]; then | |
| echo "No Codemagic release check found for $LATEST yet; continuing." | |
| exit 0 | |
| fi | |
| echo "Previous release build status: $STATUS (${CONCLUSION:-n/a})" | |
| if [ "$STATUS" = "completed" ]; then | |
| exit 0 | |
| fi | |
| sleep 60 | |
| done |
…asedHardware#5438) Adds workflow concurrency and waits for prior 'Release OMI Desktop (Swift)' check to complete before creating the next tag, preventing release/tag pile-up.
Adds workflow concurrency and waits for prior 'Release OMI Desktop (Swift)' check to complete before creating the next tag, preventing release/tag pile-up.