0
# Change Detection
1
2
Detecting which packages have changed since a given reference for selective operations.
3
4
## Capabilities
5
6
### Changed Command
7
8
List packages that have changed since the last release or specified reference.
9
10
```bash { .api }
11
# List changed packages since last release
12
lerna changed
13
lerna updated # Alias for 'changed'
14
15
# List changed packages since specific ref
16
lerna changed --since HEAD~1
17
lerna changed --since v1.0.0
18
lerna changed --since origin/main
19
20
# Include dependencies of changed packages
21
lerna changed --include-dependencies
22
23
# Include dependents of changed packages
24
lerna changed --include-dependents
25
26
# Include packages from merged tags
27
lerna changed --include-merged-tags
28
29
# Output formats
30
lerna changed --json # JSON array
31
lerna changed --ndjson # Newline-delimited JSON
32
lerna changed --parseable # Parseable format
33
lerna changed --long # Extended information
34
35
# Filtering
36
lerna changed --scope="@myorg/*" # Include only matching packages
37
lerna changed --ignore="*-test" # Exclude matching packages
38
lerna changed --no-private # Exclude private packages
39
lerna changed --all # Include all packages
40
```
41
42
### Diff Command
43
44
Show git diff for packages that have changed since the last release.
45
46
```bash { .api }
47
# Show diff for all changed packages
48
lerna diff
49
50
# Show diff for specific package
51
lerna diff package-name
52
53
# Show diff since specific reference
54
lerna diff --since HEAD~1
55
lerna diff --since v1.0.0
56
57
# Show diff for specific package since reference
58
lerna diff package-name --since origin/main
59
```
60
61
**Diff command:**
62
- Runs `git diff` on packages that have changed
63
- Similar to `lerna changed` but shows actual file differences
64
- Supports same filtering options as `lerna changed`
65
- Shows changes since last release tag by default
66
- Can target specific packages or all changed packages
67
68
### Change Detection Logic
69
70
Lerna detects changes using git diff between:
71
- **Last release tag** (default): Most recent git tag
72
- **Specific reference**: Commit, branch, or tag provided via `--since`
73
74
**Detection includes:**
75
- Modified files in package directories
76
- Added/removed files
77
- Changes to package.json dependencies
78
- Git submodule changes affecting packages
79
80
### Since Reference Options
81
82
```bash { .api }
83
# Commit references
84
lerna changed --since HEAD~3
85
lerna changed --since abc1234
86
87
# Branch references
88
lerna changed --since origin/main
89
lerna changed --since feature/new-api
90
91
# Tag references
92
lerna changed --since v1.0.0
93
lerna changed --since latest
94
95
# Time-based references
96
lerna changed --since "2 weeks ago"
97
lerna changed --since "2023-01-01"
98
```
99
100
## Advanced Change Detection
101
102
### Dependency Inclusion
103
104
Include packages based on their relationships:
105
106
```bash { .api }
107
# Include dependencies (packages that changed packages depend on)
108
lerna changed --include-dependencies
109
110
# Include dependents (packages that depend on changed packages)
111
lerna changed --include-dependents
112
113
# Include both dependencies and dependents
114
lerna changed --include-dependencies --include-dependents
115
```
116
117
**Example scenario:**
118
- Package A depends on Package B
119
- Package B changed
120
- `--include-dependents` includes Package A (depends on changed B)
121
- `--include-dependencies` includes Package B's dependencies
122
123
### Merged Tag Handling
124
125
```bash { .api }
126
# Include packages affected by merged pull requests
127
lerna changed --include-merged-tags
128
129
# Useful for CI/CD after merging features
130
lerna changed --since origin/main --include-merged-tags
131
```
132
133
This option is particularly useful when:
134
- Features are developed in branches with their own version tags
135
- Tags are merged rather than rebased
136
- You need to detect all affected packages across merged branches
137
138
### Force Detection Override
139
140
```bash { .api }
141
# Force include all packages (ignore change detection)
142
lerna changed --force-publish
143
144
# Force include specific packages
145
lerna changed --force-publish package-a,package-b
146
147
# Force include packages matching pattern
148
lerna changed --force-publish "@myorg/*"
149
```
150
151
## Output Formats
152
153
### JSON Output
154
155
```bash { .api }
156
# JSON array format
157
lerna changed --json
158
# ["package-a", "package-b", "package-c"]
159
160
# Newline-delimited JSON
161
lerna changed --ndjson
162
# "package-a"
163
# "package-b"
164
# "package-c"
165
```
166
167
### Extended Information
168
169
```bash { .api }
170
# Show version and location
171
lerna changed --long
172
# package-a v1.2.3 packages/package-a
173
# package-b v0.5.1 packages/package-b
174
175
# Parseable output (machine-readable)
176
lerna changed --parseable
177
# /path/to/workspace/packages/package-a:package-a:1.2.3
178
# /path/to/workspace/packages/package-b:package-b:0.5.1
179
```
180
181
## Integration with Other Commands
182
183
### Script Execution
184
185
```bash { .api }
186
# Run tests only on changed packages
187
lerna run test --since HEAD~1
188
189
# Build changed packages and their dependents
190
lerna run build --since v1.0.0 --include-dependents
191
```
192
193
### Publishing
194
195
```bash { .api }
196
# Publish only changed packages
197
lerna publish --since HEAD~1
198
199
# Version only changed packages
200
lerna version --since v1.0.0
201
```
202
203
### Package Operations
204
205
```bash { .api }
206
# Execute command only in changed packages
207
lerna exec --since HEAD~1 -- rm -rf node_modules
208
209
# List only changed packages
210
lerna list --since origin/main
211
```
212
213
## Configuration
214
215
### Default Since Reference
216
217
Configure default reference in lerna.json:
218
219
```json
220
{
221
"command": {
222
"changed": {
223
"since": "origin/main",
224
"includeDependents": true
225
}
226
}
227
}
228
```
229
230
### Ignore Changes
231
232
Ignore specific files/directories for change detection:
233
234
```json
235
{
236
"command": {
237
"changed": {
238
"ignoreChanges": [
239
"**/*.md",
240
"**/test/**",
241
"**/*.test.js"
242
]
243
}
244
}
245
}
246
```
247
248
**Ignore patterns:**
249
- `**/*.md` - Ignore all markdown files
250
- `**/test/**` - Ignore test directories
251
- `**/__tests__/**` - Ignore Jest test directories
252
- `**/stories/**` - Ignore Storybook files
253
- `**/*.test.{js,ts}` - Ignore test files
254
255
## CI/CD Integration
256
257
### GitHub Actions
258
259
```yaml
260
- name: Check for changes
261
id: changes
262
run: |
263
if lerna changed --since origin/main; then
264
echo "changed=true" >> $GITHUB_OUTPUT
265
else
266
echo "changed=false" >> $GITHUB_OUTPUT
267
fi
268
269
- name: Run tests on changed packages
270
if: steps.changes.outputs.changed == 'true'
271
run: lerna run test --since origin/main
272
```
273
274
### Conditional Pipeline Steps
275
276
```bash { .api }
277
# Exit with code 1 if no changes (useful for CI)
278
lerna changed --since origin/main || exit 1
279
280
# Store changed packages for later use
281
CHANGED_PACKAGES=$(lerna changed --since HEAD~1 --json)
282
echo "Changed packages: $CHANGED_PACKAGES"
283
```
284
285
## Troubleshooting
286
287
### No Changes Detected
288
289
Common causes and solutions:
290
291
```bash { .api }
292
# Verify git history
293
git log --oneline --graph
294
295
# Check for uncommitted changes
296
git status
297
298
# Verify package locations match lerna.json
299
lerna list --all
300
301
# Check ignore patterns
302
lerna changed --since HEAD~1 --loglevel verbose
303
```
304
305
### False Positives
306
307
```bash { .api }
308
# Add ignore patterns for non-functional changes
309
lerna changed --ignore-changes "**/*.md" --ignore-changes "**/test/**"
310
311
# Use specific since reference
312
lerna changed --since $(git describe --tags --abbrev=0)
313
```