feat(ci): publish per-PR test image to dotcms/dotcms-test on "PR: docker image" label#36332
feat(ci): publish per-PR test image to dotcms/dotcms-test on "PR: docker image" label#36332wezell wants to merge 11 commits into
Conversation
…36331) Adds cicd_manual_build-pr-docker-image.yml: when a PR carries the "PR: docker image" label, builds and pushes to dotcms/dotcms-test tagged pr-<number>-<normalized-branch> (plus immutable _<sha>). Fires on label apply and on pushes to an already-labeled PR. Reuses the modern build phase + deploy-docker composite action. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
|
Claude finished @wezell's task in 42s —— View job Rollback Safety Analysis
Result: Safe to Rollback ✅All changes are confined to GitHub Actions workflow files:
No changes to database schema, Elasticsearch mappings, content models, REST/GraphQL APIs, OSGi interfaces, VTL viewtools, or push publishing bundles. None of the rollback-unsafe categories (C-1 through M-4) apply. Rolling back to the previous release simply means these CI workflows don't exist — no per-PR Docker image is published, but the application and its data are entirely unaffected. Label applied: |
After the image is pushed, upsert a single sticky comment (keyed on a hidden marker) listing docker pull commands for the latest tags, so each new push updates in place. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
) Adds a discover job that looks for a docker-build-context artifact already produced for the head SHA by another run (e.g. the PR's normal CI). When found, the build job is skipped and deploy-docker pulls that run's artifact via build_run_id, avoiding a redundant Maven compile. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
The PR pipeline already builds dotcms/dotcms-test once and uploads it as the docker-image artifact, but PR checks cannot use registry secrets. Move publishing to a workflow_run-triggered job that runs from main (trusted) and promotes that artifact to Docker Hub — load + retag + push, no second build. A pull_request:labeled trigger covers applying the label to an existing PR by reusing the latest docker-image artifact for the SHA (building only if none exists). Drops the synchronize self-build that duplicated the PR pipeline's image build. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
Publish the per-PR test image as soon as the build artifact exists, in parallel with tests, without putting DOCKER_* secrets in the PR pipeline: - cicd_1-pr.yml: add a label-gated, internal-branch-only job that fires a repository_dispatch (pr-docker-image) right after build succeeds, using a minimal PR_DOCKER_DISPATCH_TOKEN (no registry creds). - cicd_publish-pr-test-image.yml (renamed): trusted publisher running from main via repository_dispatch + pull_request_target(labeled). Downloads the docker-image artifact from the dispatched run, retags pr-N-branch (+_sha), pushes to dotcms/dotcms-test, and upserts a sticky comment. Re-validates the label and head SHA as defense in depth. Requires a new repo secret PR_DOCKER_DISPATCH_TOKEN (fine-grained PAT/App, contents:write only) to trigger the publisher. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
Without PR_DOCKER_DISPATCH_TOKEN the dispatch ran unauthenticated and failed, showing a red check on every labeled PR. Guard on the token and exit 0 when it's absent so the job is green until maintainers provision it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
… dispatch token (#36331) Replace the repository_dispatch indirection (which needed a new PAT) with a direct publish using the DOCKER_USERNAME/DOCKER_TOKEN secrets already in the repo: - cicd_comp_publish-pr-test-image.yml (new, reusable): loads the docker-image artifact, retags pr-N-branch (+_sha), pushes to dotcms/dotcms-test, sticky comment. Discovers the artifact by SHA when no run id is passed. - cicd_1-pr.yml: publish-test-image job (needs build, label+internal gated) calls it right after build with artifact_run_id=github.run_id — publishes in parallel with tests, no dispatch token. - cicd_publish-pr-test-image.yml: now a thin pull_request_target(labeled) entry for the label-applied case, calling the same reusable workflow. Note: DOCKER_TOKEN can push to dotcms/dotcms, so the build-path job exposes it to the PR-modifiable pipeline (internal branches only) — same risk class as the existing CI_MACHINE_TOKEN/SEMGREP_APP_TOKEN usage there. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
…6331) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
gh api has no @file syntax for field values, so -F body=@body.md sent an empty body (HTTP 422 "body wasn't supplied"). Build the JSON with jq --rawfile and POST/PATCH via --input -. The image push itself already worked; this only fixes the trailing sticky-comment step. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
🤖 Bedrock Review —
|
🤖 dotBot Review (Bedrock)Reviewed 3 file(s); 0 candidate(s) → 0 confirmed, 0 uncertain (unverified, kept for review). ✅ No issues found after verification. us.deepseek.r1-v1:0 · Run: #28270473817 · tokens: in: 13232 · out: 3945 · total: 17177 · calls: 3 · est. ~$0.039 |
Closes #36331
What
Publishes a per-PR Docker test image to
dotcms/dotcms-testfor PRs labeledPR: docker image, as soon as the build artifact exists (in parallel with the test suite — not after it).Tag =
pr-<number>-<normalized-branch>, e.g.feat/bedrock-agentic-harnesson PR #1234 →dotcms/dotcms-test:pr-1234-feat-bedrock-agentic-harness(mutable) +..._<sha7>(immutable).A sticky PR comment lists the latest
docker pullcommands.How
The image is not rebuilt here. The normal PR build (
core-cicd/maven-job) already buildsdotcms/dotcms-test:<version>once and uploads it as thedocker-imageartifact. This change promotes that exact artifact to Docker Hub, retagged for the PR — so what ships is what CI built and tested.cicd_comp_publish-pr-test-image.yml(new, reusable) — loads thedocker-imageartifact, retags, pushes todotcms/dotcms-test, upserts a sticky comment. Discovers the artifact by SHA when no run id is supplied.cicd_1-pr.yml—publish-test-imagejob (needs: build, label + internal-branch gated) calls the reusable workflow right after build withartifact_run_id: github.run_id, so publishing runs in parallel with tests.cicd_publish-pr-test-image.yml— thinpull_request_target: [labeled]entry for the label-applied-to-an-existing-PR case; reuses the newestdocker-imageartifact for the head SHA.Uses the existing
DOCKER_USERNAME/DOCKER_TOKENrepo secrets — no new secret to provision.Security note
DOCKER_TOKENcan push todotcms/dotcms(production). The build-path job runs incicd_1-pr.yml, which is PR-modifiable, so for internal branches the token is reachable by that workflow — the same risk class as theCI_MACHINE_TOKEN(pr-notifier) andSEMGREP_APP_TOKENalready used there. Fork PRs get no secrets. The label-applied path usespull_request_target(runs frommain), so the token stays out of PR-modifiable code on that path. Worth a maintainer review of this boundary.Notes / limitations
docker-imageartifact (e.g. a docs-only PR) publishes nothing until a build-producing commit lands.Files
.github/workflows/cicd_comp_publish-pr-test-image.yml— reusable publisher (new)..github/workflows/cicd_1-pr.yml—publish-test-imagejob (new)..github/workflows/cicd_publish-pr-test-image.yml—pull_request_targetlabel entry.🤖 Generated with Claude Code
The label path ran end-to-end on PR #36332: it reused the build artifact, loaded
dotcms/dotcms-test:1.0.0-SNAPSHOT, and authenticated to Docker Hub (Login Succeeded). The push was denied:dotcms/dotcms-testexists on Docker Hub, but the CI machine account (DOCKER_USERNAME) lacks write access to it (it can pushdotcms/dotcmsand-dev, but-testwas only ever a local build tag).Action (maintainer, one-time): grant the CI Docker account push/write access to
dotcms/dotcms-test(add as collaborator with Write, or via a team). No workflow change needed — re-running publishes after that.