@@ -244,21 +244,73 @@ function publishTest(repoDir, modeConfig, dryRun) {
244244 }
245245 }
246246
247+ // Get the latest stable version from npm
248+ let latestStableVersion = null ;
249+ if ( name ) {
250+ try {
251+ const result = runQuiet ( `npm view ${ name } @latest version` , repoDir ) ;
252+ if ( result && result . trim ( ) ) {
253+ latestStableVersion = result . trim ( ) ;
254+ console . log ( `Latest published @latest version: ${ latestStableVersion } ` ) ;
255+ }
256+ } catch ( err ) {
257+ console . log ( `No @latest version published yet` ) ;
258+ }
259+ }
260+
247261 let version ;
248262
249263 // Strategy: Always compute baseVersion from the latest published @test version first
250264 // This ensures we're incrementing from what npm sees, not what our local checkout has
251265 if ( latestTestVersion ) {
252- // Extract the base version from the latest published @test version
253- const publishedMatch = latestTestVersion . match ( new RegExp ( `^(.+?)-${ preid . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) } \\.\\d+$` ) ) ;
254- if ( publishedMatch && publishedMatch [ 1 ] ) {
255- const publishedBaseVersion = publishedMatch [ 1 ] ;
256- console . log ( `Base version from published @${ preid } : ${ publishedBaseVersion } ` ) ;
266+ // Extract the base version and counter from the latest published @test version
267+ // Match pattern 1: X.Y.Z-preid.N (standard test version with counter)
268+ // Match pattern 2: X.Y.Z (just a version, no test suffix yet)
269+ const regexPattern = `^(\\d+\\.\\d+\\.\\d+)(?:.*)?-${ preid . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) } \\.(\\d+)$` ;
270+ console . log ( `[DEBUG] Testing regex: ${ regexPattern } ` ) ;
271+ console . log ( `[DEBUG] Against version: ${ latestTestVersion } ` ) ;
272+ const counterMatch = latestTestVersion . match ( new RegExp ( regexPattern ) ) ;
273+ console . log ( `[DEBUG] Regex match result:` , counterMatch ) ;
274+
275+ if ( counterMatch && counterMatch [ 1 ] ) {
276+ // Found a version with -test.N pattern
277+ const publishedBaseVersion = counterMatch [ 1 ] ;
278+ const publishedCounter = parseInt ( counterMatch [ 2 ] , 10 ) ;
279+ console . log ( `Base version from published @${ preid } : ${ publishedBaseVersion } , counter: ${ publishedCounter } ` ) ;
257280
258- // Extract counter from latest @test version
259- const counterMatch = latestTestVersion . match ( new RegExp ( `^${ publishedBaseVersion . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, '\\$&' ) } -${ preid } \\.(\\d+)$` ) ) ;
260- if ( counterMatch && counterMatch [ 1 ] ) {
261- const nextCounter = parseInt ( counterMatch [ 1 ] , 10 ) + 1 ;
281+ // Check if the base version from @test matches the latest stable
282+ // If yes, we need to bump to the next patch version for the test
283+ if ( latestStableVersion && publishedBaseVersion === latestStableVersion ) {
284+ console . log ( `Base version ${ publishedBaseVersion } matches latest stable. Bumping to next patch for test...` ) ;
285+ // Increment patch version and start at -test.0
286+ const versionParts = publishedBaseVersion . split ( '.' ) ;
287+ if ( versionParts . length >= 3 ) {
288+ versionParts [ 2 ] = String ( parseInt ( versionParts [ 2 ] , 10 ) + 1 ) ;
289+ const newBaseVersion = versionParts . join ( '.' ) ;
290+ version = `${ newBaseVersion } -${ preid } .0` ;
291+ console . log ( `Bumping to ${ version } ...` ) ;
292+ } else {
293+ // Fallback to normal bump if version format is unexpected
294+ console . log ( `Unexpected version format. Doing normal prerelease bump...` ) ;
295+ const originalScripts = disableVersionScripts ( repoDir ) ;
296+ try {
297+ run ( `npm version prerelease --preid ${ preid } --no-git-tag-version` , repoDir , dryRun ) ;
298+ } finally {
299+ restoreVersionScripts ( repoDir , originalScripts ) ;
300+ }
301+ version = getPackageVersion ( repoDir ) ;
302+ }
303+
304+ // Update package.json manually with this version
305+ if ( version && ! dryRun ) {
306+ const pkgPath = path . join ( repoDir , 'package.json' ) ;
307+ const pkgData = readJson ( pkgPath ) ;
308+ pkgData . version = version ;
309+ fs . writeFileSync ( pkgPath , JSON . stringify ( pkgData , null , 2 ) + '\n' ) ;
310+ }
311+ } else {
312+ // Base version doesn't match stable, increment the test counter
313+ const nextCounter = parseInt ( counterMatch [ 2 ] , 10 ) + 1 ;
262314 version = `${ publishedBaseVersion } -${ preid } .${ nextCounter } ` ;
263315 console . log ( `Latest @${ preid } is ${ latestTestVersion } . Incrementing to ${ version } ...` ) ;
264316
@@ -267,9 +319,58 @@ function publishTest(repoDir, modeConfig, dryRun) {
267319 const pkgData = readJson ( pkgPath ) ;
268320 pkgData . version = version ;
269321 fs . writeFileSync ( pkgPath , JSON . stringify ( pkgData , null , 2 ) + '\n' ) ;
322+ }
323+ } else {
324+ // Couldn't find exact -test.N pattern, but we do have a @test version
325+ // Extract just the X.Y.Z base from latestTestVersion
326+ const baseVersionMatch = latestTestVersion . match ( / ^ ( \d + \. \d + \. \d + ) / ) ;
327+ if ( baseVersionMatch && baseVersionMatch [ 1 ] ) {
328+ const publishedBaseVersion = baseVersionMatch [ 1 ] ;
329+ console . log ( `Found @${ preid } version but no -${ preid } .N pattern. Extracted base: ${ publishedBaseVersion } ` ) ;
330+
331+ // Check if this base version matches the latest stable
332+ if ( latestStableVersion && publishedBaseVersion === latestStableVersion ) {
333+ console . log ( `Base version ${ publishedBaseVersion } matches latest stable. Bumping to next patch for test...` ) ;
334+ const versionParts = publishedBaseVersion . split ( '.' ) ;
335+ if ( versionParts . length >= 3 ) {
336+ versionParts [ 2 ] = String ( parseInt ( versionParts [ 2 ] , 10 ) + 1 ) ;
337+ const newBaseVersion = versionParts . join ( '.' ) ;
338+ version = `${ newBaseVersion } -${ preid } .0` ;
339+ console . log ( `Bumping to ${ version } ...` ) ;
340+ } else {
341+ console . log ( `Unexpected version format. Doing normal prerelease bump...` ) ;
342+ const originalScripts = disableVersionScripts ( repoDir ) ;
343+ try {
344+ run ( `npm version prerelease --preid ${ preid } --no-git-tag-version` , repoDir , dryRun ) ;
345+ } finally {
346+ restoreVersionScripts ( repoDir , originalScripts ) ;
347+ }
348+ version = getPackageVersion ( repoDir ) ;
349+ }
350+
351+ // Update package.json manually with this version
352+ if ( version && ! dryRun ) {
353+ const pkgPath = path . join ( repoDir , 'package.json' ) ;
354+ const pkgData = readJson ( pkgPath ) ;
355+ pkgData . version = version ;
356+ fs . writeFileSync ( pkgPath , JSON . stringify ( pkgData , null , 2 ) + '\n' ) ;
357+ }
358+ } else {
359+ // Base version doesn't match stable, use this version as starting point for -test
360+ version = `${ publishedBaseVersion } -${ preid } .0` ;
361+ console . log ( `Base version ${ publishedBaseVersion } differs from stable. Starting test version at ${ version } ...` ) ;
362+
363+ // Update package.json manually with this version
364+ if ( ! dryRun ) {
365+ const pkgPath = path . join ( repoDir , 'package.json' ) ;
366+ const pkgData = readJson ( pkgPath ) ;
367+ pkgData . version = version ;
368+ fs . writeFileSync ( pkgPath , JSON . stringify ( pkgData , null , 2 ) + '\n' ) ;
369+ }
370+ }
270371 } else {
271- // Couldn't parse the counter , do normal prerelease bump
272- console . log ( `Found @${ preid } version but couldn't parse counter . Doing normal prerelease bump...` ) ;
372+ // Couldn't parse base version at all , do normal prerelease bump
373+ console . log ( `Found @${ preid } ( ${ latestTestVersion } ) but couldn't parse base version . Doing normal prerelease bump...` ) ;
273374 const originalScripts = disableVersionScripts ( repoDir ) ;
274375 try {
275376 run ( `npm version prerelease --preid ${ preid } --no-git-tag-version` , repoDir , dryRun ) ;
@@ -283,39 +384,58 @@ function publishTest(repoDir, modeConfig, dryRun) {
283384 console . log ( `After prerelease bump: ${ version } ` ) ;
284385 }
285386 }
286- } else {
287- // Couldn't parse base version from latest @test, do normal prerelease bump
288- console . log ( `Found @${ preid } (${ latestTestVersion } ) but couldn't parse base version. Doing normal prerelease bump...` ) ;
289- const originalScripts = disableVersionScripts ( repoDir ) ;
290- try {
291- run ( `npm version prerelease --preid ${ preid } --no-git-tag-version` , repoDir , dryRun ) ;
292- } finally {
293- restoreVersionScripts ( repoDir , originalScripts ) ;
294- }
295- version = getPackageVersion ( repoDir ) ;
296- if ( dryRun ) {
297- console . log ( `[dry-run simulation] Prerelease version would be: ${ version } ` ) ;
298- } else {
299- console . log ( `After prerelease bump: ${ version } ` ) ;
300- }
301387 }
302388 } else {
303- // No existing @test version, do normal prerelease bump from local version
304- console . log ( `No @${ preid } version found. Doing normal prerelease bump from local version...` ) ;
305- const originalScripts = disableVersionScripts ( repoDir ) ;
306- try {
307- run ( `npm version prerelease --preid ${ preid } --no-git-tag-version` , repoDir , dryRun ) ;
308- } finally {
309- restoreVersionScripts ( repoDir , originalScripts ) ;
310- }
311- version = getPackageVersion ( repoDir ) ;
312- if ( dryRun && localVersion ) {
313- // In dry-run, simulate the bump
314- const nextVersion = `${ localVersion } -${ preid } .0` ;
315- console . log ( `[dry-run simulation] Prerelease version would be: ${ nextVersion } ` ) ;
316- version = nextVersion ;
389+ // No existing @test version, but we can be smart about versioning
390+ console . log ( `No @${ preid } version found. Determining strategy for first test release...` ) ;
391+
392+ // Extract base version from local version (just X.Y.Z, strip any pre-release identifiers)
393+ const localBaseMatch = localVersion . match ( / ^ ( \d + \. \d + \. \d + ) / ) ;
394+ const localBaseVersion = localBaseMatch ? localBaseMatch [ 1 ] : localVersion ;
395+ console . log ( `Local base version: ${ localBaseVersion } ` ) ;
396+
397+ if ( latestStableVersion && localBaseVersion === latestStableVersion ) {
398+ // Local version base matches latest stable, so bump patch and start at -test.0
399+ console . log ( `Local base ${ localBaseVersion } matches latest stable. Bumping to next patch for test...` ) ;
400+ const versionParts = localBaseVersion . split ( '.' ) ;
401+ if ( versionParts . length >= 3 ) {
402+ versionParts [ 2 ] = String ( parseInt ( versionParts [ 2 ] , 10 ) + 1 ) ;
403+ const newBaseVersion = versionParts . join ( '.' ) ;
404+ version = `${ newBaseVersion } -${ preid } .0` ;
405+ console . log ( `Using ${ version } for test release...` ) ;
406+
407+ if ( ! dryRun ) {
408+ const pkgPath = path . join ( repoDir , 'package.json' ) ;
409+ const pkgData = readJson ( pkgPath ) ;
410+ pkgData . version = version ;
411+ fs . writeFileSync ( pkgPath , JSON . stringify ( pkgData , null , 2 ) + '\n' ) ;
412+ }
413+ } else {
414+ // Fallback to normal prerelease bump if format is unexpected
415+ console . log ( `Unexpected version format. Doing normal prerelease bump...` ) ;
416+ const originalScripts = disableVersionScripts ( repoDir ) ;
417+ try {
418+ run ( `npm version prerelease --preid ${ preid } --no-git-tag-version` , repoDir , dryRun ) ;
419+ } finally {
420+ restoreVersionScripts ( repoDir , originalScripts ) ;
421+ }
422+ version = getPackageVersion ( repoDir ) ;
423+ }
317424 } else {
318- console . log ( `After prerelease bump: ${ version } ` ) ;
425+ // Local version is newer than stable (or no stable exists), use it with -test.0
426+ version = `${ localBaseVersion } -${ preid } .0` ;
427+ console . log ( `Local base ${ localBaseVersion } is ahead of stable. Starting test at ${ version } ...` ) ;
428+
429+ if ( ! dryRun ) {
430+ const pkgPath = path . join ( repoDir , 'package.json' ) ;
431+ const pkgData = readJson ( pkgPath ) ;
432+ pkgData . version = version ;
433+ fs . writeFileSync ( pkgPath , JSON . stringify ( pkgData , null , 2 ) + '\n' ) ;
434+ }
435+ }
436+
437+ if ( dryRun ) {
438+ console . log ( `[dry-run simulation] Test version would be: ${ version } ` ) ;
319439 }
320440 }
321441
0 commit comments