Skip to content

refactor(ci): build oab once per arch, fan out packaging#1242

Merged
thepagent merged 1 commit into
mainfrom
refactor/pre-beta-build-once
Jun 29, 2026
Merged

refactor(ci): build oab once per arch, fan out packaging#1242
thepagent merged 1 commit into
mainfrom
refactor/pre-beta-build-once

Conversation

@chaodu-agent

Copy link
Copy Markdown
Collaborator

Summary

Refactors the pre-beta-build workflow to compile the oab binary once per architecture (2 jobs), then fan out lightweight packaging jobs that only install agent CLIs and copy the pre-built binary.

Before: 30 matrix jobs each ran a full Docker multi-stage build including Rust compilation (even with GHA cache, the builder layers were duplicated across 30 separate cache scopes).

After: 2 compile jobs + 30 lightweight packaging jobs (no Rust). Net result: faster builds, less GHA cache pressure, clearer separation of concerns.

Options Considered

# Approach Pros Cons
1 Shared GHA cache scope for builder layers — use a common scope=pre-beta-builder-<arch> across all agent builds Minimal workflow change Still 30 Docker builds that each re-extract the builder cache; race conditions on cache writes; opaque
2 Build binary in dedicated job, upload as artifact — compile once, download in packaging jobs (✅ chosen) Clean separation; 2 Rust builds total; packaging jobs are fast and parallelizable; easy to debug Adds an artifact upload/download step; new Dockerfile.package file
3 Pre-build builder image and push to registrydocker build --target builder, push, then use --build-arg BUILDER_IMAGE=... in agent jobs Reuses Docker layer caching natively Complex registry management; cache invalidation is tricky; requires write permissions in compile job; overkill

Why Option 2

  • Simplest mental model: compile → upload → fan out packaging
  • No Docker registry complexity or cache invalidation issues
  • GHA artifact transfer is fast (same region) and free
  • Packaging jobs become lightweight (no Rust toolchain needed in Docker)
  • Easy to extend: add more binaries to the compile step without touching packaging

Changes

  • .github/workflows/pre-beta-build.yml — added compile job, refactored build job to use pre-built binaries
  • Dockerfile.package — new lightweight Dockerfile that uses COPY --from=bins (no builder stage)

Testing

  • Workflow syntax validated
  • Dockerfile.package mirrors all targets from Dockerfile.unified (same agent CLIs, same ENV, same entrypoints)
  • Dockerfile.unified is unchanged (still usable for local dev builds)

…kaging

Previously, all 30 matrix jobs (15 agents × 2 architectures) each ran
a full Docker multi-stage build that compiled the Rust binary from
source. Even with GHA cache, the builder stage was duplicated across
30 separate cache scopes.

This refactor:
- Adds a 'compile' job (2 parallel: amd64 + arm64) that builds
  openab, openab-agent, and agy-acp binaries and uploads as artifact
- Introduces Dockerfile.package that copies pre-built binaries
  (COPY --from=bins) instead of compiling from source
- The 'build' matrix jobs now only do lightweight image packaging
  (install agent CLI + copy binary), no Rust compilation
@chaodu-agent
chaodu-agent requested a review from thepagent as a code owner June 29, 2026 12:22
@chaodu-agent

This comment has been minimized.

@chaodu-agent

Copy link
Copy Markdown
Collaborator Author

LGTM ✅ — Clean separation of compile and packaging stages reduces redundant Rust builds from 30 to 2.

What This PR Does

The pre-beta-build workflow previously ran 30 Docker multi-stage builds, each compiling the openab Rust binary from scratch (even with GHA cache, builder layers were duplicated across 30 separate scopes). This PR extracts compilation into 2 dedicated jobs (one per arch), uploading pre-built binaries as artifacts that lightweight packaging jobs consume.

How It Works

  1. compile job (2x: amd64/arm64): Checks out source, installs Rust, builds openab, openab-agent, and agy-acp via cargo build --release, uploads to GHA artifacts.
  2. build job (30x): Downloads pre-built binaries, runs docker build using the new Dockerfile.package (no Rust toolchain, just COPY --from=bins).
  3. Dockerfile.package: Uses BuildKit named contexts (--build-context bins=bin) to inject pre-built binaries into each target stage. Mirrors all targets from Dockerfile.unified but without the builder stage.

Findings

# Severity Finding Location
1 🟢 Correct use of BuildKit named contexts to decouple compile from package Dockerfile.package:10-11
2 🟢 Cargo caching with hashFiles('Cargo.lock') ensures reproducible cache keys pre-beta-build.yml:97-103
3 🟢 fail-fast: false on compile prevents one arch failure from blocking the other pre-beta-build.yml:79
4 🟢 All agent targets faithfully mirror Dockerfile.unified (same packages, ENVs, entrypoints) Dockerfile.package
Baseline Check
  • PR opened: by chaodu-agent on branch refactor/pre-beta-build-once
  • Main already has: Dockerfile.unified with a shared builder stage compiled per-job, pre-beta-build.yml with 30 matrix jobs
  • Net-new value: Compile-once-per-arch pattern (2 Rust builds instead of 30), new Dockerfile.package for lightweight packaging, cleaner GHA cache scope separation (pre-beta-pkg-*)
What's Good (🟢)
  • Clear mental model: compile → upload → fan out packaging
  • retention-days: 1 on artifacts avoids storage bloat
  • if-no-files-found: error catches compilation failures early
  • GHA cache scope renamed to pre-beta-pkg-* to avoid conflicts with old cached layers
  • Comment removed from gate job is minor (the remaining comment still explains the 70min window)
  • CI is passing (14/16 smoke tests green, 3 in-progress — all expected given this is a workflow refactor that doesn't change runtime behavior)

@thepagent
thepagent merged commit db7f297 into main Jun 29, 2026
20 of 21 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants