From 3db78a4a484bce2ccad8384955cc4deda060cc1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Tue, 14 Jul 2026 08:37:23 +0200 Subject: [PATCH] ci(staging): make PR previews opt-in (label or body marker) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR previews were built + deployed for every apps/packages PR — each one a journal container + its own database on the flagship, which is a standing contributor to the disk pressure behind recurring deploy failures and the 2026-07-14 disk-full outage. Make them opt-in: a preview is built/deployed only when the PR carries the `preview` label OR a `` marker in its description. Gate the (costly) build-images job, deploy-preview, and — via new labeled/unlabeled triggers — tear the preview down when the label is pulled, so a de-flagged PR can't orphan its stack. Main-push / dispatch deploys are unchanged. Note: the pull_request `paths` filter still applies, so labeling a PR that touches no apps/packages files won't spin up a preview (nothing to preview). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/cd-staging.yml | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cd-staging.yml b/.github/workflows/cd-staging.yml index 311a95b..e69dec6 100644 --- a/.github/workflows/cd-staging.yml +++ b/.github/workflows/cd-staging.yml @@ -17,7 +17,9 @@ on: - "infrastructure/docker-compose.staging.yml" - ".github/workflows/cd-staging.yml" pull_request: - types: [opened, synchronize, reopened, closed] + # `labeled`/`unlabeled` so toggling the `preview` label on an existing PR + # starts / tears down its preview (see the opt-in gate on the jobs below). + types: [opened, synchronize, reopened, closed, labeled, unlabeled] paths: - "apps/**" - "packages/**" @@ -44,7 +46,15 @@ jobs: # Skipped entirely on PR close (teardown doesn't need new images). build-images: name: Build & Push Docker Images - if: github.event_name != 'pull_request' || github.event.action != 'closed' + # PR previews are opt-in to keep flagship disk in check (each preview is a + # journal container + database): build a PR's images only when it carries + # the `preview` label or a `` marker in its description. + # Main-push / dispatch always build. + if: > + github.event_name != 'pull_request' || + (github.event.action != 'closed' && + (contains(github.event.pull_request.labels.*.name, 'preview') || + contains(github.event.pull_request.body, ''))) runs-on: ubuntu-latest environment: production permissions: @@ -207,11 +217,15 @@ jobs: # ── PR preview deploy ──────────────────────────────────────────────── deploy-preview: name: Deploy PR Preview - # Skip GH-Actions-only Dependabot PRs — there is no app image to preview. + # Opt-in only (see build-images): the `preview` label or a `` + # marker in the PR body. Also skips GH-Actions-only Dependabot PRs — there + # is no app image to preview. if: > github.event_name == 'pull_request' && github.event.action != 'closed' && - !startsWith(github.head_ref, 'dependabot/github_actions/') + !startsWith(github.head_ref, 'dependabot/github_actions/') && + (contains(github.event.pull_request.labels.*.name, 'preview') || + contains(github.event.pull_request.body, '')) needs: [build-images] runs-on: ubuntu-latest environment: production @@ -410,7 +424,15 @@ jobs: # ── PR preview teardown ────────────────────────────────────────────── teardown-preview: name: Tear Down PR Preview - if: github.event_name == 'pull_request' && github.event.action == 'closed' + # Tear down on close, or when the `preview` opt-in is removed (label pulled + # and no `` marker left) so a de-flagged PR doesn't orphan + # its preview stack on the flagship. + if: > + github.event_name == 'pull_request' && + (github.event.action == 'closed' || + (github.event.action == 'unlabeled' && + !(contains(github.event.pull_request.labels.*.name, 'preview') || + contains(github.event.pull_request.body, '')))) runs-on: ubuntu-latest environment: production permissions: