CI/CD Pipelines
Understanding Tuturuuu CI/CD pipelines and automated workflows.
Prerequisite: You should have read the Monorepo Architecture page to understand the basic structure of the codebase.
Overview
Tuturuuu uses GitHub Actions for continuous integration and continuous deployment (CI/CD) across our monorepo. These automated workflows help us maintain code quality, run tests, and deploy our applications to various environments.
This page documents the key CI/CD pipelines used in the Tuturuuu platform and how they support our development workflow.
Workflow Categories
Our GitHub Actions workflows are organized into several categories:
1. Application Deployments
Automated deployments to Vercel for our Next.js applications:
- Production deployments (from
production
branch) - Preview deployments (from push events to non-production branches)
2. Database Migrations
Supabase database migration workflows for different environments:
- Production database migrations
- Staging database migrations
- Type generation verification
3. Package Publishing
Workflows that publish our shared packages to NPM, GitHub Packages, and JSR:
- Types package
- UI package
- Supabase client package
- ESLint config package
- TypeScript config package
- AI package
4. Quality Assurance
Workflows that ensure code quality:
- Unit tests
- Prettier formatting checks
- CodeQL security scanning
- CodeCov code coverage reporting
Key Workflows
Application Deployments
We use Vercel for deploying our Next.js applications. The main deployment workflows are:
Production Deployments
When code is pushed to the production
branch, applications are automatically deployed to production:
We have separate production deployment workflows for each application:
vercel-production-platform.yaml
- Main web appvercel-production-nova.yaml
- Nova applicationvercel-production-rewise.yaml
- Rewise applicationvercel-production-calendar.yaml
- Calendar applicationvercel-production-upskii.yaml
- Upskii application
All production workflows follow the same pattern but deploy to different Vercel projects, each with its own environment variables and project ID.
Preview Deployments
For non-production branches, we create preview deployments that allow developers to see their changes live before merging:
Preview deployments are set up for all our applications, providing a temporary deployment URL for each branch.
Database Migrations
We use Supabase for our database, and have automated workflows for managing database migrations:
Production Database Migrations
This workflow is manually triggered (via workflow_dispatch
) to deploy database migrations to production environment. This gives us control over when migrations are applied to production.
Supabase Type Verification
We ensure that generated TypeScript types match our database schema:
This workflow runs on every push, ensuring that our TypeScript types are always in sync with the database schema.
Package Publishing
We publish several packages to make our code reusable across projects. Here’s an example workflow for the types package:
Our package publishing workflows follow a pattern:
- Check for a version bump in the package.json and ensure the PR title follows our convention
- Build and test the package
- Publish to multiple registries (JSR, GitHub Packages, NPM)
We have similar workflows for other packages:
release-ui-package.yaml
release-ai-package.yaml
release-supabase-package.yaml
release-eslint-config-package.yaml
release-typescript-config-package.yaml
Quality Assurance
We use several workflows to ensure code quality:
Unit Tests
This workflow runs on every push to main and on all pull requests, ensuring our tests pass.
Prettier Formatting
We enforce consistent code formatting with Prettier using an automated workflow that can create PRs for formatting fixes:
This workflow not only checks code formatting but also:
- Automatically applies Prettier fixes if formatting issues are found
- Creates a pull request with the fixes
- Adds informative comments to existing PRs if formatting issues are detected
Workflow Organization
Our GitHub Actions workflows are all defined in the .github/workflows
directory of the repository. They follow a consistent naming convention:
Application Deployment Workflows
vercel-production-*.yaml
: Production deployment workflows for each application- Example:
vercel-production-platform.yaml
,vercel-production-nova.yaml
- Example:
vercel-preview-*.yaml
: Preview deployment workflows for each application- Example:
vercel-preview-platform.yaml
,vercel-preview-nova.yaml
- Example:
Database Workflows
supabase-production.yaml
: Production database migrationssupabase-staging.yaml
: Staging database migrationssupabase-types.yaml
: TypeScript type verification
Package Publishing Workflows
release-*-package.yaml
: Package publishing workflows- Example:
release-ui-package.yaml
,release-types-package.yaml
- Example:
Quality Assurance Workflows
turbo-unit-tests.yaml
: Unit test workflowprettier-check.yaml
: Code formatting workflowcodecov.yaml
: Code coverage reportingcodeql.yml
: Security scanning
Other Utilities
check-and-bump-versions.yaml
: Automated dependency version managementexternal-internal-packages.yaml
: Managing external vs internal dependencies
Common Workflow Patterns
Our workflows follow several common patterns:
1. Conditional Execution
Many workflows check if they should run based on certain conditions:
2. Dependency Caching
Most workflows use caching to speed up builds:
3. PR-based Publishing
Package releases are triggered by merged PRs with specific title patterns:
Environment Variables and Secrets
Our workflows use several environment variables and secrets stored in GitHub:
VERCEL_TOKEN
: For deploying to VercelVERCEL_ORG_ID
: Vercel organization IDVERCEL_*_PROJECT_ID
: Project-specific Vercel IDsSUPABASE_ACCESS_TOKEN
: For authenticating with Supabase*_SUPABASE_URL
,*_SUPABASE_ANON_KEY
,*_SUPABASE_SERVICE_KEY
: Environment-specific Supabase credentialsNPM_TOKEN
: For publishing to NPMTIPTAP_PRO_TOKEN
: For accessing Tiptap Pro packagesTURBO_TOKEN
andTURBO_TEAM
: For Turborepo remote caching
Never hard-code sensitive information in workflow files. Always use GitHub Secrets for API tokens, passwords, and other sensitive data.
Remote Caching with Turborepo
We leverage Turborepo’s remote caching feature in our CI pipelines to speed up builds:
This allows our CI jobs to reuse cached build artifacts from previous runs, significantly reducing build times. For large monorepos like ours, this can reduce CI times from 20+ minutes to just a few minutes when the cache is warm.
Best Practices
When working with our CI/CD pipelines, follow these best practices:
1. Test Workflows Locally
Before creating a new workflow, test it locally using act or similar tools.
2. Keep Workflows Focused
Each workflow should have a single responsibility. Split complex workflows into smaller, more focused ones.
3. Reuse Common Steps
Use composite actions or job templates to reuse common steps across workflows.
4. Monitor Workflow Performance
Regularly check workflow runs for performance issues and optimize as needed:
- Use GitHub’s workflow visualization to identify bottlenecks
- Implement caching for dependencies and build artifacts
- Run jobs in parallel when possible
- Skip unnecessary steps with conditional execution
5. Document Workflow Changes
When making significant changes to workflows, document them in pull request descriptions and update this documentation.
Troubleshooting
Common Issues
1. Workflow Timeouts
If a workflow times out, it might be due to:
- Inefficient build process
- Missing cache configuration
- Network issues with external services
Try adding or improving caching strategies and optimizing build steps.
2. Failed Deployments
When deployments fail, check:
- Build logs for errors
- Environment variable configuration
- Access tokens and permissions
3. Authentication Issues
For authentication problems with NPM, GitHub Packages, or Vercel:
- Verify token permissions
- Ensure tokens are not expired
- Check that the token is correctly configured in GitHub Secrets
Creating New Workflows
When creating a new workflow, use this checklist:
- Naming Convention: Follow the established naming patterns
- Trigger Conditions: Define when the workflow should run
- Environment Variables: Include all necessary secrets and variables
- Optimizations: Add caching and conditional execution
- Error Handling: Include appropriate error handling and notifications
- Documentation: Add comments within the workflow file and update documentation