Fix RoboShield CI and migrate builds to Docker Bake - #1507
Merged
Conversation
eslint-config-commons-ui's babel-eslint-parser resolves "@babel/preset-react" via Node module resolution starting from the consuming app's own directory, not from the shared config package. Every other app on this config declares the preset directly as a workaround; roboshield never did, so the Next.js lint-on-build step has been failing "Cannot find module '@babel/preset-react'" on every RoboShield | Deploy | DEV run since at least April.
RoboShield was still built from the legacy shared root Dockerfile via two independent docker/build-push-action workflows, each hand-rolling its own build-args and Dokku push. Move it onto the same per-app Dockerfile + Docker Bake architecture as pesayetu/techlabblog/trustlab. ### What changed - Add a pruned, multi-stage Dockerfile at docker/apps/roboshield/Dockerfile. - Add the roboshield target to docker-bake.hcl and the shared apps group. Reads MONGO_URL/NEXT_PUBLIC_SENTRY_DSN as BuildKit secrets (roboshield's own env var names), rather than inheriting _payload-app-runner's DATABASE_URL, which trustlab uses instead. - Reuse the published ui-builder-base/ui-runner-base images in CI. - Package the standalone server, public/static assets, and Dokku health-check metadata. - Switch local `make roboshield` and Compose usage to the Bake-built image. - Mark roboshield migrated in docker/README.md. - Remove the now-dead roboshield-* stages from the legacy root Dockerfile. ### CI/CD - Add a reusable RoboShield Bake workflow (_build-roboshield.yml) and a new orchestration workflow (roboshield.yml): version-check, then build+deploy to dev on every push and to prod on a version bump. - RoboShield bakes NEXT_PUBLIC_APP_URL into the client bundle and dev/prod are genuinely different Dokku apps with different canonical URLs, so — unlike techlabblog/trustlab, which build once and promote — dev and prod each get their own build, matching the two-workflow setup this replaces. - Extend the shared _bake-and-push.yml workflow with roboshield's MONGO_URL/NEXT_PUBLIC_SENTRY_DSN secret plumbing. - Remove the legacy roboshield-deploy-dev.yml/roboshield-deploy-prod.yml workflows entirely (no shared root Dockerfile dependency to preserve). - No new GitHub secrets or variables required; all existing ROBOSHIELD_* secrets carry over unchanged. ### Validation - `docker buildx bake roboshield` — full turbo-prune -> install -> next build (compile, lint, static export) completes and exports an image. - `docker run` smoke test — the built image boots, Next.js starts, and it connects to its configured database with no errors. - Reproduced the exact `make roboshield` / bake-up.sh flow (env-sourced build args, no explicit --set overrides) end to end after wiring NEXT_PUBLIC_APP_URL/SENTRY_ENVIRONMENT into the target's args map. - Workflow YAML parses successfully.
kelvinkipruto
requested review from
kilemensi and
koechkevin
and removed request for
kilemensi
August 17, 2026 08:43
kilemensi
reviewed
Aug 17, 2026
Member
|
Before I forget @kelvinkipruto, there is also |
- Standardize on DATABASE_URL instead of MONGO_URL for RoboShield's Payload DB connection, matching trustlab. RoboShield's target now inherits _payload-app-runner directly instead of declaring its own mongo_url secret. Fall back to MONGO_URL in the app itself so Dokku environments not yet reconfigured with the new var name keep working. - Restore the legacy roboshield-deploy-dev.yml/roboshield-deploy-prod.yml workflows and the root Dockerfile's roboshield-* stages verbatim. They're disabled in the GitHub UI and being kept as a rollback path until the new pipeline is validated across all environments, same as pesayetu-deploy-prod.yml alongside the shared root Dockerfile. - Add roboshield to the pr-build.yml image-validation workflow and scripts/pr-build-targets.mjs's target detection, so roboshield's Docker image is exercised on trusted PRs before merging, using dummy build secrets (RoboShield doesn't query its database during static generation, unlike trustlab, so a well-formed but unreachable DATABASE_URL is sufficient).
Contributor
Author
|
@claude Review |
Mirror trustlab's pattern: read SENTRY_DSN fresh via process.env on the server, inject it into a window global from _document.tsx at SSR time, and read it from there on the client (src/utils/site.ts). Changing the DSN is now a Dokku config:set + restart, not a rebuild. instrumentation-client.ts falls back to the existing build-time NEXT_PUBLIC_SENTRY_DSN secret, since Payload's admin panel is served from a generated App Router layout (src/app/(payload)/layout.tsx) that must not be edited and has no equivalent runtime-injection point. Deployment note: SENTRY_DSN (not NEXT_PUBLIC_SENTRY_DSN) needs to be set as a runtime config var on both the dev and prod Dokku apps for the public site to pick up the DSN without a rebuild.
Per review feedback (github.com//pull/1507#discussion_r3803422254), drop the build-time NEXT_PUBLIC_SENTRY_DSN fallback rather than keeping it as a secondary source. instrumentation-client.ts now relies solely on site.sentryDsn: undefined on Payload's admin panel (App Router, no runtime-injection point), populated everywhere else via the window global injected by _document.tsx. This matches trustlab's own tradeoff exactly. Removes the now-unnecessary build-time secret plumbing entirely: Dockerfile's next_public_sentry_dsn mount, docker-bake.hcl's roboshield secret list (fully inherited now, no app-specific secrets left), _bake-and-push.yml, _build-roboshield.yml, roboshield.yml, and pr-build.yml. Also trims comments that were left duplicated or restating the code after the surrounding logic changed.
Contributor
Author
|
@claude Review |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
kilemensi updated the DEV/PROD Dokku config and scripts in the vault to set DATABASE_URL, so the MONGO_URL fallback in payload.config.ts and the migration file is no longer needed. Also renames the legacy (disabled) roboshield-deploy-dev.yml/ roboshield-deploy-prod.yml workflows' secret id/build-arg from mongo_url/MONGO_URL to database_url/DATABASE_URL, and the matching --mount in the root Dockerfile's roboshield-builder stage, so that frozen rollback path still resolves a database URL if ever re-enabled. The underlying ROBOSHIELD_MONGO_URL GitHub secret is unchanged, only the build arg/secret id it's mapped to.
koechkevin
approved these changes
Aug 19, 2026
kilemensi
approved these changes
Aug 19, 2026
kilemensi
left a comment
Member
There was a problem hiding this comment.
🚀
Checking the code, I think in all of the Payload apps that uses Page router, Sentry is only configured for pages and not admin/Payload itself. We should do a fix on a separate PR.
This was referenced Aug 20, 2026
9 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fix RoboShield's CI/CD, which has been failing on every push to
mainsince at least April, and migrate it to the repository's per-app Dockerfile and Docker Bake build architecture.Fixes the
RoboShield | Deploy | DEVworkflow, which has failed on every run since at least April 2026.Why
RoboShield | Deploy | DEVhas failed on every push tomainfor months:next build's lint step throwsCannot find module '@babel/preset-react'.eslint-config-commons-ui's babel-eslint-parser resolves that preset via Node module resolution starting from the consuming app's own directory, not from the shared config package. Every other app on this config (pesayetu,charterafrica,civicsignalblog,climatemappedafrica,codeforafrica,twoopstracker) declares the preset directly as a workaround;roboshieldnever did.RoboShield | Deploy | PRODlooked green throughout, but only because it gates the actual build behind a version-bump check that has stayedfalse— it has been skipping the build entirely, not validating it.While fixing this, RoboShield was still built from the legacy shared root
Dockerfilevia two independentdocker/build-push-actionworkflows, each hand-rolling its own build-args and Dokku push — unlikepesayetu/techlabblog/trustlab, which already share the published builder/runner base images, Bake caching, and reusable workflows. Since the build needed fixing anyway, this migrates it onto the same architecture.What changed
RoboShield CI fix
@babel/preset-reactdevDependency toapps/roboshield/package.json.RoboShield Docker Bake migration
docker/apps/roboshield/Dockerfile.roboshieldtarget todocker-bake.hcland the sharedappsgroup. ReadsMONGO_URL/NEXT_PUBLIC_SENTRY_DSNas BuildKit secrets (RoboShield's own env var names), rather than inheriting_payload-app-runner'sDATABASE_URL, whichtrustlabuses instead.ui-builder-base/ui-runner-baseimages in CI.make roboshieldand Compose usage to the Bake-built image.docker/README.md.roboshield-*stages from the legacy rootDockerfile.CI/CD
_build-roboshield.yml) and a new orchestration workflow (roboshield.yml): version-check, then build+deploy to dev on every push and to prod on a version bump.NEXT_PUBLIC_APP_URLinto the client bundle, and dev/prod are genuinely different Dokku apps with different canonical URLs — so, unliketechlabblog/trustlab, which build once and promote, dev and prod each get their own build here, matching the two-workflow setup this replaces._bake-and-push.ymlworkflow with RoboShield'sMONGO_URL/NEXT_PUBLIC_SENTRY_DSNsecret plumbing.roboshield-deploy-dev.yml/roboshield-deploy-prod.ymlworkflows entirely (no shared root Dockerfile dependency left to preserve).Deployment and rollout
No new GitHub secrets or variables are required — all existing
ROBOSHIELD_*secrets (ROBOSHIELD_MONGO_URL,ROBOSHIELD_PAYLOAD_SECRET,ROBOSHIELD_SENTRY_DSN,ROBOSHIELD_SENTRY_PROJECT) and shared secrets (SENTRY_AUTH_TOKEN,SENTRY_ORG,SSH_PRIVATE_KEY,DOCKER_HUB_*) carry over unchanged, along with the existingvars.UI_BASE_TAG.Validation
docker buildx bake roboshield— full turbo-prune → install →next build(compile, lint, static export) completes and exports an image.docker runsmoke test — the built image boots, Next.js starts, and it connects to its configured database with no errors.make roboshield/bake-up.shflow (env-sourced build args, no explicit--setoverrides) end to end, after wiringNEXT_PUBLIC_APP_URL/SENTRY_ENVIRONMENTinto the target'sargsmap.Commits
fix roboshield missing @babel/preset-react dependencymigrate roboshield builds to Docker BakeType of change
Screenshots
N/A
Checklist