Build E2E image within build_artifacts to skip base-image re-pull#28471
Build E2E image within build_artifacts to skip base-image re-pull#284719larsons wants to merge 4 commits into
Conversation
The separate Build E2E Docker Image job re-pulled the entire production image (~54s) onto a fresh runner just to add a trivial COPY layer (public-app UMD bundles + env) and re-push it. Fold that build into job_build_artifacts, where the production 'full' image is still warm in the BuildKit cache, so the e2e image resolves its base from cache instead of a full re-pull. - Delete job_build_e2e_image; build & push ghost-e2e at the end of job_build_artifacts (registry path) / save as artifact (fork path). - Preserve both distribution paths; use a host docker-driver buildx builder on the artifact path so FROM resolves the locally-loaded image. - Rewire job_e2e_tests and job_required_tests to the new source. - ghost-e2e stays a separate tag; the deployed production image is unchanged. - Do not gate job_build_artifacts start on public-apps; download that artifact at the late e2e step to avoid delaying the job's start.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThe CI workflow now builds the ghost-e2e Docker image inside job_build_artifacts (resolving the production full-image base, extracting e2e-public-apps, optionally configuring Buildx for artifact paths), exposes the resulting tags as job_build_artifacts.outputs.image-e2e-tags, and rewires job_e2e_tests to depend on and consume that output. job_build_e2e_image is removed and job_required_tests.needs is updated to drop the removed job. Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #28471 +/- ##
==========================================
- Coverage 73.75% 73.75% -0.01%
==========================================
Files 1541 1541
Lines 132219 132193 -26
Branches 15825 15819 -6
==========================================
- Hits 97516 97494 -22
+ Misses 33737 33732 -5
- Partials 966 967 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@rob-ghost I'll clean up the comments after review. Mind taking a pass? I suspect you kept these separate in order to speed up the CD workflows. |
rob-ghost
left a comment
There was a problem hiding this comment.
If I'm following correctly, we were waiting around for public UMD apps to build the docker images, when in reality we don't need them except for e2e images, so split them up so we can leverage the build cache.
I don't think this has downstream impact because only the e2e bakes in the UMD apps, public and pro use NPM CDN to deliver these IIRC.
|
| Command | Status | Duration | Result |
|---|---|---|---|
nx run ghost:test:ci:integration |
✅ Succeeded | 2m 25s | View ↗ |
nx run ghost:test:ci:e2e |
✅ Succeeded | 11m 45s | View ↗ |
nx run @tryghost/admin-x-settings:test:acceptance |
✅ Succeeded | 10m 21s | View ↗ |
nx build @tryghost/announcement-bar |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/sodo-search |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/signup-form |
✅ Succeeded | <1s | View ↗ |
nx build @tryghost/portal |
✅ Succeeded | 1s | View ↗ |
nx build @tryghost/admin-toolbar |
✅ Succeeded | <1s | View ↗ |
Additional runs (15) |
✅ Succeeded | ... | View ↗ |
💡 Verify your cache is correct by running tasks in a sandbox. Read docs ↗
☁️ Nx Cloud last updated this comment at 2026-06-12 00:58:31 UTC
There was a problem hiding this comment.
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 @.github/workflows/ci.yml:
- Around line 1047-1053: The "Download public app artifacts (e2e)" step races
with the producer; add a readiness guard by depending on or polling for the
producer job/artifact before downloading: either add an explicit needs:
job_build_e2e_public_apps dependency to the job that contains the "Download
public app artifacts (e2e)" and "Extract public app artifacts (e2e)" steps, or
insert a short retry/poll step (using e.g. actions/github-script or a curl loop
against the Actions artifacts API) that waits for the e2e-public-apps artifact
to exist and succeeds before running the download step, so the download step
always finds the artifact and avoids flakes.
🪄 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: Pro
Run ID: 12053f89-4244-4f38-b9df-e39e349eac74
📒 Files selected for processing (1)
.github/workflows/ci.yml
The E2E image build now runs inside the artifacts job, so the public app artifact can be requested before its producer finishes. Polling keeps the artifacts job's early start while ensuring download-artifact only runs once the artifact exists.

What
Folds the separate
Build E2E Docker Imagejob intojob_build_artifacts. Theghost-e2eimage is now builtFROMthe productionfullimage while it is still warm in that job's BuildKit cache, then pushed — instead of a separate runner that re-pulled the entire production image just to add a trivial layer and re-push it.Why
On the E2E critical path (
Setup → Build & Publish Artifacts → Build E2E Docker Image → E2E Tests), the E2E image job spent ~2 min almost entirely moving data: ~54sdocker pullof the freshly-built production image, ~30s fresh-runner setup, and ~39s build/push — all to applye2e/Dockerfile.e2e, which is just aCOPYof the public-app UMD bundles plus 6ENVvars. The base image already existed in the prior job's BuildKit cache.Changes
job_build_e2e_image; build & pushghost-e2eat the end ofjob_build_artifacts.FROMresolves the just-pushedfulllayers from cache (no re-pull).docker-driver builder soFROMresolves the locally-loaded image; thedocker-image-e2etarball is saved/uploaded as before.job_build_artifactsdownloads thee2e-public-appsartifact at the late e2e step and is not added toneeds(that would delay the job's start ~1.4 min and cancel the saving; public-apps finishes ~3 min, well before the step is reached).job_e2e_testsandjob_required_testsoff the deleted job.ghost-e2estays a separate tag.Expected impact
~90–110s off the E2E-lane critical path.
Verify on a real run
fullbase served from cache, not a full re-pull.docker-image-e2eartifact is produced and consumed byjob_e2e_tests.