Deployment¶
This guide covers how code moves from a feature branch to production on Kinsta, including the CI/CD pipeline, environment mapping, and the push workflow.
Environments¶
| Environment | URL | Branch | Trigger |
|---|---|---|---|
| Production | naluma.app |
main |
Push to main (merge PR) |
| Staging | Kinsta staging subdomain | staging |
Push to staging |
| Local | localhost:8080 |
Feature branches | Manual (docker compose up) |
Kinsta runs Nginx (no .htaccess), manages server-side caching, and provides a CDN with automatic WebP conversion via Cloudflare Polish.
Branch-to-environment flow¶
All work follows the same pattern: branch from main, open a PR, squash merge.
-
Create a feature branch from
main: -
Commit locally using conventional commits (
feat:,fix:,chore:,docs:). Do not push after every commit -- each push triggers CI. -
When ready, push and open a PR targeting
main: -
CI runs the quality gate automatically (see below).
-
Squash merge the PR. The repository is configured for squash-only merges with the PR title as the commit message. The branch is auto-deleted after merge.
-
Merging to
maintriggers the production deployment pipeline.
Always use the extended push command
The repository includes a large packages/ directory required by Kinsta. The default Git HTTP buffer is too small, so every push must use:
Without this flag, pushes may fail silently or time out.
CI/CD pipelines¶
Four GitHub Actions workflows handle quality checks and deployment.
php.yml -- PR quality gate¶
Runs on every pull request targeting main. This is the gatekeeper -- PRs cannot merge until it passes.
Quality job steps:
- Pint formatting check (
composer lint) - WordPress Coding Standards (
composer lint:phpcs) - PHPStan static analysis (
composer analyse) - ESLint for JavaScript (
npm run lint:js) - Stylelint for SCSS (
npm run lint:scss) - CSS build (
npm run build) with agit diff --exit-codecheck to verify compiled CSS is committed - Translation string check (
scripts/check-translations.sh)
PHPUnit job steps:
- Spins up a MariaDB 10.6 service container
- Runs unit tests (
composer test:unit) - Runs integration tests against the test database
deploy.yml -- reusable deployment workflow¶
A workflow_call workflow that both staging and production pipelines invoke. It accepts an environment input and runs two jobs:
-
Lint & Analyse -- identical to the quality gate (Pint, phpcs, PHPStan).
-
Deploy -- builds production assets and rsyncs to Kinsta:
- Installs production Composer dependencies (
--no-dev --optimize-autoloader) - Builds the design system CSS (
npm run build) - Connects to Kinsta via SSH
- Rsyncs the project, excluding development-only files (
.git/,.github/,docs/,node_modules/, SCSS source, config files, etc.)
- Installs production Composer dependencies (
The deploy job uses GitHub Environment secrets scoped per environment: KINSTA_SSH_PRIVATE_KEY, KINSTA_SSH_HOST, KINSTA_SSH_PORT, KINSTA_SSH_USER, KINSTA_REMOTE_DIR.
Concurrency is enforced per environment -- a new deploy cancels any in-progress deploy for the same target:
cd-production.yml -- production deploy¶
Triggers on push to main and calls deploy.yml with environment: production:
on:
push:
branches:
- main
jobs:
deploy:
uses: ./.github/workflows/deploy.yml
with:
environment: production
secrets: inherit
cd-staging.yml -- staging deploy¶
Identical structure, triggers on push to staging with environment: staging.
What gets deployed¶
The rsync step deploys the full project minus development artifacts. Key exclusions:
.git/,.github/,.claude/-- version control and CI config.env,.env.*-- environment secrets (managed on Kinsta directly)docs/,openspec/,scripts/-- documentation and toolingnode_modules/,package.json,package-lock.json-- frontend build toolingweb/app/themes/naluma-theme/assets/scss/-- SCSS source (compiled CSS is deployed)web/app/uploads/,web/app/cache/,web/app/languages/-- runtime directories managed by Kinsta
Compiled CSS must be committed
The CI quality gate verifies that style.css is up to date with the SCSS source. Always run npm run build locally before committing if you change any SCSS files.
Troubleshooting¶
Push fails or times out. Ensure you are using git -c http.postBuffer=524288000 push. This is required for every push, not just the first one.
CI fails on CSS diff. Run npm run build locally, commit the updated style.css, and push again.
Deploy succeeds but changes are not visible. Kinsta caches aggressively. Clear the site cache from the Kinsta dashboard or wait for the CDN TTL to expire.