The CI workflow (ci.yml) runs automated checks on pull requests and feature branch pushes to ensure code quality before merging to main.
- Pull Requests to
mainbranch - Pushes to feature branches (any branch except
main)
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: trueBenefit: When you push new commits, outdated CI runs are automatically cancelled, saving compute resources and providing faster feedback.
- Format Check (workspace-wide)
- Lint (affected packages only)
- Type Check (affected packages only)
- Test (affected packages only)
- Build (affected packages only)
Packages automatically participate in checks by defining the corresponding script in their package.json. Turborepo naturally skips packages that don't have the script.
This is the recommended approach - no special flags or configuration needed.
A package that wants all checks:
{
"name": "@marshant/web",
"scripts": {
"lint": "eslint .",
"typecheck": "tsc --noEmit",
"test": "vitest run",
"build": "next build"
}
}Result: All 4 checks run when this package is affected by changes.
A package that only needs type checking and building:
{
"name": "@marshant/sdk",
"scripts": {
"typecheck": "tsc --noEmit",
"build": "tsup"
}
}Result: Only typecheck and build run. lint and test are automatically skipped (no error).
A package with no checks (e.g., documentation-only):
{
"name": "@marshant/docs",
"scripts": {
"dev": "vitepress dev"
}
}Result: Package is skipped for all checks (no error).
The workflow uses Turborepo's --filter='...[origin/main]' to run checks only on packages affected by changes.
A package is considered affected if:
- Its source code changed
- A dependency's code changed
- Its
package.jsonchanged - Any file it depends on changed
Use consistent script names across packages:
{
"scripts": {
"lint": "eslint .", // Consistent across all packages
"typecheck": "tsc --noEmit", // Consistent across all packages
"test": "vitest run", // Consistent across all packages
"build": "..." // Tool may vary (next, tsup, vite, etc.)
}
}Developers can run the same checks locally:
# Run checks on all packages
pnpm run lint
pnpm run typecheck
pnpm run test
pnpm run build
# Run checks on affected packages only (faster)
pnpm exec turbo lint --filter='...[origin/main]'
pnpm exec turbo typecheck --filter='...[origin/main]'
pnpm exec turbo test --filter='...[origin/main]'
pnpm exec turbo build --filter='...[origin/main]'
# Run checks on a specific package
pnpm exec turbo lint --filter=@marshant/web
pnpm exec turbo build --filter=@marshant/sdkTo add a new check (e.g., validate):
- Add to workflow (
.github/workflows/ci.yml):
- name: Validate affected packages
run: pnpm exec turbo validate --filter='...[origin/main]' --continue- Add to packages that need it:
{
"scripts": {
"validate": "your-validation-command"
}
}- Packages without the script are automatically skipped.