@@ -15,6 +15,7 @@ import type {
1515} from '../../src/distributions/liberica/models.js' ;
1616import { HttpClient } from '@actions/http-client' ;
1717import os from 'os' ;
18+ import path from 'path' ;
1819
1920import manifestData from '../data/liberica.json' with { type : 'json' } ;
2021
@@ -253,35 +254,68 @@ describe('findPackageForDownload', () => {
253254 expect ( result . version ) . toBe ( expected ) ;
254255 } ) ;
255256
256- describe ( 'compound build versions' , ( ) => {
257+ describe . each ( [
258+ [ 17 , 20 ] ,
259+ [ 25 , 4 ]
260+ ] ) ( 'patch releases for Java %s.0.%s' , ( featureVersion , updateVersion ) => {
261+ const mainVersion = `${ featureVersion } .0.${ updateVersion } ` ;
262+
257263 beforeEach ( ( ) => {
258264 distribution [ 'getAvailableVersions' ] = async ( ) =>
259- [ '1' , '1.1 ' , '1.2 ' , '1 .10' ] . map ( build => ( {
260- featureVersion : 25 ,
265+ [ '+ 1' , '+10' , '.1+1' , '.1+2 ', '.1+10' , '.2+1 ', '.10+1 ' ] . map ( suffix => ( {
266+ featureVersion,
261267 interimVersion : 0 ,
262- updateVersion : 4 ,
263- buildVersion : 1 ,
264- version : `25.0.4+ ${ build } ` ,
265- downloadUrl : `https://download.bell-sw.com/java/25.0.4+ ${ build } /bellsoft-jdk25.0.4+ ${ build } -macos-aarch64.tar.gz`
268+ updateVersion,
269+ buildVersion : Number ( suffix . split ( '+' ) [ 1 ] ) ,
270+ version : `${ mainVersion } ${ suffix } ` ,
271+ downloadUrl : `https://download.bell-sw.com/java/${ mainVersion } ${ suffix } /bellsoft-jdk ${ mainVersion } ${ suffix } -macos-aarch64.tar.gz`
266272 } ) ) ;
267273 } ) ;
268274
269275 it . each ( [
270- [ '25.0.4+1.1' , '25.0.4+1.1' ] ,
271- [ '25.0.4+1' , '25.0.4+1' ] ,
272- [ '25.0.4' , '25.0.4+1.10' ] ,
273- [ '25' , '25.0.4+1.10' ]
274- ] ) ( 'version is %s -> %s' , async ( input , expected ) => {
276+ [ `${ mainVersion } +1.1` , `${ mainVersion } +1.1` , '.1+1' ] ,
277+ [ `${ mainVersion } +1.2` , `${ mainVersion } +1.2` , '.1+2' ] ,
278+ [ `${ mainVersion } +1.10` , `${ mainVersion } +1.10` , '.1+10' ] ,
279+ [ `${ mainVersion } +1` , `${ mainVersion } +1` , '+1' ] ,
280+ [ mainVersion , `${ mainVersion } +10.1` , '.10+1' ] ,
281+ [ `${ featureVersion } ` , `${ mainVersion } +10.1` , '.10+1' ]
282+ ] ) ( 'version is %s -> %s' , async ( input , expected , suffix ) => {
275283 const result = await distribution [ 'findPackageForDownload' ] ( input ) ;
276284 expect ( result ) . toEqual ( {
277285 version : expected ,
278- url : `https://download.bell-sw.com/java/${ expected } /bellsoft-jdk${ expected } -macos-aarch64.tar.gz`
286+ url : `https://download.bell-sw.com/java/${ mainVersion } ${ suffix } /bellsoft-jdk${ mainVersion } ${ suffix } -macos-aarch64.tar.gz`
279287 } ) ;
280288 } ) ;
281289
290+ it ( 'sorts builds within the same patch numerically' , async ( ) => {
291+ const versions = await distribution [ 'getAvailableVersions' ] ( ) ;
292+ distribution [ 'getAvailableVersions' ] = async ( ) =>
293+ versions . filter ( item => item . version . startsWith ( `${ mainVersion } .1+` ) ) ;
294+
295+ const result = await distribution [ 'findPackageForDownload' ] ( mainVersion ) ;
296+ expect ( result . version ) . toBe ( `${ mainVersion } +1.10` ) ;
297+ } ) ;
298+
299+ it ( 'selects the newest build for a four-component patch-only request' , async ( ) => {
300+ const patchDistribution = new LibericaDistributions ( {
301+ version : `${ mainVersion } .1` ,
302+ architecture : 'x64' ,
303+ packageType : 'jdk' ,
304+ checkLatest : false
305+ } ) ;
306+ patchDistribution [ 'getAvailableVersions' ] =
307+ distribution [ 'getAvailableVersions' ] ;
308+
309+ await expect (
310+ patchDistribution [ 'findPackageForDownload' ] (
311+ patchDistribution [ 'version' ]
312+ )
313+ ) . resolves . toMatchObject ( { version : `${ mainVersion } +1.10` } ) ;
314+ } ) ;
315+
282316 it ( 'does not substitute a different compound build' , async ( ) => {
283317 await expect (
284- distribution [ 'findPackageForDownload' ] ( '25.0.4 +1.3' )
318+ distribution [ 'findPackageForDownload' ] ( ` ${ mainVersion } +1.3` )
285319 ) . rejects . toThrow ( / N o m a t c h i n g v e r s i o n f o u n d f o r S e m V e r / ) ;
286320 } ) ;
287321 } ) ;
@@ -293,6 +327,160 @@ describe('findPackageForDownload', () => {
293327 } ) ;
294328} ) ;
295329
330+ describe ( 'patch request resolution from the constructor' , ( ) => {
331+ const releases : LibericaVersion [ ] = [ '17.0.20+10' , '17.0.20.1+1' ] . map (
332+ version => ( {
333+ featureVersion : 17 ,
334+ interimVersion : 0 ,
335+ updateVersion : 20 ,
336+ buildVersion : Number ( version . split ( '+' ) [ 1 ] ) ,
337+ version,
338+ downloadUrl : `https://download.bell-sw.com/java/${ version } /jdk.tar.gz`
339+ } )
340+ ) ;
341+ let cacheRoot : string ;
342+ let previousToolcache : string | undefined ;
343+
344+ beforeEach ( async ( ) => {
345+ previousToolcache = process . env [ 'RUNNER_TOOL_CACHE' ] ;
346+ cacheRoot = await fs . promises . mkdtemp ( path . join ( os . tmpdir ( ) , 'liberica-' ) ) ;
347+ process . env [ 'RUNNER_TOOL_CACHE' ] = cacheRoot ;
348+ for ( const version of [ '17.0.20-10' , '17.0.20-1.1' ] ) {
349+ const javaPath = path . join (
350+ cacheRoot ,
351+ 'Java_Liberica_jdk' ,
352+ version ,
353+ 'x64'
354+ ) ;
355+ await fs . promises . mkdir ( javaPath , { recursive : true } ) ;
356+ await fs . promises . writeFile ( `${ javaPath } .complete` , '' ) ;
357+ }
358+ } ) ;
359+
360+ afterEach ( async ( ) => {
361+ if ( previousToolcache === undefined ) {
362+ delete process . env [ 'RUNNER_TOOL_CACHE' ] ;
363+ } else {
364+ process . env [ 'RUNNER_TOOL_CACHE' ] = previousToolcache ;
365+ }
366+ await fs . promises . rm ( cacheRoot , { recursive : true , force : true } ) ;
367+ } ) ;
368+
369+ it . each ( [
370+ [ '17' , '17.0.20+1.1' , '17.0.20.1+1' ] ,
371+ [ '17.0.20' , '17.0.20+1.1' , '17.0.20.1+1' ] ,
372+ [ '17.0.20+10' , '17.0.20+10' , '17.0.20+10' ] ,
373+ [ '17.0.20+1.1' , '17.0.20+1.1' , '17.0.20.1+1' ] ,
374+ [ '17.0.20.1' , '17.0.20+1.1' , '17.0.20.1+1' ] ,
375+ [ '17.0.20.1+1' , '17.0.20+1.1' , '17.0.20.1+1' ] ,
376+ [ '17.0.20.0' , '17.0.20+10' , '17.0.20+10' ]
377+ ] ) (
378+ 'resolves %s consistently remotely and in cache' ,
379+ async ( input , expected , apiVersion ) => {
380+ const distribution = new LibericaDistributions ( {
381+ version : input ,
382+ architecture : 'x64' ,
383+ packageType : 'jdk' ,
384+ checkLatest : false
385+ } ) ;
386+ distribution [ 'getAvailableVersions' ] = async ( ) => releases ;
387+
388+ await expect (
389+ distribution [ 'findPackageForDownload' ] ( distribution [ 'version' ] )
390+ ) . resolves . toEqual ( {
391+ version : expected ,
392+ url : `https://download.bell-sw.com/java/${ apiVersion } /jdk.tar.gz`
393+ } ) ;
394+ expect ( distribution [ 'findInToolcache' ] ( ) ) . toEqual ( {
395+ version : expected ,
396+ path : path . join (
397+ cacheRoot ,
398+ 'Java_Liberica_jdk' ,
399+ expected . replace ( '+' , '-' ) ,
400+ 'x64'
401+ )
402+ } ) ;
403+ }
404+ ) ;
405+
406+ it . each ( [ '17.0.20.2' , '17.0.20+1.2' ] ) (
407+ 'does not substitute a different patch or exact build for %s' ,
408+ async version => {
409+ const distribution = new LibericaDistributions ( {
410+ version,
411+ architecture : 'x64' ,
412+ packageType : 'jdk' ,
413+ checkLatest : false
414+ } ) ;
415+ distribution [ 'getAvailableVersions' ] = async ( ) => releases ;
416+
417+ await expect (
418+ distribution [ 'findPackageForDownload' ] ( distribution [ 'version' ] )
419+ ) . rejects . toThrow ( / N o m a t c h i n g v e r s i o n f o u n d / ) ;
420+ expect ( distribution [ 'findInToolcache' ] ( ) ) . toBeNull ( ) ;
421+ }
422+ ) ;
423+
424+ it ( 'keeps patch-only and exact-build resolution cache identities distinct' , ( ) => {
425+ const distribution = new LibericaDistributions ( {
426+ version : '17.0.20.1' ,
427+ architecture : 'x64' ,
428+ packageType : 'jdk' ,
429+ checkLatest : false
430+ } ) ;
431+ expect ( distribution [ 'version' ] ) . toBe ( '17.0.20.1' ) ;
432+ } ) ;
433+
434+ it ( 'orders main versions, patches, and builds consistently in cache' , async ( ) => {
435+ for ( const version of [ '17.0.20-1.2' , '17.0.20-1.10' , '17.0.21-1' ] ) {
436+ const javaPath = path . join (
437+ cacheRoot ,
438+ 'Java_Liberica_jdk' ,
439+ version ,
440+ 'x64'
441+ ) ;
442+ await fs . promises . mkdir ( javaPath , { recursive : true } ) ;
443+ await fs . promises . writeFile ( `${ javaPath } .complete` , '' ) ;
444+ }
445+
446+ for ( const [ version , expected ] of [
447+ [ '17' , '17.0.21+1' ] ,
448+ [ '17.0.20' , '17.0.20+1.10' ] ,
449+ [ '17.0.20.1' , '17.0.20+1.10' ]
450+ ] ) {
451+ const distribution = new LibericaDistributions ( {
452+ version,
453+ architecture : 'x64' ,
454+ packageType : 'jdk' ,
455+ checkLatest : false
456+ } ) ;
457+ expect ( distribution [ 'findInToolcache' ] ( ) ?. version ) . toBe ( expected ) ;
458+ }
459+ } ) ;
460+
461+ it ( 'preserves early-access handling for patch-only requests' , async ( ) => {
462+ const javaPath = path . join (
463+ cacheRoot ,
464+ 'Java_Liberica_jdk' ,
465+ '17.0.20-ea.1.2' ,
466+ 'x64'
467+ ) ;
468+ await fs . promises . mkdir ( javaPath , { recursive : true } ) ;
469+ await fs . promises . writeFile ( `${ javaPath } .complete` , '' ) ;
470+ const distribution = new LibericaDistributions ( {
471+ version : '17.0.20.1-ea' ,
472+ architecture : 'x64' ,
473+ packageType : 'jdk' ,
474+ checkLatest : false
475+ } ) ;
476+ expect ( distribution [ 'stable' ] ) . toBe ( false ) ;
477+ expect ( distribution [ 'findInToolcache' ] ( ) ) . toEqual ( {
478+ version : '17.0.20+1.2' ,
479+ path : javaPath
480+ } ) ;
481+ } ) ;
482+ } ) ;
483+
296484describe ( 'getPlatformOption' , ( ) => {
297485 beforeEach ( ( ) => {
298486 // The linux row below is glibc, so pin the Alpine probe rather than
@@ -369,6 +557,36 @@ describe('convertVersionToSemver', () => {
369557 } ,
370558 '11.0.0+13'
371559 ] ,
560+ [
561+ {
562+ version : '17.0.20.1+1' ,
563+ featureVersion : 17 ,
564+ interimVersion : 0 ,
565+ updateVersion : 20 ,
566+ buildVersion : 1
567+ } ,
568+ '17.0.20+1.1'
569+ ] ,
570+ [
571+ {
572+ version : '25.0.4.1+1' ,
573+ featureVersion : 25 ,
574+ interimVersion : 0 ,
575+ updateVersion : 4 ,
576+ buildVersion : 1
577+ } ,
578+ '25.0.4+1.1'
579+ ] ,
580+ [
581+ {
582+ version : '17.0.20.1+2' ,
583+ featureVersion : 17 ,
584+ interimVersion : 0 ,
585+ updateVersion : 20 ,
586+ buildVersion : 2
587+ } ,
588+ '17.0.20+1.2'
589+ ] ,
372590 [
373591 {
374592 version : '25.0.4+1.1' ,
0 commit comments