CI/CD
Current GitHub Actions and deployment behavior.
Pipelines
GitHub Actions workflows are in .github/workflows.
ci.yml
Jobs:
Lint & Format Check:bun run checkTypeScript Check:bun run docs:generatethenbunx tsc --noEmitSecurity Audit:bun run auditandbun run audit:dashboardDocs Integrity: docs links + LLM sync checks
CI is the quality gate for pull requests. It validates source formatting, generated docs parity, TypeScript safety, security audits, and documentation integrity before merge.
coolify-deploy.yml
- Runs after the
CI/CD Pipelinesucceeds on a push tomain. - Can also be started manually with
workflow_dispatch; the manual run exposes aforceinput that rebuilds the Docker images without the GitHub Buildx cache before deploying. - Builds immutable app and worker Docker images on a GitHub-hosted
ubuntu-24.04-armrunner, targetslinux/arm64for the Mac mini VM, pushes the images to GHCR, then lets the private self-hosted runner make the Coolify VM pull those images before triggering the deployment. - Runs on the dedicated repository-scoped self-hosted runner installed on the
Mac mini with the
yayaw-coolifylabel for the Coolify API and VM SSH steps. This keeps Coolify reachable only from the private Mac/Tailscale network instead of exposing the Coolify API to the public internet. - Uses the GitHub
productionenvironment and theCOOLIFY_URL,COOLIFY_API_TOKEN, andCOOLIFY_APPLICATION_UUIDsecrets. The production environment also stores the build-timeNEXT_PUBLIC_*,BETTER_AUTH_SECRET, andDATABASE_URLvalues needed bynext build. - Serializes deployments with a dedicated concurrency group and polls Coolify until the deployment finishes or fails.
- Runs the compose
migrateservice inside the Coolify/Docker network before the app and worker start, so thedrizzle-kit pushschema sync and seed script can reach internal service names such aspostgres. - Smoke-tests production after Coolify reports the deployment as finished. The
check verifies that
/api/healthreports the merged commit SHA, thathttps://yayaw.app/frresponds, and that the seeded French Terms and Privacy pages render their page-bound legal copy without leaking reusable-section fixture text. vercel.jsondisables Vercel Git deployments withgit.deploymentEnabled: false; disconnect the Vercel Git integration in the dashboard as well if Vercel should stop posting external PR statuses entirely.
Vercel owns the hosted production build and deploy lifecycle when the Vercel
provider is used. Coolify owns self-hosted production deploys when
coolify-deploy.yml is configured: after CI passes on main, GitHub Actions
builds and pushes Docker images from the merged commit to GHCR, makes the
Coolify server pull them, updates YAYAW_APP_IMAGE and
YAYAW_WORKER_IMAGE, and asks Coolify to run the compose deployment without
rebuilding on the production VM. The
self-host compose deployment owns production schema sync and seed execution
through its migrate service. Schema changes must stay backward-compatible
with the currently deployed app and the next deployment.
YAYAW_APP_IMAGE and YAYAW_WORKER_IMAGE are marked as both runtime and
build-time Coolify variables. Docker Compose interpolates image: values while
Coolify prepares the deployment, before containers start.
Pull request development deployments use the same prebuilt-image path after CI passes. The shared development Coolify app still switches to the PR branch so the compose definition is read from the branch under test, but the heavy Docker build runs on GitHub-hosted Linux runners rather than on the Mac mini VM. The workflows use GHCR as the image transport instead of GitHub Actions artifacts, so development and production deploys are not blocked by repository artifact storage quota.
Vercel also owns preview deployments and preview comments when the hosted provider is enabled. GitHub Actions should not add duplicate preview deployment notifications for that path.
Branch and Pull Request Flow
Use one branch per task:
git checkout main
git pull --ff-only origin main
git checkout -b codex/<task-name>Before opening a PR:
- Keep the diff scoped to the task.
- Stage only intended files.
- Commit with a terse summary.
- Push the branch.
- Open a draft PR unless the user explicitly asks for ready review.
Generated files are expected when their source changes:
AGENTS.mdGEMINI.md.github/copilot-instructions.md- generated Drizzle server actions when schemas change
- Fumadocs source artifacts when docs content changes
Local Parity Commands
bun run check
bun run docs:generate
bun run docs:check-links
bun run docs:check-translations
bun run docs:llm:check
bunx tsc --noEmit
bun run buildFor billing, webhook, or code-access work, also run:
bun run testFor generated action changes, run:
bun run generate:actionsFor assistant-doc changes, run:
bun run docs:llm:generateDeployment Environments
Vercel and self-hosted Docker are both supported deployment targets. Vercel
environment variables must be scoped as Production, Preview, or Development.
Self-hosted runtime variables live in the orchestrator secret store or in the
untracked .env.self-host file used by docker-compose.self-host.yml. See
Deployment Environment Setup and
Self-Hosting for provider retrieval steps and deployment
checks.
The self-host compose migrate service owns the drizzle-kit push schema sync
and seed step for Coolify deployments. Keep the GitHub production environment
DATABASE_URL available for build-time server route evaluation, but do not run
a separate production migration workflow alongside the compose deployment.
The Coolify prebuilt-image flow requires these environment-scoped GitHub secrets or variables:
| Environment | Name | Purpose |
|---|---|---|
development, production | BETTER_AUTH_SECRET | Required by the Docker build so Better Auth route evaluation is stable. |
development, production | DATABASE_URL | Build-time database URL fallback for server route evaluation. |
development, production | NEXT_PUBLIC_* build values | Public client bundle configuration baked into Next.js. |
development, production | NEXT_BUILD_WORKERS variable | Build worker count. Defaults to 2. |
development, production | NEXT_STATIC_PAGE_GENERATION_TIMEOUT variable | Static generation timeout. Defaults to 180. |
development, production | COOLIFY_SERVER_SSH_* variables or COOLIFY_SERVER_SSH_KEY secret | Optional overrides for loading images onto the Coolify VM. The Mac mini runner defaults match the local VM SSH setup. |
The workflows grant packages: write to the image-build job and
packages: read to the Coolify deploy job so the repository GITHUB_TOKEN can
push immutable images to GHCR and the self-hosted runner can pull them onto the
VM.
After changing a Vercel environment variable, trigger a fresh deployment for
that environment. After changing a self-host secret, restart the affected app or
worker containers and verify /dashboard/admin deployment status.
Merge Safety
Auto-merge only runs when required checks have succeeded.
Do not bypass failed docs integrity checks. They usually mean either:
- an internal docs link is broken
content/llm/llm-source.mdchanged without regenerating assistant files- generated docs artifacts are stale