fix(ci): free runner disk before Android release build - #435
Conversation
The `Android Release` job crashed mid-Gradle-`bundleRelease` with "No space left on device": the isolated mobile node_modules copy + Expo prebuild + the full signed AAB (plus Sentry sourcemaps) overrun the ~14 GB free on a stock ubuntu-latest runner. The runner ran out of space so hard it could not even flush its own diagnostic log, so no step log was uploaded. Reclaim the unused preinstalled toolchains (.NET, Haskell, large apt packages, Docker images, swap) with jlumbroso/free-disk-space, pinned by SHA. Keep `android: false` so the Android SDK this Gradle build depends on is preserved. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
There was a problem hiding this comment.
Code Review: PR #435 — fix(ci): free runner disk before Android release build
Scope: PR #435 in thomasluizon/orbit-ui-mobile (.github/workflows/android-release.yml, +11/-0, single file)
Recommendation: APPROVE
Summary
The diff adds one step — jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be (pinned by full commit SHA, matching the repo's existing SonarSource pinning convention) — as the first step in the Android Release workflow, before checkout, with android: false explicitly set so the Gradle build's dependency on the preinstalled Android SDK survives. The change is narrowly scoped to CI infrastructure, correctly placed (runs before any disk-hungry step), carries a WHY-with-URL comment explaining the runner-capacity root cause, and does not touch any application code, contract, or user-facing surface.
Findings
Critical
None
High
None
Medium
None
Low / Info
[Info] Swap-storage reclamation trades disk headroom for memory headroom
· dimension: 1 (Correctness) / 12 (Security — configuration)
· location: .github/workflows/android-release.yml:60
· issue: `swap-storage` is left at the action's default (removed). `./gradlew --no-daemon bundleRelease` (line ~230) is memory-hungry; removing swap means a JVM heap spike that used to page to swap now risks an OOM kill instead.
· risk: Low — ubuntu-latest runners have enough RAM that this is unlikely to bite, and the PR's own stated failure was disk, not memory. Flagging only as a thing to watch if a future run fails with an OOM instead of a disk error.
· fix: No action needed now; if a future release run OOMs, the first thing to try is `swap-storage: false` while keeping the disk reclamation.
Per the rubric's signal gate, this Info item is not a blocking finding — included for completeness only, not counted toward the recommendation.
Subagents
| Agent | Verdict |
|---|---|
| parity-checker | N/A — diff touches only .github/workflows/android-release.yml, no apps/web/** or apps/mobile/** source file |
| i18n-syncer | N/A — no user-facing strings changed |
| contract-aligner | N/A — no packages/shared/src/types/* or endpoints.ts change, orbit-api not touched |
| security-reviewer | N/A — orbit-api not touched |
| design-reviewer | N/A — no apps/* UI files changed |
None of the five subagents gate in for this diff — it is CI-workflow-only.
Validation
Phase 6 (/validate) skipped per this PR's CI adaptation — Build / Unit Tests / SonarCloud run as separate required checks.
Deferred — N/A dimensions & files not verdicted
- Dimensions 3 (SOLID/clean-arch), 6 (type safety), 7 (
console.log), 8 (DESIGN.md/AI-slop), 9 (parity), 10 (i18n), 11 (contract drift), 13 (backend hard rules), 14 (FEATURES.md parity): all N/A — the diff is a single GitHub Actions YAML file with no application, contract, UI, or feature-surface code. - Dimension 12 (security): API-side and frontend-XSS/auth-leakage categories N/A (no app or API code); the CI-supply-chain angle (pinning,
android: false) was reviewed inline above. - Not independently verifiable in this environment: whether commit SHA
54081f138730dfa15788a46383842cd2f914a1beactually corresponds to thejlumbroso/free-disk-spacev1.3.1tag claimed in the trailing comment — no outbound network access to GitHub's API for the third-party repo in this job. The pinning style (full SHA + version comment) matches the existing SonarSource precedent insonarcloud.yml, so the practice is sound; only the specific SHA↔tag correspondence is unverified. Recommend a maintainer spot-check this once, not blocking. - orbit-api not checked out in this job — no cross-repo dimension applies to this diff anyway (CI-workflow-only change).
- No other changed files — this is the full diff.
What's good
- Root-cause diagnosis is precise and cited (
no space left on devicein a diagnostic log write, not a code defect) — matches CLAUDE.md rule 1 (root cause over workarounds). - WHY comment carries a real URL to the failed run, exactly the shape the comment-policy dimension asks for.
android: falseshows the author read the action's docs rather than accepting all defaults blind — the Android SDK removal would have broken the very build this fixes.- SHA-pinning matches the repo's own established convention rather than a mutable tag/branch ref.
- Correct step placement (first, before checkout) so reclamation happens before anything else consumes disk.
Recommendation
Approve as-is. Nothing here needs a code change. Optional, non-blocking follow-up: after the next real release run, spot-check that the SHA pin still matches v1.3.1 and that swap-storage removal hasn't introduced a memory-pressure failure mode in place of the disk one.
| Severity | Count |
|---|---|
| Critical (incl. |
0 |
| High | 0 |
| Medium | 0 |
| Low / Info | 1 |
…nt_id removal (#600) The Contract Drift gate went red on every open ui PR. It was correct: orbit-api PR #435 dropped the unread `client_id` form field from `/oauth/token`, which changed the published OpenAPI spec, so the committed Zod snapshot no longer matched orbit-api main. Regenerated with `npm run generate:zod -w @orbit/shared`. The diff is exactly the two lines the api change removed, nothing else. No consumer change is needed: grepping `packages/shared/src`, `apps/web` and `apps/mobile` outside `__generated__` finds zero references to `client_id`, so no hand-written type or callsite depended on it. The field was write-only from the client's side and was never read server-side either, which is why it was removed. Claude-Session: https://claude.ai/code/session_018M2vH4pDvNnxUPecWWvwBc Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>



Problem
Android Release run #29030329772 failed during Build signed AAB with Gradle with:
The runner exhausted its disk mid-
bundleRelease. It ran out of space so hard it couldn't even flush its own diagnostic log, so the step log blob was never uploaded (gh run view --logreturnsBlobNotFound). This is a runner-capacity problem, not a code defect: the isolated mobilenode_modulescopy +expo prebuild+ the full signed AAB (plus Sentry sourcemaps) overrun the ~14 GB free on a stockubuntu-latestrunner.Fix
Add a first step that reclaims the unused preinstalled toolchains (.NET, Haskell, large apt packages, Docker images, swap) via
jlumbroso/free-disk-space, pinned by commit SHA (matching this repo's SonarSource pinning convention).Critically,
android: false— the action removes/usr/local/lib/android/sdkby default, which this Gradle build depends on. All other reclamation targets keep their safe defaults, freeing ~15+ GB of headroom.Verification
checkout.Android Releaseworkflow (it'sworkflow_dispatch-only), which the maintainer runs to cut a build.🤖 Generated with Claude Code