7 min read • Guide 309 of 877
Continuous Integration Best Practices
Continuous Integration means merging code frequently and validating each merge automatically. Good CI catches bugs early, enables confident refactoring, and keeps the main branch always releasable. This guide covers practical CI implementation.
CI Pipeline Stages
| Stage | Purpose | Time Target |
|---|---|---|
| Lint | Code style | <1 min |
| Unit tests | Logic verification | <5 min |
| Build | Compilation | <3 min |
| Integration | Component interaction | <10 min |
| Security | Vulnerability scan | <5 min |
Pipeline Structure
Essential Stages
CI PIPELINE STAGES
══════════════════
STAGE 1: LINT & FORMAT
─────────────────────────────────────
Purpose: Consistent code style
Tools: ESLint, Prettier, Black, etc.
Time: <1 minute
Checks:
├── Code formatting
├── Style rules
├── Import ordering
├── No unused variables
└── Catch issues before review
STAGE 2: UNIT TESTS
─────────────────────────────────────
Purpose: Logic verification
Tools: Jest, PyTest, JUnit, etc.
Time: <5 minutes
Run:
├── All unit tests
├── Fast, isolated tests
├── No external dependencies
├── High coverage areas
└── Quick feedback
STAGE 3: BUILD
─────────────────────────────────────
Purpose: Verify compilation
Tools: Webpack, tsc, cargo, etc.
Time: <3 minutes
Verify:
├── Code compiles
├── Dependencies resolve
├── Assets generated
├── Build artifacts created
└── Can produce output
STAGE 4: INTEGRATION TESTS
─────────────────────────────────────
Purpose: Component interaction
Tools: Test frameworks + test DB/services
Time: <10 minutes
Test:
├── API endpoints
├── Database operations
├── Service interactions
├── Key flows
└── Realistic scenarios
STAGE 5: SECURITY SCAN
─────────────────────────────────────
Purpose: Find vulnerabilities
Tools: Snyk, OWASP, npm audit, etc.
Time: <5 minutes
Scan:
├── Dependency vulnerabilities
├── Code security issues
├── Secret detection
├── License compliance
└── Security gates
Pipeline Configuration
EXAMPLE CI CONFIGURATION
════════════════════════
GITHUB ACTIONS EXAMPLE:
─────────────────────────────────────
name: CI
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npm test
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npm run build
integration:
runs-on: ubuntu-latest
needs: [lint, test, build]
steps:
- uses: actions/checkout@v3
- run: npm ci
- run: npm run test:integration
PARALLEL EXECUTION:
─────────────────────────────────────
├── Lint, Test, Build run in parallel
├── Integration runs after all pass
├── Faster overall pipeline
├── Early failure, early feedback
└── Optimize for speed
Fast Feedback
Speed Matters
CI SPEED OPTIMIZATION
═════════════════════
WHY SPEED MATTERS:
─────────────────────────────────────
Slow CI:
├── Developers wait
├── Switch to other work
├── Context switch cost
├── Batch up changes
├── Find issues late
└── Frustration
Fast CI:
├── Immediate feedback
├── Fix while context fresh
├── More frequent commits
├── Catch issues early
├── Developer happiness
└── Higher quality
SPEED TARGETS:
─────────────────────────────────────
├── Lint: <1 minute
├── Unit tests: <5 minutes
├── Full pipeline: <10 minutes
├── Absolute max: 15 minutes
└── Faster is better
OPTIMIZATION STRATEGIES:
─────────────────────────────────────
Caching:
├── Cache dependencies
├── Cache build artifacts
├── Cache test fixtures
├── Reuse what doesn't change
└── Significant speedup
Parallelization:
├── Run independent stages parallel
├── Split test suites
├── Multiple runners
├── Reduce wall-clock time
└── Use available resources
Test optimization:
├── Fast unit tests (most)
├── Fewer integration tests
├── Slowest tests last
├── Skip unchanged areas
└── Testing pyramid
Maintaining Green
Always Releasable
KEEPING CI GREEN
════════════════
RULE: FIX BROKEN BUILDS IMMEDIATELY
─────────────────────────────────────
When CI fails:
├── Stop other work
├── Fix immediately
├── Or revert the change
├── Team's top priority
└── Broken build = blocked team
RESPONSIBILITY:
─────────────────────────────────────
Who broke it fixes it:
├── Your commit, your fix
├── Fast response
├── Don't leave for later
├── Don't ignore
└── Ownership
AVOID BROKEN BUILDS:
─────────────────────────────────────
Prevention:
├── Run tests locally first
├── Small, frequent commits
├── Thorough code review
├── Pre-commit hooks
└── Catch before push
Pre-commit:
├── Lint check
├── Format check
├── Quick unit tests
├── Catch obvious issues
└── Faster feedback
GREEN = RELEASABLE:
─────────────────────────────────────
Main branch should always be:
├── Buildable
├── Tests passing
├── Deployable
├── Production-ready
└── Ship any time
Integration Frequency
Merge Often
FREQUENT INTEGRATION
════════════════════
MERGE DAILY (AT LEAST):
─────────────────────────────────────
Best practice:
├── Multiple merges per day
├── Small changes each time
├── Never more than 1 day without merge
├── Long branches = integration problems
└── Continuous means continuous
SMALL CHANGES:
─────────────────────────────────────
Benefits of small:
├── Easier to review
├── Less likely to conflict
├── Problems isolated
├── Easy to revert
├── Faster feedback
└── Lower risk
FEATURE FLAGS:
─────────────────────────────────────
Merge incomplete features:
├── Code deployed but inactive
├── Flag controls visibility
├── Integrate continuously
├── Enable when ready
└── Decouple deploy from release
Example:
├── Merge auth code (flag off)
├── Continue development
├── Keep integrating
├── Enable flag when complete
├── Users never see incomplete
Quality Gates
Required Checks
CI QUALITY GATES
════════════════
REQUIRED FOR MERGE:
─────────────────────────────────────
☐ All tests passing
☐ Lint clean
☐ Build succeeds
☐ Coverage threshold met
☐ Security scan clean
☐ Code review approved
└── All must pass to merge
BRANCH PROTECTION:
─────────────────────────────────────
GitHub settings:
├── Require status checks
├── Require up-to-date branches
├── Require review approval
├── No force push to main
├── No direct commits to main
└── Enforce quality
COVERAGE THRESHOLDS:
─────────────────────────────────────
Set minimum:
├── 80% overall coverage
├── No decrease from baseline
├── New code must be covered
├── Fail build if below
└── Maintain quality over time
SECURITY GATES:
─────────────────────────────────────
├── No critical vulnerabilities
├── No high without exception
├── Known CVE blocking
├── Secret detection
└── Security non-negotiable
GitScrum CI Integration
Connected Workflow
GITSCRUM + CI INTEGRATION
═════════════════════════
LINK TO TASKS:
─────────────────────────────────────
PR linked to task:
├── CI status visible on task
├── Auto-update on CI completion
├── Merge → Task status update
└── Connected context
AUTOMATED TRANSITIONS:
─────────────────────────────────────
CI events trigger:
├── PR merged → Task to "Done"
├── CI failed → Alert on task
├── Deploy complete → Notify
└── Workflow automation
VISIBILITY:
─────────────────────────────────────
Dashboard:
├── CI status widget
├── Failed builds visible
├── Deploy status
├── Team awareness
└── Problems surface quickly
COMMIT LINKING:
─────────────────────────────────────
Commit message: "GS-123: Add login"
├── Links to task automatically
├── Progress visible
├── History tracked
└── Traceability
Best Practices
For CI
- Fast pipelines — Under 10 minutes
- Fix immediately — Broken builds are priority 1
- Merge frequently — Daily minimum
- Quality gates — Required checks before merge
- Green always — Main is always releasable
Anti-Patterns
CI MISTAKES:
✗ Slow pipelines (30+ minutes)
✗ Ignoring failures
✗ Long-running branches
✗ Skipping tests
✗ No branch protection
✗ Manual deployments
✗ Flaky tests tolerated
✗ "Works on my machine"