@electriccitizen/bolt 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.md +361 -0
  2. package/dist/adapters/ddev.d.ts +16 -0
  3. package/dist/adapters/ddev.js +75 -0
  4. package/dist/adapters/ddev.js.map +1 -0
  5. package/dist/adapters/index.d.ts +1 -0
  6. package/dist/adapters/index.js +2 -0
  7. package/dist/adapters/index.js.map +1 -0
  8. package/dist/cli.d.ts +2 -0
  9. package/dist/cli.js +167 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/doctor.d.ts +4 -0
  12. package/dist/commands/doctor.js +263 -0
  13. package/dist/commands/doctor.js.map +1 -0
  14. package/dist/commands/init.d.ts +12 -0
  15. package/dist/commands/init.js +319 -0
  16. package/dist/commands/init.js.map +1 -0
  17. package/dist/commands/pr.d.ts +20 -0
  18. package/dist/commands/pr.js +282 -0
  19. package/dist/commands/pr.js.map +1 -0
  20. package/dist/commands/refresh.d.ts +22 -0
  21. package/dist/commands/refresh.js +375 -0
  22. package/dist/commands/refresh.js.map +1 -0
  23. package/dist/commands/suppress.d.ts +10 -0
  24. package/dist/commands/suppress.js +86 -0
  25. package/dist/commands/suppress.js.map +1 -0
  26. package/dist/commands/test.d.ts +5 -0
  27. package/dist/commands/test.js +106 -0
  28. package/dist/commands/test.js.map +1 -0
  29. package/dist/commands/update.d.ts +26 -0
  30. package/dist/commands/update.js +573 -0
  31. package/dist/commands/update.js.map +1 -0
  32. package/dist/config.d.ts +47 -0
  33. package/dist/config.js +187 -0
  34. package/dist/config.js.map +1 -0
  35. package/dist/formatters/index.d.ts +2 -0
  36. package/dist/formatters/index.js +3 -0
  37. package/dist/formatters/index.js.map +1 -0
  38. package/dist/formatters/json.d.ts +5 -0
  39. package/dist/formatters/json.js +7 -0
  40. package/dist/formatters/json.js.map +1 -0
  41. package/dist/formatters/markdown.d.ts +5 -0
  42. package/dist/formatters/markdown.js +144 -0
  43. package/dist/formatters/markdown.js.map +1 -0
  44. package/dist/formatters/text.d.ts +5 -0
  45. package/dist/formatters/text.js +123 -0
  46. package/dist/formatters/text.js.map +1 -0
  47. package/dist/plugins/accessibility.d.ts +5 -0
  48. package/dist/plugins/accessibility.js +116 -0
  49. package/dist/plugins/accessibility.js.map +1 -0
  50. package/dist/plugins/browser-smoke.d.ts +6 -0
  51. package/dist/plugins/browser-smoke.js +331 -0
  52. package/dist/plugins/browser-smoke.js.map +1 -0
  53. package/dist/plugins/field-interaction.d.ts +6 -0
  54. package/dist/plugins/field-interaction.js +570 -0
  55. package/dist/plugins/field-interaction.js.map +1 -0
  56. package/dist/plugins/index.d.ts +6 -0
  57. package/dist/plugins/index.js +28 -0
  58. package/dist/plugins/index.js.map +1 -0
  59. package/dist/plugins/linkit.d.ts +8 -0
  60. package/dist/plugins/linkit.js +170 -0
  61. package/dist/plugins/linkit.js.map +1 -0
  62. package/dist/plugins/media-browser.d.ts +6 -0
  63. package/dist/plugins/media-browser.js +257 -0
  64. package/dist/plugins/media-browser.js.map +1 -0
  65. package/dist/plugins/structural-smoke.d.ts +6 -0
  66. package/dist/plugins/structural-smoke.js +90 -0
  67. package/dist/plugins/structural-smoke.js.map +1 -0
  68. package/dist/plugins/visual-regression.d.ts +8 -0
  69. package/dist/plugins/visual-regression.js +214 -0
  70. package/dist/plugins/visual-regression.js.map +1 -0
  71. package/dist/plugins/wysiwyg.d.ts +8 -0
  72. package/dist/plugins/wysiwyg.js +221 -0
  73. package/dist/plugins/wysiwyg.js.map +1 -0
  74. package/dist/runner.d.ts +21 -0
  75. package/dist/runner.js +293 -0
  76. package/dist/runner.js.map +1 -0
  77. package/dist/suppression.d.ts +55 -0
  78. package/dist/suppression.js +223 -0
  79. package/dist/suppression.js.map +1 -0
  80. package/dist/types.d.ts +178 -0
  81. package/dist/types.js +5 -0
  82. package/dist/types.js.map +1 -0
  83. package/modules/bolt_inspect/bolt_inspect.info.yml +6 -0
  84. package/modules/bolt_inspect/bolt_inspect.services.yml +22 -0
  85. package/modules/bolt_inspect/composer.json +16 -0
  86. package/modules/bolt_inspect/drush.services.yml +10 -0
  87. package/modules/bolt_inspect/src/Drush/Commands/BoltInspectCommands.php +203 -0
  88. package/modules/bolt_inspect/src/Service/ContentGenerator.php +586 -0
  89. package/modules/bolt_inspect/src/Service/SiteProfiler.php +362 -0
  90. package/modules/bolt_inspect/src/Service/TestEntityTracker.php +98 -0
  91. package/package.json +46 -0
  92. package/scripts/setup.sh +34 -0
