Skip to content

fix(ci): free runner disk before Android release build - #435

Merged
thomasluizon merged 1 commit into
mainfrom
fix/android-release-runner-disk-space
Jul 9, 2026
Merged

fix(ci): free runner disk before Android release build#435
thomasluizon merged 1 commit into
mainfrom
fix/android-release-runner-disk-space

Conversation

@thomasluizon

Copy link
Copy Markdown
Owner

Problem

Android Release run #29030329772 failed during Build signed AAB with Gradle with:

System.IO.IOException: No space left on device : '/home/runner/actions-runner/cached/2.335.1/_diag/Worker_...log'

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 --log returns BlobNotFound). This is a runner-capacity problem, not a code defect: 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.

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/sdk by default, which this Gradle build depends on. All other reclamation targets keep their safe defaults, freeing ~15+ GB of headroom.

Verification

  • Workflow YAML parses; new step is first, followed by the unchanged checkout.
  • The only reachable check is re-dispatching the Android Release workflow (it's workflow_dispatch-only), which the maintainer runs to cut a build.

🤖 Generated with Claude Code

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>
@vercel

vercel Bot commented Jul 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
orbit-ui-mobile-web Ignored Ignored Jul 9, 2026 4:08pm

Request Review

@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@thomasluizon
thomasluizon merged commit c491d6e into main Jul 9, 2026
18 checks passed
@thomasluizon
thomasluizon deleted the fix/android-release-runner-disk-space branch July 9, 2026 16:11

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 54081f138730dfa15788a46383842cd2f914a1be actually corresponds to the jlumbroso/free-disk-space v1.3.1 tag 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 in sonarcloud.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 device in 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: false shows 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. ⚠️ old-client breaks) 0
High 0
Medium 0
Low / Info 1

thomasluizon added a commit that referenced this pull request Jul 24, 2026
…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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant