@@ -3,12 +3,6 @@ const exec = require('@actions/exec');
33const path = require ( 'path' ) ;
44const fs = require ( 'fs' ) ;
55
6- // Using latest as default
7- const DEFAULT_FUNC_VERSION = 'latest' ;
8- const DEFAULT_BINARY_SOURCE = 'https://github.com/knative/func/releases/download' ;
9- const DEFAULT_LATEST_BINARY_SOURCE = 'https://github.com/knative/func/releases/latest/download' ;
10-
11- // Returns the binary name for the current OS/arch from GitHub releases
126function getOsBinName ( ) {
137 const osBinName = core . getInput ( 'binary' ) ;
148 if ( osBinName !== "" ) {
@@ -47,116 +41,90 @@ function resolveFullPathBin() {
4741 return path . resolve ( destination , bin ) ;
4842}
4943
50- // Normalizes version to release tag format: knative-vX.Y.Z
51- // Ex.: '1.16' or 'v1.16' will return 'knative-v1.16.0'
5244function smartVersionUpdate ( version ) {
53- const versionRegex = / ^ (?< knprefix > k n a t i v e - ) ? (?< prefix > v ? ) (?< major > \d + ) \. (?< minor > \d + ) ( \. (?< patch > \d + ) ) ? $ / ;
54- const match = version . match ( versionRegex ) ;
55- if ( ! match ) {
56- throw new Error ( `Invalid version format (${ version } ). Expected format: "1.16[.X]" or "v1.16[.X]"` ) ;
45+ const match = version . match ( / ^ (?: k n a t i v e - ) ? v ? ( \d + ) \. ( \d + ) (?: \. ( \d + ) ) ? $ / ) ;
46+ if ( ! match ) throw new Error ( `Invalid version format (${ version } ). Expected format: "1.16[.X]" or "v1.16[.X]"` ) ;
47+ return `knative-v${ match [ 1 ] } .${ match [ 2 ] } .${ match [ 3 ] ?? 0 } ` ;
48+ }
49+
50+ function resolveVersion ( ) {
51+ if ( core . getInput ( 'binarySource' ) ) return null ;
52+ const version = core . getInput ( 'version' ) || 'latest' ;
53+ if ( version . toLowerCase ( ) . trim ( ) === 'latest' ) return null ;
54+ return smartVersionUpdate ( version ) ;
55+ }
56+
57+ function resolveDownloadUrl ( version , binName ) {
58+ const binarySource = core . getInput ( 'binarySource' ) ;
59+ if ( binarySource ) {
60+ core . info ( `Using custom binary source: ${ binarySource } ` ) ;
61+ return binarySource ;
62+ }
63+
64+ if ( ! version ) {
65+ core . info ( 'Using latest version...' ) ;
66+ return `https://github.com/knative/func/releases/latest/download/${ binName } ` ;
5767 }
58- const knprefix = 'knative-' ;
59- const prefix = 'v' ;
60- const patch = match . groups . patch ?? 0 ;
61- return `${ knprefix } ${ prefix } ${ match . groups . major } .${ match . groups . minor } .${ patch } ` ;
68+ core . info ( `Using specific version ${ version } ` ) ;
69+ return `https://github.com/knative/func/releases/download/${ version } /${ binName } ` ;
6270}
6371
64- // Downloads binary from release URL and makes it executable
6572async function downloadFuncBinary ( url , binPath ) {
6673 core . info ( `Downloading from: ${ url } ` ) ;
67-
6874 await exec . exec ( 'curl' , [ '-L' , '--fail' , '-o' , binPath , url ] ) ;
6975
7076 if ( ! fs . existsSync ( binPath ) ) {
7177 throw new Error ( "Download failed, couldn't find the binary on disk" ) ;
7278 }
73-
7479 if ( process . env . RUNNER_OS !== 'Windows' ) {
7580 await exec . exec ( 'chmod' , [ '+x' , binPath ] ) ;
7681 }
7782}
7883
79- // Adds binary directory to PATH for current and subsequent steps
8084function addBinToPath ( binPath ) {
8185 const dir = path . dirname ( binPath ) ;
8286 fs . appendFileSync ( process . env . GITHUB_PATH , `\n${ dir } ` ) ;
83-
8487 if ( ! process . env . PATH . split ( path . delimiter ) . includes ( dir ) ) {
85- process . env . PATH = process . env . PATH + path . delimiter + dir ;
88+ process . env . PATH += path . delimiter + dir ;
8689 core . info ( `${ dir } added to PATH` ) ;
8790 }
8891}
8992
90- // Resolve download url based on given input
91- // binName: name of func binary when it is to be constructed for full URL
92- // (when not using binarySource)
93- function resolveDownloadUrl ( binName ) {
94- const binarySource = core . getInput ( 'binarySource' ) ;
95- if ( binarySource !== "" ) {
96- core . info ( `Using custom binary source: ${ binarySource } ` ) ;
97- return binarySource ;
98- }
99-
100- const versionInput = core . getInput ( 'version' ) || DEFAULT_FUNC_VERSION ;
101- if ( versionInput . toLowerCase ( ) . trim ( ) === DEFAULT_FUNC_VERSION ) {
102- core . info ( "Using latest version..." ) ;
103- return buildUrlString ( DEFAULT_FUNC_VERSION ) ;
104- }
105- const version = smartVersionUpdate ( versionInput ) ;
106- core . info ( `Using specific version ${ version } ` ) ;
107- return buildUrlString ( version ) ;
108-
109- function buildUrlString ( version ) {
110- return version === DEFAULT_FUNC_VERSION
111- ? `${ DEFAULT_LATEST_BINARY_SOURCE } /${ binName } `
112- : `${ DEFAULT_BINARY_SOURCE } /${ version } /${ binName } ` ;
93+ async function warnStaleVersion ( version ) {
94+ try {
95+ const res = await fetch ( 'https://github.com/knative/func/releases/latest' , {
96+ method : 'HEAD' ,
97+ redirect : 'manual' ,
98+ } ) ;
99+ const loc = res . headers . get ( 'location' ) ;
100+ if ( ! loc ) return ;
101+
102+ const latest = loc . split ( '/' ) . pop ( ) ;
103+ const toNum = ( v ) => { const m = v . match ( / ( \d + ) \. ( \d + ) / ) ; return m && m [ 1 ] * 100 + + m [ 2 ] ; } ;
104+ const diff = toNum ( latest ) - toNum ( version ) ;
105+
106+ if ( diff >= 3 ) {
107+ core . warning ( `You are using func ${ version } , which is ${ diff } minor versions behind the latest (${ latest } ). Upgrading is recommended.` ) ;
108+ }
109+ } catch {
110+ core . debug ( 'Skipping stale version check' ) ;
113111 }
114112}
115113
116114async function run ( ) {
117- let osBinName ;
118- try {
119- osBinName = getOsBinName ( ) ;
120- } catch ( error ) {
121- core . setFailed ( error . message ) ;
122- return ;
123- }
124-
125- let url ;
126115 try {
127- url = resolveDownloadUrl ( osBinName ) ;
128- } catch ( error ) {
129- core . setFailed ( `Failed to resolve url: ${ error . message } ` ) ;
130- return ;
131- }
132-
133- let fullPathBin ;
134- try {
135- fullPathBin = resolveFullPathBin ( ) ;
136- } catch ( error ) {
137- core . setFailed ( error . message ) ;
138- return ;
139- }
116+ const osBinName = getOsBinName ( ) ;
117+ const version = resolveVersion ( ) ;
118+ const url = resolveDownloadUrl ( version , osBinName ) ;
119+ const fullPathBin = resolveFullPathBin ( ) ;
140120
141- try {
142121 await downloadFuncBinary ( url , fullPathBin ) ;
143- } catch ( error ) {
144- core . setFailed ( `Download failed: ${ error . message } ` ) ;
145- return ;
146- }
147-
148- try {
149122 addBinToPath ( fullPathBin ) ;
150- } catch ( error ) {
151- core . setFailed ( error . message ) ;
152- return ;
153- }
154123
155- try {
124+ if ( version ) await warnStaleVersion ( version ) ;
156125 await exec . exec ( fullPathBin , [ 'version' ] ) ;
157126 } catch ( error ) {
158127 core . setFailed ( error . message ) ;
159- return ;
160128 }
161129}
162130
0 commit comments