Status: Implemented and extended. This spec describes the current preview-environment workflow, direct local URLs, dashboard, and approval wiring built from the matching PRD.
Source PRD: docs/prd/pull-request-preview-environments.md
The current implementation adds one preview-delivery slice on top of the existing CI and k3d setup:
- deterministic preview IDs derived from pull request numbers or branch names
- isolated Helm release, namespace, and ingress host generation
- direct local preview URLs for
k3drehearsals - a generated dashboard for observing active previews
- GitHub Actions workflow for build, deploy, test, PR comment, and cleanup
- a guarded approval workflow that can enable merge on approval
- local
k3dpreview rehearsal through Makefile targets and the same scripts
The preview scripts derive a stable identifier using these rules:
- use
pr-<number>when a pull request number is available - otherwise slugify the branch name
- otherwise accept an explicit preview key from the CLI
That identifier drives:
- namespace
- Helm release name
- ingress host
- preview URL output
infrastructure/k3s/scripts/pr-env-create.sh
- computes preview identifiers
- installs or upgrades the Helm release
- accepts image overrides for backend and frontend preview images
- labels and annotates the preview namespace for dashboard discovery
- writes preview outputs for GitHub Actions when
PREVIEW_OUTPUT_FILEis set
infrastructure/k3s/scripts/pr-env-test.sh
- waits for backend, frontend, nginx, and database readiness
- prints namespace and ingress state
- can smoke-check previews either through a direct local URL or a host-header gateway route
infrastructure/k3s/scripts/pr-env-delete.sh
- resolves the same preview identity
- uninstalls the Helm release
- deletes the preview namespace
infrastructure/k3s/scripts/pr-env-dashboard.sh
- inspects namespaces labeled as active previews
- renders an HTML dashboard with preview links, status, and rollout summaries
- supports a local observation loop during review
The chart now supports preview deployment needs through:
- overridable backend and frontend image names
- per-container
imagePullPolicy - optional
imagePullSecrets - ingress annotations for external preview controllers
.github/workflows/preview-environment.yml
- triggers on pull request open, synchronize, reopen, and close
- builds backend and frontend preview images
- pushes those images to GHCR
- deploys the preview release with branch or PR-specific identity
- validates rollout with the shared preview test script
- posts or updates a pull request comment with the preview URL
- deletes the preview namespace when the pull request closes
.github/workflows/preview-approval.yml
- listens for approved pull-request reviews
- only acts when
PREVIEW_AUTO_MERGE_ON_APPROVAL=true - prefers GitHub auto-merge and falls back to direct merge when possible
- relies on the existing close workflow to remove the preview after merge
The workflow expects these repository settings for remote preview deployment:
- secret:
PREVIEW_KUBECONFIG_B64 - variable:
PREVIEW_BASE_DOMAIN
Optional repository variables:
PREVIEW_INGRESS_CLASSPREVIEW_IMAGE_PULL_SECRETPREVIEW_URL_SCHEMEPREVIEW_AUTO_MERGE_ON_APPROVALPREVIEW_AUTO_MERGE_METHOD
When the required settings are missing, the workflow reports that preview deployment is skipped instead of pretending it ran.
The Makefile exposes a local preview rehearsal path against k3d:
- build and import preview images
- create a PR-style preview release
- wait for rollout
- curl the preview through the local ingress entrypoint using the preview host header
- delete the namespace when done
This keeps the preview flow testable without needing a remote cluster for every change.
The local preview path uses hosts like:
http://pr-204.localhost:8088http://feature-preview-url.localhost:8088
That means a reviewer can open a local preview directly in a browser without manually constructing Host headers.
The local observation path is:
- create one or more previews
- generate the dashboard with
make pr-env-dashboard - open the generated HTML file
- use the listed URLs and readiness summaries to decide whether to keep, merge, or delete a slice
- A preview namespace can be created from a PR number without manual Helm edits.
- A preview namespace can also be created from a branch name when no PR number exists.
- The preview test script can prove workload readiness for backend, frontend, nginx, and database.
- A GitHub pull request can receive a preview URL comment when preview deployment is configured.
- The preview namespace can be deleted cleanly on pull request close.
- This slice wires the preview workflow and local rehearsal path. It does not solve enterprise DNS, auth, or cost governance by itself.
- A real deployment still depends on cluster credentials, registry access, and a base domain controlled outside the repo.
- Preview environments help people decide faster, but they do not replace acceptance criteria, QA, or merge discipline.