@lumenflow/cli 2.3.1 → 2.3.2
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.
- package/dist/__tests__/release.test.js +61 -0
- package/dist/init.js +9 -0
- package/dist/release.js +69 -29
- package/package.json +6 -6
|
@@ -135,6 +135,67 @@ describe('release command integration', () => {
|
|
|
135
135
|
expect(typeof module.updatePackageVersions).toBe('function');
|
|
136
136
|
});
|
|
137
137
|
});
|
|
138
|
+
/**
|
|
139
|
+
* WU-1296: Tests for release flow trunk protection compatibility
|
|
140
|
+
*
|
|
141
|
+
* Verifies:
|
|
142
|
+
* - RELEASE_WU_TOOL constant is exported for pre-push hook bypass
|
|
143
|
+
* - withReleaseEnv helper sets LUMENFLOW_WU_TOOL=release during execution
|
|
144
|
+
* - Environment is properly restored after execution (including on error)
|
|
145
|
+
*/
|
|
146
|
+
describe('WU-1296: release flow trunk protection compatibility', () => {
|
|
147
|
+
it('should export RELEASE_WU_TOOL constant for pre-push hook bypass', async () => {
|
|
148
|
+
const { RELEASE_WU_TOOL } = await import('../release.js');
|
|
149
|
+
expect(RELEASE_WU_TOOL).toBe('release');
|
|
150
|
+
});
|
|
151
|
+
it('should export withReleaseEnv helper for setting LUMENFLOW_WU_TOOL', async () => {
|
|
152
|
+
const { withReleaseEnv } = await import('../release.js');
|
|
153
|
+
expect(typeof withReleaseEnv).toBe('function');
|
|
154
|
+
});
|
|
155
|
+
it('withReleaseEnv should set and restore LUMENFLOW_WU_TOOL', async () => {
|
|
156
|
+
const { withReleaseEnv } = await import('../release.js');
|
|
157
|
+
// Save original value
|
|
158
|
+
const originalValue = process.env.LUMENFLOW_WU_TOOL;
|
|
159
|
+
let capturedValue;
|
|
160
|
+
await withReleaseEnv(async () => {
|
|
161
|
+
capturedValue = process.env.LUMENFLOW_WU_TOOL;
|
|
162
|
+
});
|
|
163
|
+
expect(capturedValue).toBe('release');
|
|
164
|
+
expect(process.env.LUMENFLOW_WU_TOOL).toBe(originalValue);
|
|
165
|
+
});
|
|
166
|
+
it('withReleaseEnv should restore LUMENFLOW_WU_TOOL even on error', async () => {
|
|
167
|
+
const { withReleaseEnv } = await import('../release.js');
|
|
168
|
+
// Save original value
|
|
169
|
+
const originalValue = process.env.LUMENFLOW_WU_TOOL;
|
|
170
|
+
try {
|
|
171
|
+
await withReleaseEnv(async () => {
|
|
172
|
+
throw new Error('Test error');
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// Expected to throw
|
|
177
|
+
}
|
|
178
|
+
expect(process.env.LUMENFLOW_WU_TOOL).toBe(originalValue);
|
|
179
|
+
});
|
|
180
|
+
it('withReleaseEnv should preserve existing LUMENFLOW_WU_TOOL value', async () => {
|
|
181
|
+
const { withReleaseEnv } = await import('../release.js');
|
|
182
|
+
// Set a specific value before running
|
|
183
|
+
const testValue = 'wu-done';
|
|
184
|
+
process.env.LUMENFLOW_WU_TOOL = testValue;
|
|
185
|
+
try {
|
|
186
|
+
let capturedValue;
|
|
187
|
+
await withReleaseEnv(async () => {
|
|
188
|
+
capturedValue = process.env.LUMENFLOW_WU_TOOL;
|
|
189
|
+
});
|
|
190
|
+
expect(capturedValue).toBe('release');
|
|
191
|
+
expect(process.env.LUMENFLOW_WU_TOOL).toBe(testValue);
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
// Cleanup
|
|
195
|
+
delete process.env.LUMENFLOW_WU_TOOL;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
});
|
|
138
199
|
/**
|
|
139
200
|
* WU-1077: Tests for release script bug fixes
|
|
140
201
|
*
|
package/dist/init.js
CHANGED
|
@@ -1597,3 +1597,12 @@ export async function main() {
|
|
|
1597
1597
|
console.log(' 3. Run: pnpm wu:create --id WU-0001 --lane <lane> --title "First WU"');
|
|
1598
1598
|
/* eslint-enable no-console */
|
|
1599
1599
|
}
|
|
1600
|
+
// WU-1297: Use import.meta.main instead of exporting main() without calling it
|
|
1601
|
+
// This ensures main() runs when the script is executed as a CLI entry point
|
|
1602
|
+
if (import.meta.main) {
|
|
1603
|
+
main().catch((err) => {
|
|
1604
|
+
// eslint-disable-next-line no-console -- CLI error output
|
|
1605
|
+
console.error('[lumenflow init] Error:', err instanceof Error ? err.message : String(err));
|
|
1606
|
+
process.exit(1);
|
|
1607
|
+
});
|
|
1608
|
+
}
|
package/dist/release.js
CHANGED
|
@@ -60,6 +60,42 @@ const CHANGESET_DIR = '.changeset';
|
|
|
60
60
|
const LUMENFLOW_FORCE_ENV = 'LUMENFLOW_FORCE';
|
|
61
61
|
/** Environment variable to provide reason for force bypass */
|
|
62
62
|
const LUMENFLOW_FORCE_REASON_ENV = 'LUMENFLOW_FORCE_REASON';
|
|
63
|
+
/**
|
|
64
|
+
* Environment variable for WU tool identification (WU-1296)
|
|
65
|
+
* Pre-push hook checks this to allow approved tool operations
|
|
66
|
+
*/
|
|
67
|
+
const LUMENFLOW_WU_TOOL_ENV = 'LUMENFLOW_WU_TOOL';
|
|
68
|
+
/**
|
|
69
|
+
* Release tool identifier for pre-push hook bypass (WU-1296)
|
|
70
|
+
* Added to ALLOWED_WU_TOOLS in pre-push.mjs
|
|
71
|
+
*/
|
|
72
|
+
export const RELEASE_WU_TOOL = 'release';
|
|
73
|
+
/**
|
|
74
|
+
* Execute a function with LUMENFLOW_WU_TOOL set to 'release' (WU-1296)
|
|
75
|
+
*
|
|
76
|
+
* This allows the release command to push to main via micro-worktree
|
|
77
|
+
* without requiring LUMENFLOW_FORCE bypass. The pre-push hook checks
|
|
78
|
+
* LUMENFLOW_WU_TOOL and allows approved tools like 'release'.
|
|
79
|
+
*
|
|
80
|
+
* @param fn - Async function to execute with release env set
|
|
81
|
+
* @returns Result of the function
|
|
82
|
+
*/
|
|
83
|
+
export async function withReleaseEnv(fn) {
|
|
84
|
+
const originalValue = process.env[LUMENFLOW_WU_TOOL_ENV];
|
|
85
|
+
try {
|
|
86
|
+
process.env[LUMENFLOW_WU_TOOL_ENV] = RELEASE_WU_TOOL;
|
|
87
|
+
return await fn();
|
|
88
|
+
}
|
|
89
|
+
finally {
|
|
90
|
+
// Restore original value (or delete if it wasn't set)
|
|
91
|
+
if (originalValue === undefined) {
|
|
92
|
+
delete process.env[LUMENFLOW_WU_TOOL_ENV];
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
process.env[LUMENFLOW_WU_TOOL_ENV] = originalValue;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
63
99
|
/**
|
|
64
100
|
* Validate that a string is a valid semver version
|
|
65
101
|
*
|
|
@@ -327,35 +363,39 @@ async function main() {
|
|
|
327
363
|
}
|
|
328
364
|
else {
|
|
329
365
|
console.log(`${LOG_PREFIX} Bumping versions using micro-worktree isolation...`);
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
366
|
+
// WU-1296: Use withReleaseEnv to set LUMENFLOW_WU_TOOL=release
|
|
367
|
+
// This allows the micro-worktree push to main without LUMENFLOW_FORCE
|
|
368
|
+
await withReleaseEnv(async () => {
|
|
369
|
+
await withMicroWorktree({
|
|
370
|
+
operation: OPERATION_NAME,
|
|
371
|
+
id: `v${version}`,
|
|
372
|
+
logPrefix: LOG_PREFIX,
|
|
373
|
+
execute: async ({ worktreePath }) => {
|
|
374
|
+
// Check and exit changeset pre mode if active
|
|
375
|
+
if (isInChangesetPreMode(worktreePath)) {
|
|
376
|
+
console.log(`${LOG_PREFIX} Detected changeset pre-release mode, exiting...`);
|
|
377
|
+
exitChangesetPreMode(worktreePath);
|
|
378
|
+
console.log(`${LOG_PREFIX} ✅ Exited changeset pre mode`);
|
|
379
|
+
}
|
|
380
|
+
// Find package paths within the worktree
|
|
381
|
+
const worktreePackagePaths = findPackageJsonPaths(worktreePath);
|
|
382
|
+
// Update versions
|
|
383
|
+
console.log(`${LOG_PREFIX} Updating ${worktreePackagePaths.length} package versions...`);
|
|
384
|
+
await updatePackageVersions(worktreePackagePaths, version);
|
|
385
|
+
// Get relative paths for commit
|
|
386
|
+
const relativePaths = worktreePackagePaths.map((p) => getRelativePath(p, worktreePath));
|
|
387
|
+
// If we exited pre mode, include the deleted pre.json in files to commit
|
|
388
|
+
// (the deletion will be staged automatically by git add -A behavior)
|
|
389
|
+
const changesetPrePath = join(CHANGESET_DIR, CHANGESET_PRE_JSON);
|
|
390
|
+
const filesToCommit = [...relativePaths];
|
|
391
|
+
// Note: Deletion of pre.json is handled by git detecting the missing file
|
|
392
|
+
console.log(`${LOG_PREFIX} ✅ Versions updated to ${version}`);
|
|
393
|
+
return {
|
|
394
|
+
commitMessage: buildCommitMessage(version),
|
|
395
|
+
files: filesToCommit,
|
|
396
|
+
};
|
|
397
|
+
},
|
|
398
|
+
});
|
|
359
399
|
});
|
|
360
400
|
console.log(`${LOG_PREFIX} ✅ Version bump committed and pushed`);
|
|
361
401
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lumenflow/cli",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "Command-line interface for LumenFlow workflow framework",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"lumenflow",
|
|
@@ -142,11 +142,11 @@
|
|
|
142
142
|
"pretty-ms": "^9.2.0",
|
|
143
143
|
"simple-git": "^3.30.0",
|
|
144
144
|
"yaml": "^2.8.2",
|
|
145
|
-
"@lumenflow/core": "2.3.
|
|
146
|
-
"@lumenflow/
|
|
147
|
-
"@lumenflow/
|
|
148
|
-
"@lumenflow/agent": "2.3.
|
|
149
|
-
"@lumenflow/
|
|
145
|
+
"@lumenflow/core": "2.3.2",
|
|
146
|
+
"@lumenflow/memory": "2.3.2",
|
|
147
|
+
"@lumenflow/initiatives": "2.3.2",
|
|
148
|
+
"@lumenflow/agent": "2.3.2",
|
|
149
|
+
"@lumenflow/metrics": "2.3.2"
|
|
150
150
|
},
|
|
151
151
|
"devDependencies": {
|
|
152
152
|
"@vitest/coverage-v8": "^4.0.17",
|