import * as tc from '@actions/tool-cache' ; import * as core from '@actions/core' ; import * as semver from 'semver' ; import * as httpm from '@actions/http-client' ; import os from 'os' ; const DEFAULT_RELEASES_URL = 'https://releases.hashicorp.com' ; interface Build { arch : string ; filename : string ; name : string ; os : string ; url : string ; version : string ; } interface Version { name : string ; shasums : string ; shasums_signature : string ; version : string ; builds : Build [ ] ; } interface MetadataIndex { name : string ; versions : Versions ; } interface Versions { [ version ] : Version ; } export function releasesUrl ( ) { return core . getInput ( 'releases_url' ) || DEFAULT_RELEASES_URL ; } async function getMetadata ( product ) { const http = new httpm . HttpClient ( 'action-setup-waypoint' , [ ] , { allowRetries : true , maxRetries : 5 , } ) ; try { const resp = await http . getJson < MetadataIndex > ( `${ releasesUrl ( ) }/${ product }/index.json` ) ; return resp . result || undefined ; } catch ( err ) { throw new Error ( `Failed to fetch version metadata file ${ err }` ) ; } } param versionSpec param versions returns function matchVersion ( versionSpec , versions ) { let version = '' ; versions = versions . sort ( ( a , b ) => { if ( semver . gt ( a , b ) ) { return 1 ; } return - 1 ; } ) ; for ( let i = versions . length - 1 ; i >= 0 ; i -- ) { const potential = versions [ i ] ; const satisfied = semver . satisfies ( potential , versionSpec ) ; if ( satisfied ) { version = potential ; break ; } } if ( version ) { core . debug ( `found version match: ${ version }` ) ; } else { core . debug ( `version match not found for ${ version }` ) ; } return version ; } param versionSpec returns async function getVersion ( product , versionSpec ) { core . debug ( 'downloading release metadata to determine latest version' ) ; const meta = await getMetadata ( product ) ; const versions = [ ] ; if ( ! meta ?. versions ) { core . setFailed ( `response does not contain versions. ${ meta ?. versions }` ) ; return ; } for ( const version of Object . values ( meta . versions ) ) { versions . push ( version . version ) ; } const version = matchVersion ( versionSpec , versions ) ; return meta . versions [ version ] ; } param configuredVersion returns export async function getBinary ( product , configuredVersion ) { const version = await getVersion ( product , configuredVersion ) ; if ( ! version ?. version ) { throw new Error ( `${ product } version '${ configuredVersion }' does not exist` ) ; } let toolPath ; toolPath = tc . find ( product , version . version , os . arch ( ) ) ; if ( toolPath ) { core . info ( `found in cache: ${ toolPath }` ) ; return toolPath ; } const platform = os . platform ( ) ; const arch = os . arch ( ) ; const goArch = ( ) : string => { switch ( arch ) { case 'x64' : return 'amd64' ; case 'x32' : return '386' ; default : return arch ; } } ; const goPlatform = ( ) : string => { switch ( platform ) { case 'win32' : return 'windows' ; default : return platform ; } } ; core . info ( `downloading ${ version . version } from ${ releasesUrl ( ) }` ) ; try { toolPath = await tc . downloadTool ( `${ releasesUrl ( ) }/${ product }/${ version ?. version }/${ product }_${ version ?. version }_${ goPlatform ( ) }_${ goArch ( ) }.zip` ) ; } catch ( error ) { core . debug ( error ) ; } const extractedPath = await tc . extractZip ( toolPath ) ; const dir = await tc . cacheDir ( extractedPath , product , version . version , os . arch ( ) ) ; return dir ; }