Skip to content

Commit d08c72b

Browse files
committed
fix: Update CI
1 parent 3ab1426 commit d08c72b

1 file changed

Lines changed: 299 additions & 36 deletions

File tree

content/MinimumCD/CI/_index.md

Lines changed: 299 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,334 @@
11
---
22
title: Continuous Integration
3-
description: Start here
3+
description: Integrate work to trunk at least daily with automated testing
44
weight: 2
55
type: docs
66
---
77

88
## Definition
99

10-
While CI depends on tooling, the team workflow and working agreement are more important.
10+
Continuous Integration (CI) is the activity of each developer integrating work to the trunk of version control at least daily and verifying that the work is, to the best of our knowledge, releasable.
1111

12-
1. We will work as a team to define work with [testable acceptance criteria](https://dojoconsortium.org/docs/work-decomposition/behavior-driven-development/). Those acceptance criteria will drive our testing efforts.
13-
2. No work will be committed to version control unless accompanied by all required tests.
14-
3. Work committed to version control may not be "feature complete", but it must not break existing work.
15-
4. All work begins from the trunk and integrates into the trunk at least daily.
16-
5. If the CI server detects an error, the team stops feature work and collaborates to fix the build. We should not create more unverified changes without the ability to receive quality feedback from the CI server.
12+
CI is not just about tooling—it's fundamentally about team workflow and working agreements.
1713

18-
## Recommended practices
14+
### The minimum activities required for CI
1915

20-
Evolutionary coding methods:
16+
1. [Trunk-based development](/minimumcd/tbd/) - all work integrates to trunk
17+
2. Work integrates to trunk at a minimum daily (each developer, every day)
18+
3. Work has automated testing before merge to trunk
19+
4. Work is tested with other work automatically on merge
20+
5. All feature work stops when the build is red
21+
6. New work does not break delivered work
2122

22-
- [Branch by abstraction](https://www.branchbyabstraction.com/) is a good process for replacing existing new behaviors or frameworks with something new while constantly delivering. Also, a good pattern to use for A/B testing
23-
- [Feature flags](https://martinfowler.com/articles/feature-toggles.html) can be temporary tools for feature release management or permanent tools for enabling behaviors for different personas. They can also be controlled with application configuration or dynamically with logic.
23+
## Why This Matters
24+
25+
### Without CI, Teams Experience
26+
27+
- **Integration hell**: Weeks or months of painful merge conflicts
28+
- **Late defect detection**: Bugs found after they're expensive to fix
29+
- **Reduced collaboration**: Developers work in isolation, losing context
30+
- **Deployment fear**: Large batches of untested changes create risk
31+
- **Slower delivery**: Time wasted on merge conflicts and rework
32+
- **Quality erosion**: Without rapid feedback, technical debt accumulates
33+
34+
### With CI, Teams Achieve
35+
36+
- **Rapid feedback**: Know within minutes if changes broke something
37+
- **Smaller changes**: Daily integration forces better work breakdown
38+
- **Better collaboration**: Team shares ownership of the codebase
39+
- **Lower risk**: Small, tested changes are easier to diagnose and fix
40+
- **Faster delivery**: No integration delays blocking deployment
41+
- **Higher quality**: Continuous testing catches issues early
42+
43+
## Team Working Agreements
44+
45+
While CI depends on tooling, the team workflow and working agreement are more important:
46+
47+
1. **Define testable work**: Work includes [testable acceptance criteria](https://dojoconsortium.org/docs/work-decomposition/behavior-driven-development/) that drive testing efforts
48+
2. **Tests accompany commits**: No work committed to version control without required tests
49+
3. **Incremental progress**: Committed work may not be "feature complete", but must not break existing work
50+
4. **Trunk-based workflow**: All work begins from trunk and integrates to trunk at least daily
51+
5. **Team commitment**: If CI detects an error, the team stops feature work and collaborates to fix the build
52+
53+
## Example Implementations
54+
55+
### Anti-Pattern: Feature Branch Workflow Without CI
56+
57+
```text
58+
Developer A: feature-branch-1 (3 weeks of work)
59+
Developer B: feature-branch-2 (2 weeks of work)
60+
Developer C: feature-branch-3 (4 weeks of work)
61+
62+
Week 4: Merge conflicts, integration issues, broken tests
63+
Week 5: Still fixing integration problems
64+
Week 6: Finally stabilized, but lost 2 weeks to integration
65+
```
66+
67+
**Problems:**
68+
69+
- Long-lived branches accumulate merge conflicts
70+
- Integration issues discovered late
71+
- No early feedback on compatibility
72+
- Large batches of untested changes
73+
- Team blocked while resolving conflicts
74+
75+
### Good Pattern: Continuous Integration to Trunk
76+
77+
```yaml
78+
# .github/workflows/ci.yml
79+
name: Continuous Integration
80+
81+
on:
82+
push:
83+
branches: [main]
84+
pull_request:
85+
branches: [main]
86+
87+
jobs:
88+
test:
89+
runs-on: ubuntu-latest
90+
steps:
91+
- uses: actions/checkout@v3
92+
93+
- name: Install dependencies
94+
run: npm ci
95+
96+
- name: Run unit tests
97+
run: npm test
98+
99+
- name: Run integration tests
100+
run: npm run test:integration
101+
102+
- name: Code quality checks
103+
run: npm run lint
104+
105+
- name: Security scan
106+
run: npm audit
107+
108+
- name: Build application
109+
run: npm run build
110+
111+
notify-on-failure:
112+
needs: test
113+
if: failure()
114+
runs-on: ubuntu-latest
115+
steps:
116+
- name: Notify team
117+
run: |
118+
echo "Build failed - stop feature work and fix!"
119+
# Send Slack/email notification
120+
```
121+
122+
**Benefits:**
123+
124+
- Changes tested within minutes
125+
- Team gets immediate feedback
126+
- Small changes are easy to debug
127+
- Integration is never a surprise
128+
- Quality maintained continuously
129+
130+
## Evolutionary Coding Practices
131+
132+
To integrate code daily while building large features, use these patterns:
133+
134+
### Branch by Abstraction
135+
136+
Gradually replace existing behavior while continuously integrating:
137+
138+
```javascript
139+
// Step 1: Create abstraction (integrate to trunk)
140+
class PaymentProcessor {
141+
process(payment) {
142+
return this.implementation.process(payment)
143+
}
144+
}
145+
146+
// Step 2: Add new implementation alongside old (integrate to trunk)
147+
class StripePaymentProcessor {
148+
process(payment) {
149+
// New Stripe implementation
150+
}
151+
}
152+
153+
// Step 3: Switch implementations (integrate to trunk)
154+
const processor = useNewStripe
155+
? new StripePaymentProcessor()
156+
: new LegacyProcessor()
157+
158+
// Step 4: Remove old implementation (integrate to trunk)
159+
```
160+
161+
### Feature Flags
162+
163+
Control feature visibility without blocking integration:
164+
165+
```javascript
166+
// Incomplete feature integrated to trunk, hidden behind flag
167+
if (featureFlags.newCheckout) {
168+
return renderNewCheckout() // Work in progress
169+
}
170+
return renderOldCheckout() // Stable existing feature
171+
172+
// Team can continue integrating newCheckout code daily
173+
// Feature revealed when complete by toggling flag
174+
```
175+
176+
### Connect Last
177+
178+
Build complete features, connect them in final commit:
179+
180+
```javascript
181+
// Commits 1-10: Build new checkout components (all tested, all integrated)
182+
function CheckoutStep1() { /* tested, working */ }
183+
function CheckoutStep2() { /* tested, working */ }
184+
function CheckoutStep3() { /* tested, working */ }
185+
186+
// Commit 11: Wire up to UI (final integration)
187+
<Route path="/checkout" component={CheckoutStep1} />
188+
```
189+
190+
For detailed guidance on when to use each pattern, see [Feature Flags](/recommendations/featureflags/).
191+
192+
## What Tests Should Run
193+
194+
### Pre-Merge (Fast Feedback)
195+
196+
Run before code merges to trunk:
197+
198+
- **Unit tests**: Test individual components in isolation
199+
- **Linting**: Code style and quality checks
200+
- **Static security scans**: SAST tools checking for vulnerabilities
201+
- **Dependency audits**: Known vulnerabilities in dependencies
202+
203+
**Goal**: Complete in < 10 minutes
204+
205+
### Post-Merge (Comprehensive Validation)
206+
207+
Run after code merges to trunk:
208+
209+
- **Integration tests**: Test component interactions
210+
- **Functional tests**: Test user-facing behavior
211+
- **Performance tests**: Ensure no regressions
212+
- **Security tests**: Dynamic security analysis
213+
214+
**Goal**: Complete in < 30 minutes
215+
216+
### What About Deployment Testing?
217+
218+
Tests requiring deployment (end-to-end, smoke tests) are part of the [deployment pipeline](/minimumcd/singlepath/), not CI.
24219

25220
## What is Improved
26221

27-
- **Teamwork:** CI requires a lot of teamwork to function correctly. If the team currently uses a "push" workflow where work is assigned instead of a "pull" workflow where the next most important work is picked up by the next available teammate, then CI will be very difficult. Teamwork suffers because everyone is focused on their individual "assignments" rather than team goals. Long delays in code review, large changesets, and excessive process hurt outcomes. Find a cadence for code review to process them quickly and set some team norms on changeset size and collaboration. Pair programming is a good way to help address these problems quickly.
28-
- **Work Breakdown:** We need to [break down work better](https://dojoconsortium.org/docs/work-decomposition/work-breakdown/). We should have a "Definition of Ready" that requires every story and task has a testable description of "done" before any work starts. A good rule of thumb is that if everyone agrees the team can complete that item in less than 2 days, it's refined enough for CI.
29-
- **Testing:** This is a common struggle. It's common that teams either do not test or know little about basic unit testing. Testing implementation instead of behavior is another common issue. Teams will need to improve the efficiency and effectiveness of their tests and build a suite of various types of tests with the goal of moving detection as close to creation as possible. CI requires falling passionately in love with testing, but that should be true of software engineering anyway.
222+
### Teamwork
30223

31-
## Health Metrics
224+
CI requires strong teamwork to function correctly. Key improvements:
225+
226+
- **Pull workflow**: Team picks next important work instead of working from assignments
227+
- **Code review cadence**: Quick reviews (< 4 hours) keep work flowing
228+
- **Pair programming**: Real-time collaboration eliminates review delays
229+
- **Shared ownership**: Everyone maintains the codebase together
230+
- **Team goals over individual tasks**: Focus shifts from "my work" to "our progress"
231+
232+
**Anti-pattern**: "Push" workflow where work is assigned creates silos and delays.
233+
234+
### Work Breakdown
235+
236+
CI forces better work decomposition:
237+
238+
- **Definition of Ready**: Every story has testable acceptance criteria before work starts
239+
- **Small batches**: If the team can complete work in < 2 days, it's refined enough
240+
- **Vertical slicing**: Each change delivers a thin, tested slice of functionality
241+
- **Incremental delivery**: Features built incrementally, each step integrated daily
32242

33-
- **Commits/Day/Developer**: How frequently are we as a team integrating code to the trunk each day? "Good" is 1 or more per day per dev. Never compare individuals. this is a team average.
34-
- **Development cycle time**: The time from when work begins to being completed. "Good" is less than 2 days on average.
35-
- **Defect rate**: A critical guardrail metric to ensure speed does not overtake quality and vice versa.
243+
See [Work Breakdown](https://dojoconsortium.org/docs/work-decomposition/work-breakdown/) for detailed guidance.
36244

37-
## FAQ
245+
### Testing
246+
247+
CI requires a shift in testing approach:
248+
249+
**From**: Writing tests after code is "complete"
250+
**To**: Writing tests before/during coding (TDD/BDD)
251+
252+
**From**: Testing implementation details
253+
**To**: Testing behavior and outcomes
254+
255+
**From**: Manual testing before deployment
256+
**To**: Automated testing on every commit
257+
258+
**From**: Separate QA phase
259+
**To**: Quality built into development
260+
261+
CI teams build a comprehensive test suite with the goal of detecting issues as close to creation as possible. See [Behavior-Driven Development](https://dojoconsortium.org/docs/work-decomposition/behavior-driven-development/).
262+
263+
## Common Challenges
38264

39265
### "What are the main problems to overcome?"
40266

41-
1. Poor teamwork, usually driven by assigning work instead of using a pull system.
42-
2. Lack of proper testable acceptance criteria. This is made worse by #1 because everyone will be focused on their individual assignments instead of the team's goals. [BDD](https://dojoconsortium.org/docs/work-decomposition/behavior-driven-development/) is the best way to get to true, declarative functional tests that everyone understands. Coding should be driven by those tests.
43-
3. Lack of knowledge of evolutionary coding practices. "I can't commit until the feature is complete!" We need to break those changes down to the level where we can commit a passing unit test. Branch by abstraction, feature flags, or just planning changes so that the last change integrates the feature with the rest of the application.
267+
1. **Poor teamwork**: Usually driven by assigning work instead of using a pull system
268+
2. **Lack of testable acceptance criteria**: Made worse by individual assignments instead of team goals. [BDD](https://dojoconsortium.org/docs/work-decomposition/behavior-driven-development/) provides declarative functional tests everyone understands
269+
3. **Lack of evolutionary coding knowledge**: "I can't commit until the feature is complete!" Use branch by abstraction, feature flags, or plan changes so the last change integrates the feature
44270

45271
### "How do I complete a large feature in less than a day?"
46272

47-
You probably don't. However, there are several strategies available for making evolutionary changes that build toward the complete feature. See [Recommended practices](#recommended-practices).
273+
You probably don't complete it in a day, but you integrate progress every day. See [Evolutionary Coding Practices](#evolutionary-coding-practices) for detailed patterns and code examples.
274+
275+
### "What code coverage level is needed before we can do CI?"
276+
277+
You don't need tests in existing code to begin CI. You need to test **new code without exception**.
278+
279+
**Starting point**: "We will not go lower than the current level of code coverage."
280+
281+
### "What code coverage percentage should we have?"
282+
283+
"I'm confident." Are you confident you've covered enough positive and negative cases?
284+
285+
**Better question**: "Do we trust our tests?" Test coverage percentage doesn't indicate test quality.
286+
287+
### "Should we set a code coverage standard for all teams?"
288+
289+
No. Code coverage mandates incentivize meaningless tests that hide the fact that code is not tested.
290+
291+
**It is better to have no tests than to have tests you do not trust.**
292+
293+
Instead: Focus on test quality, behavior coverage, and team discipline. See [Code Coverage](https://dojoconsortium.org/docs/metrics/code-coverage/) for detailed guidance.
294+
295+
## Health Metrics
296+
297+
### Commits per Day per Developer
48298

49-
### "What tests should run during CI?"
299+
**What**: How frequently the team integrates code to trunk
300+
**Good**: 1 or more per developer per day (team average)
301+
**Important**: Never compare individuals—this is a team metric
50302

51-
Our goal is to detect issues as early as possible. Any functional tests that can be executed without deploying the application should be run. This includes, but is not limited to:
303+
### Development Cycle Time
52304

53-
- Static code quality
54-
- Static security scans
55-
- [Functional tests](https://martinfowler.com/articles/practical-test-pyramid.html) that do not require external services.
305+
**What**: Time from when work begins to completion
306+
**Good**: Less than 2 days on average
307+
**Indicates**: Effective work breakdown and CI practice
56308

57-
### What code coverage level is needed before we can do CI?
309+
### Build Success Rate
58310

59-
You don't need tests in the existing code to begin. You need to test new code without exception.
311+
**What**: Percentage of trunk builds that pass
312+
**Good**: > 95%
313+
**Indicates**: Quality of pre-merge testing and team discipline
60314

61-
### What code coverage percentage should we have?
315+
### Time to Fix Broken Build
62316

63-
"I'm confident". Are you confident you've covered enough positive and negative cases to make you confident?
317+
**What**: How quickly team resolves build failures
318+
**Good**: < 1 hour
319+
**Indicates**: Team commitment to "stop and fix"
64320

65-
### What code coverage percentage should we set as a standard for our team?
321+
### Defect Rate
66322

67-
"We will not go lower than the current level of code coverage." However, if the team is not committed to a disciplined quality process to the extent that delivery dates are never seen as an excuse, this could incentivize fake tests to meet the coverage minimum.
323+
**What**: Critical guardrail metric to ensure speed doesn't overtake quality
324+
**Good**: Stable or decreasing as CI improves
325+
**Indicates**: CI is improving quality, not just speed
68326

69-
### What code coverage percentage should we set as a standard for all teams?
327+
## Additional Resources
70328

71-
We shouldn't. Code coverage mandates incentivize meaningless tests that hide the fact that code is not tested. It is better to have no tests than to have tests you do not trust. See the [Dojo Consortium's info](https://dojoconsortium.org/docs/metrics/code-coverage/) on this metric.
329+
- [Continuous Integration on Martin Fowler's site](https://martinfowler.com/articles/continuousIntegration.html)
330+
- [Accelerate: Technical Practices](https://itrevolution.com/articles/accelerate-book/) - Nicole Forsgren, Jez Humble, Gene Kim
331+
- [The Practical Test Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html) - Martin Fowler
332+
- [Branch By Abstraction](https://www.branchbyabstraction.com/)
333+
- [Feature Toggles](https://martinfowler.com/articles/feature-toggles.html) - Martin Fowler
334+
- [Behavior-Driven Development](https://dojoconsortium.org/docs/work-decomposition/behavior-driven-development/) - DevOps Dojo Consortium

0 commit comments

Comments
 (0)