@@ -0,0 +1,573 @@
1
+ /**
2
+ * bolt update — automated Drupal module/core updates with per-module testing.
3
+ *
4
+ * For each outdated package: creates a branch, updates, tests, and
5
+ * commits (or rolls back). Produces a summary report at the end.
6
+ */
7
+ import { execFile } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import { createInterface } from 'readline';
10
+ import { DdevAdapter } from '../adapters/ddev.js';
11
+ import { runTests } from '../runner.js';
12
+ import { loadConfig } from '../config.js';
13
+ const execFileAsync = promisify(execFile);
14
+ /** Write progress messages to stderr. */
15
+ function log(msg) {
16
+ process.stderr.write(` ${msg}\n`);
17
+ }
18
+ function logOk(msg) {
19
+ process.stderr.write(` ✓ ${msg}\n`);
20
+ }
21
+ function logFail(msg) {
22
+ process.stderr.write(` ✗ ${msg}\n`);
23
+ }
24
+ function logWarn(msg) {
25
+ process.stderr.write(` ⚠ ${msg}\n`);
26
+ }
27
+ function formatDuration(ms) {
28
+ if (ms < 1000)
29
+ return `${ms}ms`;
30
+ if (ms < 60_000)
31
+ return `${(ms / 1000).toFixed(1)}s`;
32
+ return `${Math.floor(ms / 60_000)}m ${Math.round((ms % 60_000) / 1000)}s`;
33
+ }
34
+ async function exec(command, args, timeoutMs = 300_000) {
35
+ try {
36
+ const { stdout, stderr } = await execFileAsync(command, args, {
37
+ maxBuffer: 10 * 1024 * 1024,
38
+ timeout: timeoutMs,
39
+ });
40
+ return { stdout, stderr, exitCode: 0 };
41
+ }
42
+ catch (err) {
43
+ if (err instanceof Error) {
44
+ const execErr = err;
45
+ return {
46
+ stdout: execErr.stdout ?? '',
47
+ stderr: execErr.stderr ?? err.message,
48
+ exitCode: typeof execErr.code === 'number' ? execErr.code : 1,
49
+ };
50
+ }
51
+ return { stdout: '', stderr: String(err), exitCode: 1 };
52
+ }
53
+ }
54
+ async function confirm(question) {
55
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
56
+ return new Promise((resolve) => {
57
+ rl.question(` ${question} (y/N) `, (answer) => {
58
+ rl.close();
59
+ resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
60
+ });
61
+ });
62
+ }
63
+ /**
64
+ * Get the current git branch name.
65
+ */
66
+ async function getCurrentBranch() {
67
+ const result = await exec('git', ['rev-parse', '--abbrev-ref', 'HEAD']);
68
+ return result.stdout.trim();
69
+ }
70
+ /**
71
+ * Check if a git branch exists locally.
72
+ */
73
+ async function branchExists(name) {
74
+ const result = await exec('git', ['rev-parse', '--verify', name]);
75
+ return result.exitCode === 0;
76
+ }
77
+ /**
78
+ * Parse `ddev composer outdated --format=json` output into UpdateCandidates.
79
+ */
80
+ function parseOutdated(stdout, securityPackages) {
81
+ let data;
82
+ try {
83
+ data = JSON.parse(stdout);
84
+ }
85
+ catch {
86
+ return [];
87
+ }
88
+ // Composer outdated --format=json returns { installed: [...] }
89
+ const installed = (data.installed ?? data);
90
+ if (!Array.isArray(installed))
91
+ return [];
92
+ return installed
93
+ .filter((pkg) => pkg.name && pkg.version && pkg.latest)
94
+ .map((pkg) => ({
95
+ name: pkg.name,
96
+ currentVersion: pkg.version,
97
+ latestVersion: pkg.latest,
98
+ updateType: pkg['latest-status'] ?? 'unknown',
99
+ description: pkg.description,
100
+ isSecurityUpdate: securityPackages.has(pkg.name),
101
+ }));
102
+ }
103
+ /**
104
+ * Get packages with security advisories via `composer audit`.
105
+ */
106
+ async function getSecurityPackages() {
107
+ const result = await exec('ddev', ['composer', 'audit', '--format=json'], 60_000);
108
+ const packages = new Set();
109
+ try {
110
+ const data = JSON.parse(result.stdout);
111
+ const advisories = data.advisories;
112
+ if (advisories) {
113
+ for (const name of Object.keys(advisories)) {
114
+ packages.add(name);
115
+ }
116
+ }
117
+ }
118
+ catch {
119
+ // No advisories or parse error — that's fine.
120
+ }
121
+ return packages;
122
+ }
123
+ /**
124
+ * Filter and sort candidates based on config and options.
125
+ */
126
+ function filterCandidates(candidates, options, config) {
127
+ let filtered = [...candidates];
128
+ // Filter to single module if specified.
129
+ if (options.module) {
130
+ filtered = filtered.filter((c) => c.name === options.module);
131
+ if (filtered.length === 0) {
132
+ // Try partial match (e.g., "token" matches "drupal/token").
133
+ filtered = candidates.filter((c) => c.name.endsWith(`/${options.module}`) || c.name === options.module);
134
+ }
135
+ }
136
+ // Security only.
137
+ if (options.securityOnly) {
138
+ filtered = filtered.filter((c) => c.isSecurityUpdate);
139
+ }
140
+ // Apply ignore patterns from config.
141
+ if (config.ignore.length > 0) {
142
+ filtered = filtered.filter((c) => {
143
+ return !config.ignore.some((pattern) => {
144
+ if (pattern.includes('*')) {
145
+ const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
146
+ return regex.test(c.name);
147
+ }
148
+ return c.name === pattern;
149
+ });
150
+ });
151
+ }
152
+ // Sort: security first, then priority list, then alphabetical.
153
+ filtered.sort((a, b) => {
154
+ // Security updates first.
155
+ if (a.isSecurityUpdate && !b.isSecurityUpdate)
156
+ return -1;
157
+ if (!a.isSecurityUpdate && b.isSecurityUpdate)
158
+ return 1;
159
+ // Priority list items come next.
160
+ const aPriority = config.priority.indexOf(a.name);
161
+ const bPriority = config.priority.indexOf(b.name);
162
+ if (aPriority !== -1 && bPriority === -1)
163
+ return -1;
164
+ if (aPriority === -1 && bPriority !== -1)
165
+ return 1;
166
+ if (aPriority !== -1 && bPriority !== -1)
167
+ return aPriority - bPriority;
168
+ // Alphabetical.
169
+ return a.name.localeCompare(b.name);
170
+ });
171
+ return filtered;
172
+ }
173
+ /**
174
+ * Sanitize a package name for use in a branch name.
175
+ */
176
+ function toBranchName(packageName, version) {
177
+ const clean = packageName.replace(/\//g, '-').replace(/[^a-zA-Z0-9_.-]/g, '');
178
+ const cleanVersion = version.replace(/[^a-zA-Z0-9._-]/g, '');
179
+ return `update/${clean}-${cleanVersion}`;
180
+ }
181
+ /**
182
+ * Run bolt test internally (like suppress does) and return pass/fail.
183
+ */
184
+ async function runBaselineTest(adapter, config, siteUrl) {
185
+ const testOptions = {
186
+ url: siteUrl,
187
+ mode: 'full',
188
+ output: 'json',
189
+ exitCode: false,
190
+ failOn: 'major',
191
+ headed: false,
192
+ configSkip: config.plugins.skip.length > 0 ? config.plugins.skip : undefined,
193
+ boltConfig: config,
194
+ };
195
+ const report = await runTests(adapter, testOptions);
196
+ const failCount = report.results.filter((r) => r.status === 'fail').length;
197
+ const passCount = report.results.filter((r) => r.status === 'pass').length;
198
+ const suppressedCount = report.results.filter((r) => r.status === 'suppressed').length;
199
+ return { passed: failCount === 0, failCount, passCount, suppressedCount };
200
+ }
201
+ /**
202
+ * Run a quick test suite for a single module update verification.
203
+ */
204
+ async function runModuleTest(adapter, config, siteUrl) {
205
+ // Same as baseline — run the full test suite to catch regressions.
206
+ return runBaselineTest(adapter, config, siteUrl);
207
+ }
208
+ export async function updateCommand(options) {
209
+ const startTime = Date.now();
210
+ const config = options.boltConfig ?? loadConfig();
211
+ const updateConfig = config.update;
212
+ const adapter = new DdevAdapter();
213
+ const results = [];
214
+ process.stderr.write('\nbolt update\n');
215
+ process.stderr.write('━'.repeat(50) + '\n\n');
216
+ // Verify DDEV connectivity.
217
+ const connected = await adapter.canConnect();
218
+ if (!connected) {
219
+ process.stderr.write('Error: Cannot connect to DDEV. Is it running?\n' +
220
+ 'Run this command from your Drupal project directory.\n');
221
+ process.exit(2);
222
+ }
223
+ // Get site URL.
224
+ const siteUrl = await adapter.getSiteUrl();
225
+ if (!siteUrl) {
226
+ process.stderr.write('Error: Could not detect site URL from DDEV.\n');
227
+ process.exit(2);
228
+ }
229
+ // --- Pre-flight ---
230
+ const baseBranch = config.refresh.base_branch || 'main';
231
+ // 1a. Pre-update refresh (code sync).
232
+ if (!options.skipRefresh) {
233
+ log('Pre-update refresh...');
234
+ // Ensure we're on the base branch.
235
+ const currentBranch = await getCurrentBranch();
236
+ if (currentBranch !== baseBranch) {
237
+ log(`Switching to ${baseBranch}...`);
238
+ const checkout = await exec('git', ['checkout', baseBranch]);
239
+ if (checkout.exitCode !== 0) {
240
+ logFail(`Failed to checkout ${baseBranch}: ${checkout.stderr.trim()}`);
241
+ process.exit(2);
242
+ }
243
+ }
244
+ // Pull latest.
245
+ log('Pulling latest...');
246
+ const pull = await exec('git', ['pull', 'origin', baseBranch]);
247
+ if (pull.exitCode !== 0) {
248
+ logFail(`git pull failed: ${pull.stderr.trim()}`);
249
+ process.exit(2);
250
+ }
251
+ // Composer install.
252
+ log('Running composer install...');
253
+ const ci = await exec('ddev', ['composer', 'install'], 300_000);
254
+ if (ci.exitCode !== 0) {
255
+ logFail(`composer install failed: ${ci.stderr.trim()}`);
256
+ process.exit(2);
257
+ }
258
+ // Cache rebuild.
259
+ await exec('ddev', ['drush', 'cr']);
260
+ logOk('Pre-update refresh complete');
261
+ }
262
+ else {
263
+ log('Skipping pre-update refresh (--skip-refresh)');
264
+ }
265
+ // 1b. Baseline test.
266
+ if (!options.skipTest && !options.dryRun) {
267
+ log('Running baseline test...');
268
+ try {
269
+ const baseline = await runBaselineTest(adapter, config, siteUrl);
270
+ if (!baseline.passed) {
271
+ logFail(`Baseline test failed: ${baseline.failCount} failure(s)`);
272
+ process.stderr.write('\nCannot verify updates when the site already has test failures.\n' +
273
+ 'Fix the failures or run `bolt suppress` to baseline known issues.\n');
274
+ process.exit(1);
275
+ }
276
+ logOk(`Baseline test passed (${baseline.passCount} passed, ${baseline.suppressedCount} suppressed)`);
277
+ }
278
+ catch (err) {
279
+ logFail(`Baseline test error: ${err instanceof Error ? err.message : String(err)}`);
280
+ process.exit(2);
281
+ }
282
+ }
283
+ // 1c. Get outdated packages.
284
+ log('Checking for outdated packages...');
285
+ const securityPackages = await getSecurityPackages();
286
+ const outdatedResult = await exec('ddev', ['composer', 'outdated', '--format=json', '--direct'], 60_000);
287
+ // composer outdated returns exit code 0 when everything is up to date,
288
+ // and non-zero when there are outdated packages — both are valid.
289
+ const candidates = parseOutdated(outdatedResult.stdout, securityPackages);
290
+ if (candidates.length === 0) {
291
+ logOk('All packages are up to date');
292
+ process.exit(0);
293
+ }
294
+ // 1d. Filter and sort.
295
+ const filtered = filterCandidates(candidates, options, updateConfig);
296
+ if (filtered.length === 0) {
297
+ if (options.securityOnly) {
298
+ logOk('No security updates available');
299
+ }
300
+ else if (options.module) {
301
+ logFail(`Package "${options.module}" not found in outdated list`);
302
+ log('Available outdated packages:');
303
+ for (const c of candidates.slice(0, 10)) {
304
+ log(` ${c.name}: ${c.currentVersion} → ${c.latestVersion}`);
305
+ }
306
+ }
307
+ else {
308
+ logOk('No matching packages to update (check update.ignore in .bolt.yml)');
309
+ }
310
+ process.exit(0);
311
+ }
312
+ // 1e. Show update plan.
313
+ process.stderr.write('\nUpdate plan:\n');
314
+ for (const c of filtered) {
315
+ const secTag = c.isSecurityUpdate ? ' [SECURITY]' : '';
316
+ process.stderr.write(` ${c.name}: ${c.currentVersion} → ${c.latestVersion}${secTag}\n`);
317
+ }
318
+ process.stderr.write(`\n ${filtered.length} package(s) to update\n\n`);
319
+ if (options.dryRun) {
320
+ log('Dry run — no changes made.');
321
+ process.exit(0);
322
+ }
323
+ if (!options.yes) {
324
+ const proceed = await confirm('Proceed with updates?');
325
+ if (!proceed) {
326
+ log('Aborted.');
327
+ process.exit(0);
328
+ }
329
+ }
330
+ // --- Per-module update loop ---
331
+ process.stderr.write('\n');
332
+ for (let i = 0; i < filtered.length; i++) {
333
+ const candidate = filtered[i];
334
+ const moduleStart = Date.now();
335
+ const branchName = toBranchName(candidate.name, candidate.latestVersion);
336
+ process.stderr.write(`[${i + 1}/${filtered.length}] ${candidate.name} ` +
337
+ `${candidate.currentVersion} → ${candidate.latestVersion}\n`);
338
+ // Check if branch already exists (--continue support).
339
+ if (await branchExists(branchName)) {
340
+ log(`Branch "${branchName}" already exists — skipping (already updated)`);
341
+ results.push({
342
+ package: candidate.name,
343
+ oldVersion: candidate.currentVersion,
344
+ newVersion: candidate.latestVersion,
345
+ status: 'skip',
346
+ branch: branchName,
347
+ error: 'Branch already exists',
348
+ duration: Date.now() - moduleStart,
349
+ });
350
+ continue;
351
+ }
352
+ // Ensure we're on base branch.
353
+ const currentBranch = await getCurrentBranch();
354
+ if (currentBranch !== baseBranch) {
355
+ await exec('git', ['checkout', baseBranch]);
356
+ }
357
+ // Create update branch.
358
+ const branchResult = await exec('git', ['checkout', '-b', branchName]);
359
+ if (branchResult.exitCode !== 0) {
360
+ logFail(`Failed to create branch: ${branchResult.stderr.trim()}`);
361
+ results.push({
362
+ package: candidate.name,
363
+ oldVersion: candidate.currentVersion,
364
+ newVersion: candidate.latestVersion,
365
+ status: 'fail',
366
+ branch: branchName,
367
+ error: branchResult.stderr.trim(),
368
+ duration: Date.now() - moduleStart,
369
+ });
370
+ continue;
371
+ }
372
+ // Composer update.
373
+ log(`Updating ${candidate.name}...`);
374
+ const updateResult = await exec('ddev', ['composer', 'update', candidate.name, '--with-dependencies'], 300_000);
375
+ if (updateResult.exitCode !== 0) {
376
+ logFail(`composer update failed: ${updateResult.stderr.trim()}`);
377
+ // Rollback.
378
+ await exec('git', ['checkout', '.']);
379
+ await exec('git', ['clean', '-fd']);
380
+ await exec('git', ['checkout', baseBranch]);
381
+ await exec('git', ['branch', '-D', branchName]);
382
+ results.push({
383
+ package: candidate.name,
384
+ oldVersion: candidate.currentVersion,
385
+ newVersion: candidate.latestVersion,
386
+ status: 'conflict',
387
+ branch: branchName,
388
+ error: updateResult.stderr.trim(),
389
+ duration: Date.now() - moduleStart,
390
+ });
391
+ continue;
392
+ }
393
+ // Database updates.
394
+ log('Running database updates...');
395
+ const updbResult = await exec('ddev', ['drush', 'updb', '-y']);
396
+ const dbUpdates = updbResult.stdout.includes('No pending updates') ? 0 : 1;
397
+ if (updbResult.exitCode !== 0) {
398
+ logFail(`drush updb failed: ${updbResult.stderr.trim()}`);
399
+ // Rollback.
400
+ await exec('git', ['checkout', '.']);
401
+ await exec('git', ['clean', '-fd']);
402
+ await exec('git', ['checkout', baseBranch]);
403
+ await exec('git', ['branch', '-D', branchName]);
404
+ results.push({
405
+ package: candidate.name,
406
+ oldVersion: candidate.currentVersion,
407
+ newVersion: candidate.latestVersion,
408
+ status: 'fail',
409
+ branch: branchName,
410
+ error: `drush updb failed: ${updbResult.stderr.trim()}`,
411
+ duration: Date.now() - moduleStart,
412
+ });
413
+ continue;
414
+ }
415
+ // Cache rebuild.
416
+ await exec('ddev', ['drush', 'cr']);
417
+ // Run tests.
418
+ log('Running regression tests...');
419
+ let testResult;
420
+ try {
421
+ testResult = await runModuleTest(adapter, config, siteUrl);
422
+ }
423
+ catch (err) {
424
+ logFail(`Test error: ${err instanceof Error ? err.message : String(err)}`);
425
+ // Rollback.
426
+ await exec('git', ['checkout', '.']);
427
+ await exec('git', ['clean', '-fd']);
428
+ await exec('git', ['checkout', baseBranch]);
429
+ await exec('git', ['branch', '-D', branchName]);
430
+ results.push({
431
+ package: candidate.name,
432
+ oldVersion: candidate.currentVersion,
433
+ newVersion: candidate.latestVersion,
434
+ status: 'fail',
435
+ branch: branchName,
436
+ error: `Test error: ${err instanceof Error ? err.message : String(err)}`,
437
+ duration: Date.now() - moduleStart,
438
+ });
439
+ continue;
440
+ }
441
+ if (!testResult.passed) {
442
+ logFail(`Tests failed: ${testResult.failCount} failure(s)`);
443
+ // Rollback.
444
+ await exec('git', ['checkout', '.']);
445
+ await exec('git', ['clean', '-fd']);
446
+ await exec('git', ['checkout', baseBranch]);
447
+ await exec('git', ['branch', '-D', branchName]);
448
+ results.push({
449
+ package: candidate.name,
450
+ oldVersion: candidate.currentVersion,
451
+ newVersion: candidate.latestVersion,
452
+ status: 'fail',
453
+ branch: branchName,
454
+ testSummary: {
455
+ passed: testResult.passCount,
456
+ failed: testResult.failCount,
457
+ suppressed: testResult.suppressedCount,
458
+ },
459
+ error: `${testResult.failCount} test failure(s)`,
460
+ duration: Date.now() - moduleStart,
461
+ });
462
+ continue;
463
+ }
464
+ logOk(`Tests passed (${testResult.passCount} passed, ${testResult.suppressedCount} suppressed)`);
465
+ // Export config changes.
466
+ log('Exporting config...');
467
+ const cexResult = await exec('ddev', ['drush', 'cex', '-y']);
468
+ let configChanges = [];
469
+ if (cexResult.exitCode === 0 && !cexResult.stdout.includes('No changes to export')) {
470
+ // Get list of changed config files from git.
471
+ const diffResult = await exec('git', ['diff', '--name-only']);
472
+ configChanges = diffResult.stdout
473
+ .trim()
474
+ .split('\n')
475
+ .filter((f) => f.startsWith('config/') || f.endsWith('.yml'));
476
+ }
477
+ // Stage and commit.
478
+ log('Committing...');
479
+ await exec('git', ['add', '-A']);
480
+ const commitMessage = [
481
+ `Update ${candidate.name} from ${candidate.currentVersion} to ${candidate.latestVersion}`,
482
+ '',
483
+ `Composer: ddev composer update ${candidate.name} --with-dependencies`,
484
+ `Database: drush updb (${dbUpdates > 0 ? 'updates applied' : 'no pending updates'})`,
485
+ `Config: drush cex (${configChanges.length > 0 ? `${configChanges.length} files changed` : 'no changes'})`,
486
+ '',
487
+ `Bolt test: PASS (${testResult.passCount} passed, ${testResult.failCount} failed, ${testResult.suppressedCount} suppressed)`,
488
+ ].join('\n');
489
+ const commitResult = await exec('git', ['commit', '-m', commitMessage]);
490
+ const commitHash = commitResult.exitCode === 0
491
+ ? (await exec('git', ['rev-parse', '--short', 'HEAD'])).stdout.trim()
492
+ : undefined;
493
+ if (commitResult.exitCode === 0) {
494
+ logOk(`Committed on ${branchName} (${commitHash})`);
495
+ }
496
+ else {
497
+ logWarn(`Commit failed: ${commitResult.stderr.trim()}`);
498
+ }
499
+ results.push({
500
+ package: candidate.name,
501
+ oldVersion: candidate.currentVersion,
502
+ newVersion: candidate.latestVersion,
503
+ status: 'pass',
504
+ branch: branchName,
505
+ commitHash,
506
+ testSummary: {
507
+ passed: testResult.passCount,
508
+ failed: testResult.failCount,
509
+ suppressed: testResult.suppressedCount,
510
+ },
511
+ configChanges,
512
+ dbUpdates,
513
+ duration: Date.now() - moduleStart,
514
+ });
515
+ // Return to base branch for next module.
516
+ await exec('git', ['checkout', baseBranch]);
517
+ process.stderr.write('\n');
518
+ }
519
+ // --- Report ---
520
+ const totalDuration = Date.now() - startTime;
521
+ const updated = results.filter((r) => r.status === 'pass').length;
522
+ const failed = results.filter((r) => r.status === 'fail' || r.status === 'conflict').length;
523
+ const skipped = results.filter((r) => r.status === 'skip').length;
524
+ const report = {
525
+ timestamp: new Date().toISOString(),
526
+ baseBranch,
527
+ totalCandidates: filtered.length,
528
+ updated,
529
+ failed,
530
+ skipped,
531
+ duration: totalDuration,
532
+ results,
533
+ };
534
+ process.stderr.write('━'.repeat(50) + '\n');
535
+ process.stderr.write(`\nUpdate summary: ${updated} updated, ${failed} failed, ${skipped} skipped (${formatDuration(totalDuration)})\n\n`);
536
+ // Show per-module results.
537
+ for (const r of results) {
538
+ const icon = r.status === 'pass' ? '✓'
539
+ : r.status === 'fail' ? '✗'
540
+ : r.status === 'conflict' ? '⚡'
541
+ : '⊘';
542
+ const detail = r.status === 'pass'
543
+ ? `→ ${r.branch} (${r.commitHash})`
544
+ : r.error
545
+ ? `— ${r.error}`
546
+ : '';
547
+ process.stderr.write(` ${icon} ${r.package}: ${r.oldVersion} → ${r.newVersion} ${detail}\n`);
548
+ }
549
+ // Write JSON report to .bolt/logs/.
550
+ try {
551
+ const { mkdirSync, writeFileSync } = await import('fs');
552
+ const { join } = await import('path');
553
+ const logDir = join(process.cwd(), '.bolt', 'logs');
554
+ mkdirSync(logDir, { recursive: true });
555
+ const ts = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
556
+ const reportPath = join(logDir, `update-${ts}.json`);
557
+ writeFileSync(reportPath, JSON.stringify(report, null, 2), 'utf-8');
558
+ process.stderr.write(`\n Report saved to .bolt/logs/update-${ts}.json\n`);
559
+ }
560
+ catch {
561
+ // Non-fatal.
562
+ }
563
+ if (updated > 0) {
564
+ process.stderr.write('\nNext steps:\n');
565
+ process.stderr.write(' bolt pr --all — create PRs for update branches\n');
566
+ process.stderr.write('\n');
567
+ }
568
+ // Exit code: 0 if any succeeded, 1 if all failed.
569
+ if (updated === 0 && failed > 0) {
570
+ process.exit(1);
571
+ }
572
+ }
573
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * .bolt.yml config loader and validator.
3
+ */
4
+ export interface RefreshDbConfig {
5
+ source: string;
6
+ pantheon_site?: string;
7
+ pantheon_env?: string;
8
+ file_path?: string;
9
+ }
10
+ export interface RefreshConfig {
11
+ base_branch: string;
12
+ db: RefreshDbConfig;
13
+ }
14
+ export interface PrConfig {
15
+ base_branch: string;
16
+ default_reviewers: string[];
17
+ draft: boolean;
18
+ remote: string;
19
+ }
20
+ export interface UpdateConfig {
21
+ ignore: string[];
22
+ priority: string[];
23
+ }
24
+ export interface BoltConfig {
25
+ adapter: string;
26
+ plugins: {
27
+ skip: string[];
28
+ config: Record<string, Record<string, unknown>>;
29
+ };
30
+ custom_routes: string[];
31
+ refresh: RefreshConfig;
32
+ update: UpdateConfig;
33
+ pr: PrConfig;
34
+ }
35
+ /**
36
+ * Find and load .bolt.yml from the current directory.
37
+ * Returns default config if no file exists.
38
+ */
39
+ export declare function loadConfig(dir?: string): BoltConfig;
40
+ /**
41
+ * Validate config and return any issues found.
42
+ */
43
+ export declare function validateConfig(config: BoltConfig): string[];
44
+ /**
45
+ * Generate a .bolt.yml template string.
46
+ */
47
+ export declare function generateConfigTemplate(): string;