Git Workflow & Automated Testing
Complete guide to branching strategy, commit conventions, automated testing with Bun and Playwright, and semantic releases with GitHub Actions.
Last updated: 11/21/2025
Git Workflow & Automated Testing
Introduction
SveltyCMS uses a comprehensive Git workflow with automated testing and semantic versioning to ensure code quality and streamline the release process. Understanding this workflow is essential for all contributors.
Our CI/CD pipeline uses:
- Bun Tests for fast unit & integration testing (~575 tests)
- Playwright for comprehensive E2E testing (~40 tests)
- Semantic Release for automated versioning
- GitHub Actions for CI/CD automation
- Test Gating to ensure releases only happen when tests pass
- Future: Matrix testing across multiple databases (MongoDB, PostgreSQL, MariaDB, MySQL)
Table of Contents
- Branching Strategy
- Commit Message Convention
- GitHub Actions Workflows
- Automated Testing
- Release Process
- Development Workflow
- Best Practices
Branching Strategy
We have two primary, long-lived branches: main and next.
main Branch (Production)
- Purpose: Production-ready, stable code. This branch represents the latest official release.
- Protection:
- Protected branch requiring pull request reviews
- All code must first be merged into
next - Promoted to
mainonly after thorough testing - Tests must pass before any release is created
- Automated Actions:
- ✅ Runs full Playwright + Bun test suite
- ✅ Only releases if tests pass
- ✅ Creates stable semantic version (e.g.,
v1.3.0) - ✅ Automatically cleans
/config/collectionsdirectory - ✅ Generates changelog and release notes
- Key Rule: This branch must never contain test configurations. The
/config/collectionsdirectory is automatically removed during the release process.
next Branch (Development)
- Purpose: Development and staging. This is the primary branch for all new features, bug fixes, and ongoing work.
- Pull Requests: All contributions should be made to feature branches and then submitted as pull requests targeting
next. - Automated Actions:
- ✅ Runs full test suite on every push
- ✅ Tests both dev and preview modes
- ✅ Matrix testing across multiple browsers
- ✅ No automatic releases (tests only)
- Testing Strategy:
- Every push triggers comprehensive E2E and unit tests
- Tests run in both development and production build modes
- MongoDB service container for database testing
- Automated database seeding before tests
Commit Message Convention
Our automated release process depends on a strict commit message format. We use the Conventional Commits specification. The release automation analyzes these messages to determine if a new version should be released and what the version number should be.
Format
Each commit message consists of a type, a scope (optional), and a subject:
<type>(<scope>): <subject>
[optional body]
[optional footer]
Common Commit Types
| Type | Description | Version Impact | Example |
|---|---|---|---|
feat |
A new feature | MINOR (1.2.0 → 1.3.0) | feat(auth): add OAuth2 login |
fix |
A bug fix | PATCH (1.2.0 → 1.2.1) | fix(api): resolve memory leak |
docs |
Documentation only | None | docs: update installation guide |
style |
Code style changes | None | style: fix indentation |
refactor |
Code refactoring | None | refactor: simplify auth logic |
perf |
Performance improvements | PATCH | perf(db): optimize query speed |
test |
Adding or updating tests | None | test: add collection tests |
chore |
Build/tooling changes | None | chore: update dependencies |
ci |
CI/CD configuration | None | ci: update GitHub Actions |
BREAKING CHANGE |
Breaking API change | MAJOR (1.2.0 → 2.0.0) | See below |
Breaking Changes
To trigger a MAJOR version release, use one of these methods:
Method 1: Add ! after type
feat!: redesign collection API
Method 2: Add BREAKING CHANGE: footer
feat(api): redesign collection endpoints
BREAKING CHANGE: The collection API now uses different parameter names
⚠️ IMPORTANT: If your commit doesn’t use
feat,fix, orBREAKING CHANGE, the automated system will not create a new version.
GitHub Actions Workflows
SveltyCMS uses two main workflows for CI/CD automation.
Workflow 1: Playwright Tests
File: .github/workflows/playwright.yml
Triggers:
- Push to
mainornext - Pull requests to
main - Called by auto-release workflow
What it does:
- Unit Tests Job: Runs Bun unit tests (~350 tests, ~2s)
- Integration Tests Job:
- Starts MongoDB service container
- Cleans
config/directory for fresh state - Starts dev server
- Seeds test database via
scripts/seed-test-db.ts - Runs Bun integration tests (~225 tests, ~15s)
- E2E Tests Job:
- Starts MongoDB service container
- Cleans
config/directory - Installs Playwright browsers
- Starts dev server
- Seeds test database
- Runs Playwright E2E tests (~40 tests, ~60s)
- Uploads test results and artifacts on failure
[!NOTE] Future Enhancement: Matrix testing across multiple databases
strategy: matrix: database: [mongodb, postgresql, mariadb, mysql]This will ensure SveltyCMS works with all supported databases via Drizzle ORM.
Test Matrix:
strategy:
matrix:
browser: [chromium, firefox, webkit]
mode: [dev, preview]
Workflow 2: Auto-Release
File: .github/workflows/auto-release.yaml
Triggers:
- Push to
mainbranch only
What it does:
- Runs tests first (calls
playwright.yml) - Only releases if tests pass
- Cleans
/config/collectionsdirectory - Runs semantic-release (version bump, changelog, GitHub release)
Test Gating:
jobs:
test:
# Run all tests
release:
needs: test # Only runs if tests pass
if: success()
Automated Testing
SveltyCMS uses a dual-testing strategy combining fast unit tests with comprehensive E2E testing.
Testing Architecture
🧪 Bun Tests (Unit & Integration)
- Speed: ⚡ Lightning fast (<5s for full suite)
- Purpose: Business logic, services, widgets, security, API endpoints
- Location:
tests/bun/ - Run:
bun test tests/bun - Framework: Bun Test v1.3.1
🎭 Playwright Tests (E2E)
- Speed: Thorough (30-60s per suite)
- Purpose: User flows, UI interactions, cross-browser
- Location:
tests/playwright/ - Run:
bun x playwright test - Browsers: Chromium, Firefox, WebKit
Current Test Status (November 21, 2025)
- ✅ 403 passing tests (~65%)
- ❌ 172 failing tests (API/Setup integration)
- ⏭️ 40 skipped tests (placeholders)
- 📊 615 total tests
- ⚡ Unit tests: ~2s | Integration: ~15s | E2E: ~60s
Recently Fixed:
- ✅
authorization.test.ts(22 tests) - Fixed mock database adapter - ✅
theme.test.ts(40 tests) - Fixed mockResolve signature - ✅
firewall.test.ts(27 tests) - Fixed logger import - ✅
user.test.ts(Integration) - Fixed auth flow & helpers - ✅
collections.test.ts(Integration) - Fixed dynamic config cleanup - ✅
setup.test.ts(Hooks) - Fixed mocking ofnode:fs& redirects
Fully Passing Test Suites:
- ✅ Security (8/8 tests) - XSS detection, HTML sanitization
- ✅ Widget Validation (8/8 tests) - RichText, form validation
- ✅ Cache System (17/17 tests) - Redis, metrics, multi-tenant
- ✅ UI Components (5/5 tests) - Store management
- ✅ Content Utilities (6/6 tests) - Normalization, helpers
- ✅ Server Hooks (89/89 tests) - All middleware hooks passing
⚠️ API Endpoints (Mixed) - Some integration test failures ❌ Setup Middleware (0/45 tests) - Requires fixes
Running Tests Locally
Quick feedback (recommended):
# Fast unit tests
bun test tests/bun
# Specific test file
bun test tests/bun/services/SecurityResponseService.test.ts
bun test tests/bun/api/user.test.ts
# Specific test suite
bun test tests/bun/api/user.test.ts -t "createUser"
E2E testing:
# All E2E tests
bun x playwright test
# Interactive mode
bun x playwright test --ui
# Specific browser
bun x playwright test --project=chromium
Complete test suite:
# Bun + Playwright
bun run test:all
Test Infrastructure
Test Configuration:
bunfig.toml- Bun test configuration with Svelte preloadtests/bun/svelte-loader.js- Svelte component loadertests/bun/mocks/setup.ts- Environment mocks (500+ lines)playwright.config.ts- E2E test configuration
Test Helpers:
tests/bun/helpers/testSetup.ts- Fixtures, database cleanup, role resolutiontests/bun/helpers/server.ts- Server wait utility (prevents timeouts)tests/bun/helpers/auth.ts- Real authentication helpers (FormData support)tests/bun/helpers/db-helper.ts- API-based verification (no direct DB access)tests/bun/mocks/setup.ts- Comprehensive environment mocking
Mocked Services:
- SvelteKit environment (
$app/environment) - Global settings (
publicEnv,privateEnv) - Svelte 5 runes (
$state,$derived,$effect) - Widget factory with 30+ widgets
- Paraglide i18n messages (100+ translations)
- Setup wizard store
- Skeleton UI components
CI Integration:
- Tests run on every push to
mainandnext - Release blocked if tests fail
- Matrix testing across 3 browsers × 2 modes = 6 configurations
- MongoDB service container for E2E tests
- Automatic database seeding
Release Process
Complete Flow
Development (→ next):
- Create feature branch from ‘next’
git checkout -b feat/my-feature next - Make changes with conventional commits
git commit -m "feat(auth): add OAuth2 support" - Push and create PR to ‘next’
git push origin feat/my-feature - Tests run automatically (Bun + Playwright)
- Merge after approval
- Tests must pass
- PR requires approval
- Tests run on ‘next’ (no release created)
Release (→ main):
- Create PR from ‘next’ to ‘main’
- Ensure all features are stable
- Review CHANGELOG
- Tests run automatically
- Full Playwright suite
- All Bun tests
- Matrix testing
- Merge after approval
- Requires maintainer approval
- All checks must pass
- Tests run on ‘main’
- Complete test suite
- Database seeding
- Cross-browser testing
- If tests pass:
- ✅ semantic-release analyzes commits
- ✅ Determines version bump
- ✅ Updates
package.json - ✅ Generates
CHANGELOG.md - ✅ Creates GitHub release
- ✅ Cleans
/config/collections
- If tests fail:
- ❌ No release created
- ❌ Maintainers notified
- ❌ Fix required before retry
Version Determination
Based on commit messages since last release:
| Commits | Version Change | Example |
|---|---|---|
fix: only |
PATCH | 1.2.0 → 1.2.1 |
feat: present |
MINOR | 1.2.0 → 1.3.0 |
BREAKING CHANGE: or ! |
MAJOR | 1.2.0 → 2.0.0 |
No feat/fix/BREAKING |
No release | - |
Development Workflow
Step-by-Step Guide
1. Start a new feature:
# Update local next branch
git checkout next
git pull origin next
# Create feature branch
git checkout -b feat/my-feature
# Or for bug fix
git checkout -b fix/bug-description
2. Make changes:
# Write code
# Add tests
# Run tests locally
bun test
bun x playwright test
# Commit with conventional format
git add .
git commit -m "feat(auth): add OAuth2 support"
3. Push and create PR:
# Push to remote
git push origin feat/my-feature
# Create PR to 'next' on GitHub
# - Fill in PR template
# - Link related issues
# - Request reviewers
4. Address review comments:
# Make changes
git add .
git commit -m "fix(auth): address review comments"
# Push updates
git push origin feat/my-feature
5. Merge and cleanup:
# After PR is merged
git checkout next
git pull origin next
# Delete feature branch
git branch -d feat/my-feature
git push origin --delete feat/my-feature
Best Practices
Commit Messages
✅ Good Examples:
feat(auth): add OAuth2 supportfix(api): resolve memory leak in user endpointdocs: update testing guidetest(user): add avatar upload testsperf(cache): optimize Redis queriesrefactor(widget): simplify factory logic
❌ Bad Examples:
fixed stuffWIPchangesupdateasdf
Pull Requests
Before creating a PR:
- ✅ Run tests locally (
bun test) - ✅ Update relevant documentation
- ✅ Add tests for new features
- ✅ Follow code style guidelines
- ✅ Use conventional commit messages
PR Guidelines:
- Keep PRs focused and small (< 500 lines preferred)
- Write clear descriptions
- Link related issues
- Respond to reviews promptly
- Ensure CI passes before requesting review
Testing
Test-Driven Development:
# 1. Write failing test
bun test tests/bun/api/my-feature.test.ts
# 2. Implement feature
# ... code ...
# 3. Verify test passes
bun test tests/bun/api/my-feature.test.ts
# 4. Run full suite
bun test
Before pushing:
# Run all tests
bun test tests/bun
# Run E2E tests for affected features
bun x playwright test tests/my-feature.spec.ts
# Check for linting errors
bun run lint
Troubleshooting
Tests Failing in CI but Passing Locally
Common causes:
- Different Node/Bun versions
- Solution: Use
.nvmrcor check CI version
- Solution: Use
- Missing environment variables
- Solution: Check GitHub Secrets configuration
- Database state issues
- Solution: Ensure tests clean up properly
- Timing issues
- Solution: Use
waitForServer()helper
- Solution: Use
Release Not Created
Check:
- Did tests pass?
- View GitHub Actions logs
- Did commits use conventional format?
- Must have
feat:,fix:, orBREAKING CHANGE:
- Must have
- Are you on
mainbranch?- Releases only happen on
main
- Releases only happen on
- Is semantic-release configured?
- Check
.releasercconfiguration
- Check
Related Documentation
- Test Status Report - Current test coverage and status
- User API Tests - Complete user API test documentation
- Contributing Guide - How to contribute
- Troubleshooting - Common issues
Follow these workflows for smooth development and reliable releases! 🚀