Continuous Integration (CI)
debt(d3/e5/b7/t5)
Closest to 'default linter catches the common case' (d3). The detection_hints.tools list includes github-actions, gitlab-ci, circleci, phpunit, and phpstan — these platforms surface CI failures immediately and visibly in pull request checks. Missing CI configuration or failing pipelines are caught automatically by these platforms with clear feedback, though detecting whether you're doing 'true CI' (daily merges to main) vs just running tests on branches requires process review.
Closest to 'touches multiple files / significant refactor in one component' (e5). The quick_fix suggests a straightforward pipeline setup (composer install, PHPStan, phpcs, phpunit), but implementing CI properly requires configuring pipeline files, adjusting test suites to run reliably in CI, setting up branch protection rules, and potentially refactoring slow tests. If CI was never set up, it's a multi-file effort; if it's misconfigured (long-lived branches, slow pipelines), fixing it may require test refactoring.
Closest to 'strong gravitational pull' (b7). CI applies across all contexts (web, cli, queue-worker) per the term metadata. Once established, CI shapes every developer's workflow — every commit, every PR, every merge is affected. The pipeline configuration becomes a load-bearing part of the development process. Poor CI choices (slow pipelines, flaky tests) impose a persistent tax on all work streams, and changing CI strategy affects the entire team's workflow.
Closest to 'notable trap' (t5). The misconception field explicitly states the trap: 'Having a CI server running means you're doing CI' when true CI requires daily merges to main with gated automated tests. This is a documented gotcha that many teams eventually learn — running tests on long-lived feature branches for weeks isn't CI, it's just automated testing. The common_mistakes reinforce this: treating CI as optional, running it only on main branch, accepting slow pipelines.
Also Known As
TL;DR
Explanation
CI (continuous integration) requires developers to integrate code frequently (at least daily) into a shared branch, with automated pipelines that run tests, static analysis, and build checks on every push. Fast feedback (minutes) prevents branches from diverging far and makes integration failures cheap to fix. A PHP CI pipeline typically includes: Composer install, PHP_CodeSniffer/PHP-CS-Fixer, PHPStan/Psalm, PHPUnit, and optionally security audit. GitHub Actions, GitLab CI, Jenkins, and CircleCI are common platforms.
Diagram
flowchart LR
DEV[Developer] -->|git push| GIT[(Git Repo)]
GIT -->|webhook| CI[CI Pipeline]
CI --> LINT[Lint & Style]
LINT --> TEST[Unit Tests]
TEST --> ANALYSIS[Static Analysis]
ANALYSIS --> BUILD[Build Artifact]
BUILD -->|pass| NOTIFY[Green]
LINT & TEST & ANALYSIS -->|fail| FAIL[Notify Dev]
style NOTIFY fill:#238636,color:#fff
style FAIL fill:#f85149,color:#fff
style BUILD fill:#238636,color:#fff
Common Misconception
Why It Matters
Common Mistakes
- Running CI only on the main branch — feature branches need the same checks before merge.
- Having a CI pipeline that takes 30+ minutes — developers stop waiting for it and merge blind.
- Treating a failing CI as optional to fix — a broken main branch blocks the entire team.
- Not running the same checks locally that CI runs — "it passes on my machine" becomes "it fails on CI".
Avoid When
- Merging to main without a passing CI build — a broken main blocks the entire team.
- CI pipelines that take more than 10 minutes — slow pipelines get bypassed; keep the fast feedback loop fast.
- Only running CI on pull requests — also run on main to catch integration bugs that pass review.
- Treating CI failures as optional — a red build must block deployment and be fixed before other work continues.
When To Use
- Every commit to a shared branch — automated tests catch regressions before they reach other developers.
- Running the full test suite, linting, static analysis, and security scans automatically on every push.
- Gating pull request merges on a passing CI run — enforce the rule with branch protection.
- Generating build artefacts and publishing coverage reports on every successful run.
Code Examples
// No CI — integration happens at release time:
// Dev A works on branch for 3 weeks
// Dev B works on branch for 3 weeks
// Both merge to main: 847 conflicts, 12 test failures
// 2 days to resolve — 'integration hell'
// With CI:
// Both merge small changes daily
// Pipeline: lint → test → build on every push
// Conflicts caught same day — trivial to resolve
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with: { php-version: '8.3', coverage: xdebug }
- run: composer install --no-progress
- run: vendor/bin/phpcs --standard=PSR12 src/
- run: vendor/bin/phpstan analyse src/ --level=6
- run: vendor/bin/phpunit --coverage-clover=coverage.xml
- run: composer audit