Skip to content

fix(ci): build.yml runs out of disk on GitHub-hosted runners #189

@scottschreckengaust

Description

@scottschreckengaust

Problem

The build job in build.yml fails with ENOSPC: no space left on device during CDK test/synth esbuild bundling. This affects all PRs (e.g., #144 — a docs-only PR).

Error: Failed to write to output file: write /tmp/cdk.outRhUxmE/bundling-temp-.../index.js: no space left on device

Root cause

The build runs on ubuntu-latest runners (~25-30 GB free). Disk is consumed by:

Phase Approximate disk used
Pre-installed software (Android SDK, .NET, tools) ~55 GB (only ~25-30 GB remains)
yarn install (node_modules, 3 workspaces) ~1.5 GB
uv sync (agent .venv) ~200 MB
//cdk:test → Jest triggers CDK synth → esbuild bundles ALL Lambda handlers to /tmp ~2-4 GB
//cdk:synth:quiet → esbuild bundles ALL handlers AGAIN to /tmp + writes cdk.out/ ~2-4 GB

The CDK test step and CDK synth step both do full esbuild bundling independently, accumulating artifacts in /tmp.

Recommended fix (Option 1 — preferred, ~10 seconds added to build)

Add a disk cleanup step before Install dependencies:

- name: Free disk space
  run: sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/hostedtoolcache

This frees ~22 GB in under 10 seconds by removing pre-installed Android SDK (~14 GB), .NET (~2.7 GB), and tool cache (~5.9 GB). No apt-get (which is what makes full cleanup actions take 5+ minutes).

For maximum headroom (~28 GB, still under 30 seconds):

- name: Free disk space
  run: |
    sudo rm -rf /usr/local/lib/android /usr/share/dotnet /opt/hostedtoolcache \
      /opt/ghc /usr/local/.ghcup /usr/local/share/powershell
    sudo docker image prune --all --force

Alternative fixes (lower priority)

Option 2: Clean /tmp between CDK test and synth

Add rm -rf /tmp/cdk.out* after //cdk:test and before //cdk:synth. This addresses the double-bundling accumulation but doesn't fix the underlying tight headroom.

Could be done in cdk/mise.toml:

[tasks."synth:quiet"]
description = "cdk synth (quiet, with pre-clean)"
run = ["rm -rf /tmp/cdk.out*", "npx cdk synth -q"]

Option 3: Use jlumbroso/free-disk-space action (MIT license)

- uses: jlumbroso/free-disk-space@main
  with:
    large-packages: false  # Skip apt-get (saves 3-5 min)
    android: true
    dotnet: true
    haskell: true
    tool-cache: true
    docker-images: false   # We need Docker for CDK bundling
    swap-storage: false

This takes ~30-60 seconds with large-packages: false. With it enabled, 3-5 minutes.

FOSS actions evaluated

Action License Speed Notes
jlumbroso/free-disk-space MIT 30s–8min Best option if using an action; disable large-packages for speed
easimon/maximize-build-space MIT Minutes Also does LVM resize — overkill for our need
Inline rm -rf N/A <10s Simplest, fastest, zero dependencies

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions