Skip to content

perf(ci): reuse trusted registry build caches - #6891

Merged
cv merged 9 commits into
mainfrom
codex/cache-hermes-rebuild-e2e
Jul 14, 2026
Merged

perf(ci): reuse trusted registry build caches#6891
cv merged 9 commits into
mainfrom
codex/cache-hermes-rebuild-e2e

Conversation

@cv

@cv cv commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Moves base-image BuildKit cache storage from quota-constrained GitHub Actions caches to per-image GHCR registry cache artifacts. OpenClaw and Hermes rebuild E2Es plus the Deep Agents Code profile gate import those trusted caches through job-local Buildx builders without exporting PR-controlled layers, and the selected builder now reaches the Docker builds spawned by the fixtures and CLI.

Changes

  • Publish one :buildcache registry artifact beside each OpenClaw, Hermes, and Deep Agents Code base image, using mode=max only in the trusted publisher workflow.
  • Warm the OpenClaw, Hermes, and Deep Agents Code E2E builders from their publisher caches while keeping E2E cache use read-only; old rebuild fixtures reuse compatible layers already present in the job-local builder.
  • Preserve BUILDX_BUILDER across the fixture and sandbox-prebuild environment boundaries so direct test builds and NemoClaw prebuilds use the warmed builder.
  • Extend base-image workflow triggers and source identity to include every direct Dockerfile.base COPY input.
  • Add workflow mutation and environment-boundary tests that reject cache exports from PR jobs, wrong cache ownership, builder-routing drift, stale invalidation inputs, and step-order drift.
  • Leave the intentionally cold full-e2e path and the existing build-once/artifact-sharing sandbox-image workflows unchanged.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: The required documentation review confirmed this is internal CI/cache behavior with no user-facing command, configuration, supported product behavior, contributor procedure, or cold-path change.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: Publisher jobs are the only registry-cache writers; PR-controlled E2E jobs have read-only GitHub permissions, receive no GHCR write credential, and are protected by mutation tests that reject cache-to or push inputs. Existing credential isolation and immutable action pins remain intact.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes a Signed-off-by: line and every commit appears as Verified in GitHub
  • Normal pre-commit, commit-msg, and pre-push hooks passed, or npm run check:diff passed when hooks were skipped or unavailable
  • Targeted behavior tests pass for the current change set, or tests are marked not applicable above — npx vitest run --project cli --project integration --project e2e-support src/lib/onboard/sandbox-prebuild.test.ts src/lib/sandbox-base-image/source-identity.test.ts src/lib/sandbox-base-image/resolution-key.test.ts test/dcode-base-image-workflow.test.ts test/e2e/support/e2e-workflow.test.ts test/e2e/support/hosted-inference.test.ts (6 files, 88 tests); npx vitest run --project installer-integration test/install-openshell-version-check.test.ts -t "preserves rebuild Hermes workflow inputs through the real installer boundary" (1 passed); npm run source-shape:check (passed)
  • Applicable broad gate passed — npm test for broad runtime/test-harness changes; npm run check for repo-wide validation/coverage changes — command/result:
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Additional runtime evidence from the original change set: a local container-driver Buildx smoke confirmed that a subsequent plain docker build selected the named builder, reused the warmed layer as CACHED, and auto-loaded the resulting image.


Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • Chores
    • Expanded base-image rebuild triggers to include additional runtime/config files, reviewed npm archive, and sandbox rate-limit scripts.
    • Switched base-image Buildx caching to registry-backed build cache (mode=max) across relevant build-and-push jobs.
    • Standardized E2E rebuild workflows with shared Buildx builder setup/routing, production build-arg validation, and stricter “warm cache” step pinning/order.
  • Tests
    • Added/strengthened assertions for registry cache publisher invariants and E2E boundary protection against cache/wiring drift.
    • Updated sandbox/E2E env propagation coverage for BUILDX_BUILDER, plus sandbox base-image identity/resolution-key test updates.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv self-assigned this Jul 14, 2026
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 069c3623-2baa-4870-b287-7d9420a2b84a

📥 Commits

Reviewing files that changed from the base of the PR and between e2475e9 and c14b9f4.

📒 Files selected for processing (3)
  • .github/workflows/e2e.yaml
  • test/e2e/support/e2e-workflow.test.ts
  • tools/e2e/workflow-boundary.mts
💤 Files with no reviewable changes (1)
  • tools/e2e/workflow-boundary.mts
🚧 Files skipped from review as they are similar to previous changes (2)
  • test/e2e/support/e2e-workflow.test.ts
  • .github/workflows/e2e.yaml

📝 Walkthrough

Walkthrough

Base-image workflows now publish registry-backed Buildx caches and track additional image inputs. E2E workflows configure and route dedicated builders, warm current caches, and validate cache wiring, action pins, environment propagation, target scoping, and execution order.

Changes

Buildx cache publication and input tracking

Layer / File(s) Summary
Base-image cache contract and input tracking
.github/workflows/base-image.yaml, src/lib/sandbox-base-image/*, test/dcode-base-image-workflow.test.ts
Base-image publishers use publisher-specific registry cache refs, trigger on expanded inputs, and validate cache ownership, matching refs, export mode, and uniqueness.
E2E cache warming and builder routing
.github/workflows/e2e.yaml
Live DCode and rebuild jobs configure dedicated Buildx builders, route Docker builds through them, validate build arguments, and warm current base-image caches.
Workflow boundary invariants and ordering
tools/e2e/workflow-boundary.mts, test/e2e/support/e2e-workflow.test.ts
Boundary checks enforce pinned actions, cache policies, builder and Dockerfile wiring, target scoping, required scripts, and ordering of setup, warming, preparation, and tests.
Builder environment propagation
src/lib/onboard/sandbox-prebuild.*, test/e2e/*, test/install-openshell-version-check.test.ts
Selected child environments preserve BUILDX_BUILDER while excluding unrelated variables.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant E2EWorkflow
  participant Buildx
  participant DockerBuild
  participant BoundaryValidator
  participant E2ETest
  E2ETest->>E2EWorkflow: Load workflow configuration
  E2EWorkflow->>Buildx: Configure dedicated builder
  E2EWorkflow->>DockerBuild: Warm current base-image registry cache
  E2EWorkflow->>DockerBuild: Run routed Docker build
  E2ETest->>BoundaryValidator: Validate cache wiring and step order
  BoundaryValidator-->>E2ETest: Return boundary validation results
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the main CI change: switching to trusted registry-backed build caches.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cache-hermes-rebuild-e2e

Comment @coderabbitai help to get the list of available commands.

@github-code-quality

github-code-quality Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage remains at 96%, unchanged from the main branch.

TypeScript / code-coverage/cli

The overall coverage in the codex/cache-hermes-r... branch remains at 79%, unchanged from the main branch.

Show a code coverage summary of the most impacted files.
File main ea143b8 codex/cache-hermes-r... c14b9f4 +/-
src/lib/sandbox...rce-identity.ts 94% 93% -1%
src/lib/state/m...-acquisition.ts 89% 90% +1%
src/lib/actions...ge-preflight.ts 74% 89% +15%

Updated July 14, 2026 23:43 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

PR Review Advisor — Informational

Advisor assessment: Informational / medium confidence
Next action: No advisor follow-up needed.
Findings: 0 blockers · 0 warnings · 0 suggestions
Status: No actionable findings remain in the canonical review ledger.

Model lanes

  • GPT-5.6 Terra (primary): Completed · medium confidence · 0 blockers · 0 warnings · 0 suggestions
  • Nemotron 3 Ultra (second opinion): Failed after a partial review · low confidence · 0 blockers · 2 warnings · 0 suggestions

Nemotron output stays in workflow artifacts and does not change the assessment above.

E2E guidance

Advisory only. E2E / PR Gate selects and runs jobs independently.

Recommended E2E: cloud-onboard, credential-sanitization, security-posture, inference-routing, network-policy, onboard-repair, onboard-resume, state-backup-restore, upgrade-stale-sandbox

4 optional E2E recommendations
  • rebuild-openclaw
  • rebuild-hermes
  • rebuild-hermes-stale-base
  • ubuntu-repo-cloud-langchain-deepagents-code

Workflow run details

This automated review informs maintainers. Warnings and suggestions do not require a response. A maintainer decides whether to merge.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/dcode-base-image-workflow.test.ts (1)

73-86: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

ghaCacheEntries assumes type=gha is always the first CSV field.

.split(",").slice(1) drops whichever field is first, not the type=gha token specifically. If a cache string ever places type=gha in a non-leading position (e.g. scope=x,type=gha), the real scope=/mode= field would be dropped instead, and the validator would falsely flag a valid config. Currently safe only because every cache string in the workflows puts type=gha first.

♻️ Proposed fix: filter out the `type=gha` token explicitly instead of assuming position
     .map((entry) =>
       Object.fromEntries(
         entry
           .split(",")
-          .slice(1)
+          .filter((field) => field !== "type=gha")
           .map((field) => field.split("=", 2) as [string, string]),
       ),
     );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/dcode-base-image-workflow.test.ts` around lines 73 - 86, Update
ghaCacheEntries to remove the type=gha field explicitly before constructing the
entry object, rather than dropping the first CSV field with slice(1). Preserve
all other fields, including scope and mode, regardless of their position.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/e2e/support/e2e-workflow.test.ts`:
- Around line 39-65: Clone the four steps selected by setupBuildx, routeBuilds,
warmCurrent, and warmOld before mutating their with/env fields, then replace the
corresponding entries in rebuild-hermes.steps with those clones. Keep the
synthetic drift isolated to rebuild-hermes so shared steps used by
rebuild-hermes-stale-base remain unchanged.

---

Nitpick comments:
In `@test/dcode-base-image-workflow.test.ts`:
- Around line 73-86: Update ghaCacheEntries to remove the type=gha field
explicitly before constructing the entry object, rather than dropping the first
CSV field with slice(1). Preserve all other fields, including scope and mode,
regardless of their position.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8e33d1e0-04de-47cb-a2d1-4d5bd955b905

📥 Commits

Reviewing files that changed from the base of the PR and between 45b1cb5 and e929a7c.

📒 Files selected for processing (5)
  • .github/workflows/base-image.yaml
  • .github/workflows/e2e.yaml
  • test/dcode-base-image-workflow.test.ts
  • test/e2e/support/e2e-workflow.test.ts
  • tools/e2e/workflow-boundary.mts

Comment thread test/e2e/support/e2e-workflow.test.ts Outdated
Signed-off-by: Carlos Villela <cvillela@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/e2e/support/e2e-workflow.test.ts`:
- Around line 55-61: Update cloneStep to validate the result of steps.findIndex
before accessing or cloning steps[index]. When the named step is absent, throw a
descriptive error identifying the missing step; only perform structuredClone and
replacement after the index is confirmed valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a89fff99-d9ff-4fca-b8a6-154190ad8dc5

📥 Commits

Reviewing files that changed from the base of the PR and between 6f8df84 and 368dd20.

📒 Files selected for processing (2)
  • test/dcode-base-image-workflow.test.ts
  • test/e2e/support/e2e-workflow.test.ts

Comment thread test/e2e/support/e2e-workflow.test.ts Outdated
@wscurran wscurran added area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure chore Build, CI, dependency, or tooling maintenance integration: dcode LangChain Deep Code integration behavior integration: hermes Hermes integration behavior integration: openclaw OpenClaw integration behavior labels Jul 14, 2026
@cv cv changed the title perf(ci): reuse BuildKit cache in Hermes rebuild E2E perf(ci): reuse trusted registry build caches Jul 14, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tools/e2e/workflow-boundary.mts`:
- Around line 3941-4001: Remove the redundant cache-to/push validation from the
warmDcodeInputs block in the DCode workflow checks. Keep
requireReadOnlyBuildCacheImports(errors, steps, "live DCode cache warm") as the
sole validation for job-local PR-controlled layers, while preserving the
existing builder, context, file, and cache-from checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: db5b053c-5e6e-473f-8a96-a81946162bb1

📥 Commits

Reviewing files that changed from the base of the PR and between 368dd20 and e2475e9.

📒 Files selected for processing (13)
  • .github/workflows/base-image.yaml
  • .github/workflows/e2e.yaml
  • src/lib/onboard/sandbox-prebuild.test.ts
  • src/lib/onboard/sandbox-prebuild.ts
  • src/lib/sandbox-base-image/resolution-key.test.ts
  • src/lib/sandbox-base-image/source-identity.test.ts
  • src/lib/sandbox-base-image/source-identity.ts
  • test/dcode-base-image-workflow.test.ts
  • test/e2e/fixtures/availability-env.ts
  • test/e2e/support/e2e-workflow.test.ts
  • test/e2e/support/hosted-inference.test.ts
  • test/install-openshell-version-check.test.ts
  • tools/e2e/workflow-boundary.mts

Comment thread tools/e2e/workflow-boundary.mts
@cv

cv commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@cv
cv merged commit ebd1ed0 into main Jul 14, 2026
60 of 63 checks passed
@cv
cv deleted the codex/cache-hermes-rebuild-e2e branch July 14, 2026 23:59
cv added a commit that referenced this pull request Jul 15, 2026
<!-- markdownlint-disable MD041 -->
## Summary

Repair the rebuild E2E cache regressions introduced by #6891. The
rebuild jobs now keep their sequential production Docker builds on the
Docker engine cache; trusted base-image publisher jobs continue to
import and export their registry caches unchanged.

## Changes

- Remove the separate Buildx setup and base-cache warm from
`rebuild-openclaw`, `rebuild-hermes`, and `rebuild-hermes-stale-base`.
Cache metadata created in the isolated container builder is not
available to the later Docker engine builds, so these steps only add
work.
- Keep the DCode profile-import gate on the Docker engine. Its three
negative builds communicate through temporary local image tags that are
unavailable to a containerized builder.
- Remove the now-unused `BUILDX_BUILDER` propagation through fixture and
sandbox-prebuild child environments.
- Preserve the trusted base-image publisher cache imports/exports,
provenance, permissions, and registry ownership from #6891.
- Add workflow-boundary mutations that reject separate Buildx
setup/cache-warm actions and persistent builder selection in rebuild and
DCode jobs.

Runtime measurements confirmed the split:

- DCode passed end to end on the Docker engine in [run
29378936022](https://github.com/NVIDIA/NemoClaw/actions/runs/29378936022).
Its target job took 8m37s versus an 8m48s pre-change average (11s
faster, effectively unchanged).
- An isolated OpenClaw warm plus Docker-engine live test took 9m53s in
[run
29379468825](https://github.com/NVIDIA/NemoClaw/actions/runs/29379468825),
versus a 9m06s pre-change live-test average. The warm cost 34s, while
the current-base build was still 41s with 10 cached steps; the registry
warm did not transfer cache metadata into the engine.
- Routing the whole OpenClaw test through the isolated builder was
worse: the live test took 9m54s after a 28s warm in [run
29378572904](https://github.com/NVIDIA/NemoClaw/actions/runs/29378572904),
and the later production rebuild retained only 15 cached steps instead
of the Docker engine baseline of 79.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates

- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: Documentation review
confirmed this is internal CI cache topology with no user-facing
command, configuration, image contract, or supported product behavior
change.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: Publisher provenance,
cache writers, registry ownership, and permissions are unchanged.
Rebuild jobs stop selecting an isolated PR-job builder and retain their
existing Docker engine execution boundary.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification

- [x] PR description includes a `Signed-off-by:` line and every commit
appears as `Verified` in GitHub
- [x] Normal `pre-commit`, `commit-msg`, and `pre-push` hooks passed, or
`npm run check:diff` passed when hooks were skipped or unavailable
- [x] Targeted behavior tests pass for the current change set, or tests
are marked not applicable above — `npx vitest run --project cli
--project e2e-support src/lib/onboard/sandbox-prebuild.test.ts
test/e2e/support/e2e-workflow.test.ts
test/e2e/support/dcode-profile-import-gate-workflow-boundary.test.ts
test/e2e/support/hosted-inference.test.ts` (4 files, 75 tests); `npx
vitest run --project installer-integration
test/install-openshell-version-check.test.ts -t "preserves the rebuild
Hermes requested channel through the real installer boundary"` (1
passed); `npm run source-shape:check` (passed)
- [ ] Applicable broad gate passed — `npm test` for broad
runtime/test-harness changes; `npm run check` for repo-wide
validation/coverage changes — command/result:
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

---

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci CI workflows, checks, release automation, or GitHub Actions area: e2e End-to-end tests, nightly failures, or validation infrastructure chore Build, CI, dependency, or tooling maintenance integration: dcode LangChain Deep Code integration behavior integration: hermes Hermes integration behavior integration: openclaw OpenClaw integration behavior

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants