@wipcomputer/wip-ai-devops-toolbox 1.9.69-alpha.1 → 1.9.70
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/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.70 (2026-04-01)
|
|
3
4
|
|
|
5
|
+
### wip-release
|
|
6
|
+
- Fix semver NaN bug: `semver.inc()` returns null on prerelease versions, causing NaN propagation through the entire release pipeline
|
|
7
|
+
- Add sub-tool independent version validation: detects when sub-tool package.json versions drift from root and warns before publish
|
|
4
8
|
|
|
9
|
+
### wip-branch-guard
|
|
10
|
+
- Add cooldown skip: avoids redundant guard checks within rapid tool sequences
|
|
11
|
+
- Add trash pattern exclusion: allows `.Trash` and system cleanup paths through the guard
|
|
5
12
|
|
|
6
13
|
|
|
7
14
|
|
package/package.json
CHANGED
|
@@ -25,7 +25,8 @@ export function detectCurrentVersion(repoPath) {
|
|
|
25
25
|
* Bump a semver string by level.
|
|
26
26
|
*/
|
|
27
27
|
export function bumpSemver(version, level) {
|
|
28
|
-
const
|
|
28
|
+
const base = version.replace(/-.*$/, '');
|
|
29
|
+
const [major, minor, patch] = base.split('.').map(Number);
|
|
29
30
|
switch (level) {
|
|
30
31
|
case 'major': return `${major + 1}.0.0`;
|
|
31
32
|
case 'minor': return `${major}.${minor + 1}.0`;
|
|
@@ -1674,27 +1675,33 @@ export async function release({ repoPath, level, notes, notesSource, dryRun, noP
|
|
|
1674
1675
|
writePackageVersion(repoPath, newVersion);
|
|
1675
1676
|
console.log(` ✓ package.json -> ${newVersion}`);
|
|
1676
1677
|
|
|
1677
|
-
// 1.5.
|
|
1678
|
+
// 1.5. Validate sub-tool version bumps in toolbox repos (tools/*/)
|
|
1679
|
+
// Sub-tools have independent versions. If files changed since last tag
|
|
1680
|
+
// but the version didn't bump, warn. Developer must bump manually.
|
|
1678
1681
|
const toolsDir = join(repoPath, 'tools');
|
|
1679
1682
|
if (existsSync(toolsDir)) {
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1683
|
+
const lastTag = (() => { try { return execFileSync('git', ['describe', '--tags', '--abbrev=0'], { cwd: repoPath, encoding: 'utf8' }).trim(); } catch { return null; } })();
|
|
1684
|
+
if (lastTag) {
|
|
1685
|
+
try {
|
|
1686
|
+
const entries = readdirSync(toolsDir, { withFileTypes: true });
|
|
1687
|
+
for (const entry of entries) {
|
|
1688
|
+
if (!entry.isDirectory()) continue;
|
|
1689
|
+
const subDir = join('tools', entry.name);
|
|
1690
|
+
const subPkgPath = join(toolsDir, entry.name, 'package.json');
|
|
1691
|
+
if (!existsSync(subPkgPath)) continue;
|
|
1687
1692
|
try {
|
|
1688
|
-
const
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1693
|
+
const diff = execFileSync('git', ['diff', '--name-only', lastTag, 'HEAD', '--', subDir], { cwd: repoPath, encoding: 'utf8' }).trim();
|
|
1694
|
+
if (!diff) continue;
|
|
1695
|
+
const currentSubVersion = JSON.parse(readFileSync(subPkgPath, 'utf8')).version;
|
|
1696
|
+
const oldSubVersion = (() => { try { return JSON.parse(execFileSync('git', ['show', `${lastTag}:${subDir}/package.json`], { cwd: repoPath, encoding: 'utf8' })).version; } catch { return null; } })();
|
|
1697
|
+
if (currentSubVersion === oldSubVersion) {
|
|
1698
|
+
console.log(` ! WARNING: ${entry.name} has changed files since ${lastTag} but version is still ${currentSubVersion}`);
|
|
1699
|
+
console.log(` Changed: ${diff.split('\n').join(', ')}`);
|
|
1700
|
+
console.log(` Bump tools/${entry.name}/package.json before releasing.`);
|
|
1701
|
+
}
|
|
1692
1702
|
} catch {}
|
|
1693
1703
|
}
|
|
1694
|
-
}
|
|
1695
|
-
} catch {}
|
|
1696
|
-
if (subBumped > 0) {
|
|
1697
|
-
console.log(` ✓ ${subBumped} sub-tool(s) -> ${newVersion}`);
|
|
1704
|
+
} catch {}
|
|
1698
1705
|
}
|
|
1699
1706
|
}
|
|
1700
1707
|
|
|
@@ -2040,6 +2047,37 @@ export async function releasePrerelease({ repoPath, track, notes, dryRun, noPubl
|
|
|
2040
2047
|
writePackageVersion(repoPath, newVersion);
|
|
2041
2048
|
console.log(` \u2713 package.json -> ${newVersion}`);
|
|
2042
2049
|
|
|
2050
|
+
// 1.5. Validate sub-tool version bumps in toolbox repos (tools/*/)
|
|
2051
|
+
// If a sub-tool's files changed since the last tag but its version didn't bump, warn.
|
|
2052
|
+
const toolsDir = join(repoPath, 'tools');
|
|
2053
|
+
if (existsSync(toolsDir)) {
|
|
2054
|
+
const lastTag = (() => { try { return execFileSync('git', ['describe', '--tags', '--abbrev=0'], { cwd: repoPath, encoding: 'utf8' }).trim(); } catch { return null; } })();
|
|
2055
|
+
if (lastTag) {
|
|
2056
|
+
try {
|
|
2057
|
+
const entries = readdirSync(toolsDir, { withFileTypes: true });
|
|
2058
|
+
for (const entry of entries) {
|
|
2059
|
+
if (!entry.isDirectory()) continue;
|
|
2060
|
+
const subDir = join('tools', entry.name);
|
|
2061
|
+
const subPkgPath = join(toolsDir, entry.name, 'package.json');
|
|
2062
|
+
if (!existsSync(subPkgPath)) continue;
|
|
2063
|
+
// Check if any files in this sub-tool changed since last tag
|
|
2064
|
+
try {
|
|
2065
|
+
const diff = execFileSync('git', ['diff', '--name-only', lastTag, 'HEAD', '--', subDir], { cwd: repoPath, encoding: 'utf8' }).trim();
|
|
2066
|
+
if (!diff) continue; // No changes, skip
|
|
2067
|
+
// Files changed. Check if version was bumped.
|
|
2068
|
+
const currentSubVersion = JSON.parse(readFileSync(subPkgPath, 'utf8')).version;
|
|
2069
|
+
const oldSubVersion = (() => { try { return JSON.parse(execFileSync('git', ['show', `${lastTag}:${subDir}/package.json`], { cwd: repoPath, encoding: 'utf8' })).version; } catch { return null; } })();
|
|
2070
|
+
if (currentSubVersion === oldSubVersion) {
|
|
2071
|
+
console.log(` ! WARNING: ${entry.name} has changed files since ${lastTag} but version is still ${currentSubVersion}`);
|
|
2072
|
+
console.log(` Changed: ${diff.split('\n').join(', ')}`);
|
|
2073
|
+
console.log(` Bump tools/${entry.name}/package.json before releasing.`);
|
|
2074
|
+
}
|
|
2075
|
+
} catch {}
|
|
2076
|
+
}
|
|
2077
|
+
} catch {}
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
|
|
2043
2081
|
// 2. Update CHANGELOG.md (lightweight entry)
|
|
2044
2082
|
updateChangelog(repoPath, newVersion, notes || `${track} prerelease`);
|
|
2045
2083
|
console.log(` \u2713 CHANGELOG.md updated`);
|
|
@@ -2241,27 +2279,31 @@ export async function releaseHotfix({ repoPath, notes, notesSource, dryRun, noPu
|
|
|
2241
2279
|
writePackageVersion(repoPath, newVersion);
|
|
2242
2280
|
console.log(` \u2713 package.json -> ${newVersion}`);
|
|
2243
2281
|
|
|
2244
|
-
// 1.5.
|
|
2282
|
+
// 1.5. Validate sub-tool version bumps in toolbox repos (tools/*/)
|
|
2245
2283
|
const toolsDir = join(repoPath, 'tools');
|
|
2246
2284
|
if (existsSync(toolsDir)) {
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2285
|
+
const lastTag = (() => { try { return execFileSync('git', ['describe', '--tags', '--abbrev=0'], { cwd: repoPath, encoding: 'utf8' }).trim(); } catch { return null; } })();
|
|
2286
|
+
if (lastTag) {
|
|
2287
|
+
try {
|
|
2288
|
+
const entries = readdirSync(toolsDir, { withFileTypes: true });
|
|
2289
|
+
for (const entry of entries) {
|
|
2290
|
+
if (!entry.isDirectory()) continue;
|
|
2291
|
+
const subDir = join('tools', entry.name);
|
|
2292
|
+
const subPkgPath = join(toolsDir, entry.name, 'package.json');
|
|
2293
|
+
if (!existsSync(subPkgPath)) continue;
|
|
2254
2294
|
try {
|
|
2255
|
-
const
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2295
|
+
const diff = execFileSync('git', ['diff', '--name-only', lastTag, 'HEAD', '--', subDir], { cwd: repoPath, encoding: 'utf8' }).trim();
|
|
2296
|
+
if (!diff) continue;
|
|
2297
|
+
const currentSubVersion = JSON.parse(readFileSync(subPkgPath, 'utf8')).version;
|
|
2298
|
+
const oldSubVersion = (() => { try { return JSON.parse(execFileSync('git', ['show', `${lastTag}:${subDir}/package.json`], { cwd: repoPath, encoding: 'utf8' })).version; } catch { return null; } })();
|
|
2299
|
+
if (currentSubVersion === oldSubVersion) {
|
|
2300
|
+
console.log(` ! WARNING: ${entry.name} has changed files since ${lastTag} but version is still ${currentSubVersion}`);
|
|
2301
|
+
console.log(` Changed: ${diff.split('\n').join(', ')}`);
|
|
2302
|
+
console.log(` Bump tools/${entry.name}/package.json before releasing.`);
|
|
2303
|
+
}
|
|
2259
2304
|
} catch {}
|
|
2260
2305
|
}
|
|
2261
|
-
}
|
|
2262
|
-
} catch {}
|
|
2263
|
-
if (subBumped > 0) {
|
|
2264
|
-
console.log(` \u2713 ${subBumped} sub-tool(s) -> ${newVersion}`);
|
|
2306
|
+
} catch {}
|
|
2265
2307
|
}
|
|
2266
2308
|
}
|
|
2267
2309
|
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
# Release Notes: wip-branch-guard v1.9.64
|
|
2
|
-
|
|
3
|
-
**One-line summary of what this release does**
|
|
4
|
-
|
|
5
|
-
Tell the story. What was broken or missing? What did we build? Why does the user care?
|
|
6
|
-
Write at least one real paragraph of prose. Not just bullets. The release notes gate
|
|
7
|
-
will block if there is no narrative. Bullets are fine for details, but the story comes first.
|
|
8
|
-
|
|
9
|
-
## The story
|
|
10
|
-
|
|
11
|
-
(Write a paragraph here. What was the problem? What does this release fix? Why does it matter?
|
|
12
|
-
This is what users read. Make it worth reading.)
|
|
13
|
-
|
|
14
|
-
## Issues closed
|
|
15
|
-
|
|
16
|
-
- #296
|
|
17
|
-
- #295
|
|
18
|
-
|
|
19
|
-
## How to verify
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
# Commands to test the changes
|
|
23
|
-
```
|