From f1573f4906065a3c60fc4770a70dcea988f10da1 Mon Sep 17 00:00:00 2001 From: jjbrunton Date: Mon, 31 Aug 2026 17:56:41 +0100 Subject: [PATCH 1/2] fix(admin): keep admin app in the docker build context The root .dockerignore excluded apps/admin, so the monorepo build context dropped that workspace entirely: npm ci skipped it and `npm run build -w @sauci/admin` failed with "No workspaces found". The ignore file was authored for the mcp image and later extended with re-includes for web; admin never got the same treatment. Re-include apps/admin, and re-exclude node_modules/dist last so the re-includes cannot pull host build artefacts into any image context. Verified with `docker build -f apps/admin/Dockerfile .`. Co-Authored-By: Claude Opus 5 --- .dockerignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.dockerignore b/.dockerignore index f6e50f1..cb7f5a2 100644 --- a/.dockerignore +++ b/.dockerignore @@ -39,3 +39,11 @@ terraform .claude .codex .ralph + +# The admin app builds from this same monorepo context (apps/admin/Dockerfile). +!apps/admin +!apps/admin/** + +# Host build artefacts must never leak into any image context. +**/node_modules +**/dist From d14869d7458d2faaa99814e37c3f9ef474cdb768 Mon Sep 17 00:00:00 2001 From: jjbrunton Date: Mon, 31 Aug 2026 18:03:34 +0100 Subject: [PATCH 2/2] ci(branch-policy): allow hotfix and release branches into main The policy accepted only `staging` as a head for main, so any change production needed before the next promotion had nowhere to go: the PR was unmergeable by CI and branch protection blocks direct pushes. Accept `hotfix/*` and `release/*` heads as well. The naming requirement keeps a direct-to-main change deliberate and visible, and the master freeze plus the "features target staging" rule are unchanged. Document the escape hatch and the need to land the same commit on staging. Co-Authored-By: Claude Opus 5 --- .github/workflows/verify.yml | 11 ++++++++--- docs/operations/backend-deployments.md | 12 ++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index f870058..3fa551a 100644 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -24,9 +24,14 @@ jobs: echo "master is frozen; target staging or main" >&2 exit 1 fi - if [ "$BASE_BRANCH" = "main" ] && [ "$HEAD_BRANCH" != "staging" ]; then - echo "Only staging may be promoted to main" >&2 - exit 1 + if [ "$BASE_BRANCH" = "main" ]; then + case "$HEAD_BRANCH" in + staging|hotfix/*|release/*) ;; + *) + echo "main takes staging promotions, or a hotfix/* or release/* branch for direct work" >&2 + exit 1 + ;; + esac fi if [ "$BASE_BRANCH" != "staging" ] && [ "$BASE_BRANCH" != "main" ]; then echo "Feature pull requests target staging; promotions target main" >&2 diff --git a/docs/operations/backend-deployments.md b/docs/operations/backend-deployments.md index 2ccb482..dab7dbb 100644 --- a/docs/operations/backend-deployments.md +++ b/docs/operations/backend-deployments.md @@ -14,10 +14,14 @@ not deploy the retired Supabase data plane. | `master` | frozen legacy default | none | none | Normal feature pull requests target `staging`. After CI and authenticated staging -acceptance pass, open a promotion pull request from `staging` to `main`. Do not -add production-only commits to `main`: production should run the exact commit -already exercised in staging. Direct pushes to either deployment branch are for -explicit incident recovery only. +acceptance pass, open a promotion pull request from `staging` to `main`. Prefer +that route: production then runs the exact commit already exercised in staging. + +When production needs a change that cannot wait for the next promotion, open a +pull request into `main` from a `hotfix/*` or `release/*` branch. CI enforces +that naming so a direct-to-main change is always deliberate and visible. Land +the same commit on `staging` too, or the next promotion will revert it. Direct +pushes to either deployment branch remain blocked by branch protection. Each Dokploy Compose application is connected to `jjbrunton/Sauci`, watches its single branch with push-triggered automatic deployment, and uses