Skip to main content
The project uses a three-branch model with Conventional Commits and semantic-release for automated versioning.

Branch strategy

Branch protection rules

main

  • Require pull request reviews (code owner approval)
  • Require status checks to pass (enforced by enforce-preview-branch.yml)
  • Only preview branch may open a PR to main — any other source is rejected by the enforce-preview-branch.yml workflow
  • Direct pushes disabled

preview

  • Require CI to pass (unit-tests and lighthouse jobs in ci.yml)
  • PRs from main are blocked by enforce-preview-source.yml (the sync-preview.yml workflow handles that direction automatically)
  • Direct pushes disabled

Commit format

Keep the description short and in the imperative mood (“add”, “fix”, “update” — not “added”, “fixed”, “updated”).

Conventional commit types

Breaking changes can be indicated two ways:
  • feat!: rename block prop interface
  • feat: rename block prop interface\n\nBREAKING CHANGE: Props renamed from camelCase to snake_case
Both trigger a major version bump.

PR flow

1

Branch from preview

Always start from the latest preview branch:
2

Commit with conventional format

Each commit message must start with a recognized type prefix followed by a colon and space.
3

Open PR to preview

CI runs automatically:
  • unit-tests job: all Vitest tests must pass
  • lighthouse job: Lighthouse CI runs against the built site
  • enforce-preview-source.yml: confirms the source is not main
4

Merge to preview

After CI passes, merge the PR. The feature branch can be deleted.
5

Open PR to main

When the staging environment looks good:
The enforce-preview-branch.yml workflow verifies the source is preview. A code owner review is required.
6

Merge to main → release happens automatically

On merge:
  1. release.yml runs semantic-release → version bump, CHANGELOG, GitHub Release
  2. sync-preview.yml merges main back into preview
  3. Discord notification confirms the sync

Common examples

Why this workflow

preview as integration buffer

All feature branches merge to preview first. This catches integration issues before they reach production. The preview branch also doubles as the staging environment (SSR + Visual Editing ON).

Automated releases

semantic-release eliminates manual version management. The version number is derived from the commit history, making it impossible to forget a version bump or write inconsistent changelog entries.

CI gate

Unit tests and Lighthouse CI run on every PR to preview. Performance regressions are caught before they land in the staging environment, let alone production.

Discord visibility

The sync notification tells the whole team when preview is safe to branch from again after a release. No need to check the Actions tab.

Troubleshooting

PR from feature branch to main blocked: Open a PR to preview first, not directly to main. The enforce-preview-branch.yml workflow blocks all non-preview sources. PR from main to preview blocked: The enforce-preview-source.yml workflow blocks this direction. It is handled automatically by sync-preview.yml after every release. No manual PR is needed. sync-preview fails with merge conflict: A manual merge is required. Checkout preview, merge origin/main, resolve conflicts, and push. Then manually trigger the Discord notification or post an update to the team. semantic-release creates no release: All commits since the last tag use non-release prefixes (chore:, docs:, ci:, test:, refactor:). Add at least one feat: or fix: commit to trigger a release.