@@ -3,112 +3,139 @@ const exec = require('@actions/exec');
33const path = require ( 'path' ) ;
44const fs = require ( 'fs' ) ;
55
6- // Static version - update manually when new func releases are available
7- const DEFAULT_FUNC_VERSION = 'knative-v1.20.1 ' ;
6+ // Using latest as default
7+ const DEFAULT_FUNC_VERSION = 'latest ' ;
88
99// Returns the binary name for the current OS/arch from GitHub releases
1010function getOsBinName ( ) {
11- const runnerOS = process . env . RUNNER_OS ;
12- const runnerArch = process . env . RUNNER_ARCH ;
13-
14- if ( runnerOS === 'Linux' ) {
15- switch ( runnerArch ) {
16- case 'X64' : return 'func_linux_amd64' ;
17- case 'ARM64' : return 'func_linux_arm64' ;
18- case 'PPC64LE' : return 'func_linux_ppc64le' ;
19- case 'S390X' : return 'func_linux_s390x' ;
20- default : return 'unknown' ;
11+ const runnerOS = process . env . RUNNER_OS ;
12+ const runnerArch = process . env . RUNNER_ARCH ;
13+
14+ if ( runnerOS === 'Linux' ) {
15+ switch ( runnerArch ) {
16+ case 'X64' : return 'func_linux_amd64' ;
17+ case 'ARM64' : return 'func_linux_arm64' ;
18+ case 'PPC64LE' : return 'func_linux_ppc64le' ;
19+ case 'S390X' : return 'func_linux_s390x' ;
20+ default : return 'unknown' ;
21+ }
22+ } else if ( runnerOS === 'macOS' ) {
23+ return runnerArch === 'X64' ? 'func_darwin_amd64' : 'func_darwin_arm64' ;
24+ } else if ( runnerOS === 'Windows' ) {
25+ return 'func_windows_amd64.exe' ;
26+ } else {
27+ return 'unknown' ;
2128 }
22- } else if ( runnerOS === 'macOS' ) {
23- return runnerArch === 'X64' ? 'func_darwin_amd64' : 'func_darwin_arm64' ;
24- } else if ( runnerOS === 'Windows' ) {
25- return 'func_windows_amd64.exe' ;
26- } else {
27- return 'unknown' ;
28- }
2929}
3030
3131// Normalizes version to release tag format: knative-vX.Y.Z
3232// Ex.: '1.16' or 'v1.16' will return 'knative-v1.16.0'
3333function smartVersionUpdate ( version ) {
34- const versionRegex = / ^ (?< knprefix > k n a t i v e - ) ? (?< prefix > v ? ) (?< major > \d + ) \. (?< minor > \d + ) ( .(?< patch > \d + ) ) ? $ / ;
35- const match = version . match ( versionRegex ) ;
36- if ( ! match ) {
37- throw new Error ( `Invalid version format (${ version } ). Expected format: "1.16[.X]" or "v1.16[.X]"` ) ;
38- }
39- const knprefix = 'knative-' ;
40- const prefix = 'v' ;
41- const patch = match . groups . patch ?? 0 ;
42- return `${ knprefix } ${ prefix } ${ match . groups . major } .${ match . groups . minor } .${ patch } ` ;
34+ const versionRegex = / ^ (?< knprefix > k n a t i v e - ) ? (?< prefix > v ? ) (?< major > \d + ) \. (?< minor > \d + ) ( .(?< patch > \d + ) ) ? $ / ;
35+ const match = version . match ( versionRegex ) ;
36+ if ( ! match ) {
37+ throw new Error ( `Invalid version format (${ version } ). Expected format: "1.16[.X]" or "v1.16[.X]"` ) ;
38+ }
39+ const knprefix = 'knative-' ;
40+ const prefix = 'v' ;
41+ const patch = match . groups . patch ?? 0 ;
42+ return `${ knprefix } ${ prefix } ${ match . groups . major } .${ match . groups . minor } .${ patch } ` ;
4343}
4444
45- const DEFAULT_BINARY_SOURCE = 'https://github.com/knative/func/releases/download' ;
4645
4746// Downloads binary from release URL and makes it executable
48- async function downloadFuncBinary ( version , osBinName , binPath , binarySource ) {
49- const url = `${ binarySource } /${ version } /${ osBinName } ` ;
50- core . info ( `Downloading from: ${ url } ` ) ;
47+ async function downloadFuncBinary ( url , binPath ) {
48+ core . info ( `Downloading from: ${ url } ` ) ;
5149
52- await exec . exec ( 'curl' , [ '-L' , '--fail' , '-o' , binPath , url ] ) ;
50+ await exec . exec ( 'curl' , [ '-L' , '--fail' , '-o' , binPath , url ] ) ;
5351
54- if ( ! fs . existsSync ( binPath ) ) {
55- throw new Error ( "Download failed, couldn't find the binary on disk" ) ;
56- }
52+ if ( ! fs . existsSync ( binPath ) ) {
53+ throw new Error ( "Download failed, couldn't find the binary on disk" ) ;
54+ }
5755
58- if ( process . env . RUNNER_OS !== 'Windows' ) {
59- await exec . exec ( 'chmod' , [ '+x' , binPath ] ) ;
60- }
56+ if ( process . env . RUNNER_OS !== 'Windows' ) {
57+ await exec . exec ( 'chmod' , [ '+x' , binPath ] ) ;
58+ }
6159}
6260
6361// Adds binary directory to PATH for current and subsequent steps
6462async function addBinToPath ( binPath ) {
65- const dir = path . dirname ( binPath ) ;
66- fs . appendFileSync ( process . env . GITHUB_PATH , `\n${ dir } ` ) ;
63+ const dir = path . dirname ( binPath ) ;
64+ fs . appendFileSync ( process . env . GITHUB_PATH , `\n${ dir } ` ) ;
65+
66+ if ( ! process . env . PATH . includes ( dir ) ) {
67+ process . env . PATH = process . env . PATH + path . delimiter + dir ;
68+ core . info ( `${ dir } added to PATH` ) ;
69+ }
70+ }
6771
68- if ( ! process . env . PATH . includes ( dir ) ) {
69- process . env . PATH = process . env . PATH + path . delimiter + dir ;
70- core . info ( `${ dir } added to PATH` ) ;
71- }
72+ const DEFAULT_BINARY_SOURCE = 'https://github.com/knative/func/releases/download' ;
73+ const DEFAULT_LATEST_BINARY_SOURCE = 'https://github.com/knative/func/releases/latest/download' ;
74+
75+ // resolve url based on given input
76+ // version: can be 'latest' or specific version based on GitHub releases
77+ // bin: binary name - is passed in to form the full url
78+ function resolveUrl ( version , bin ) {
79+ let base ;
80+ let last ;
81+ if ( version === "latest" ) {
82+ base = DEFAULT_LATEST_BINARY_SOURCE ;
83+ last = bin
84+ } else {
85+ base = DEFAULT_BINARY_SOURCE ;
86+ last = `${ version } /${ bin } `
87+ }
88+ return `${ base } /${ last } `
7289}
7390
7491async function run ( ) {
75- const osBinName = core . getInput ( 'binary' ) || getOsBinName ( ) ;
76- if ( osBinName === "unknown" ) {
77- core . setFailed ( "Invalid os binary determination, try setting it specifically using 'binary'" ) ;
78- return ;
79- }
80-
81- const versionInput = core . getInput ( 'version' ) || DEFAULT_FUNC_VERSION ;
82- const destination = core . getInput ( 'destination' ) || process . cwd ( ) ;
83- const binarySource = core . getInput ( 'binarySource' ) || DEFAULT_BINARY_SOURCE ;
84- let bin = core . getInput ( 'name' ) || 'func' ;
85- if ( process . env . RUNNER_OS === 'Windows' && ! bin . endsWith ( '.exe' ) ) {
86- bin += '.exe' ;
87- }
88-
89- let version ;
90- try {
91- version = smartVersionUpdate ( versionInput ) ;
92- } catch ( error ) {
93- core . setFailed ( error . message ) ;
94- return ;
95- }
96-
97- if ( ! fs . existsSync ( destination ) ) {
98- fs . mkdirSync ( destination , { recursive : true } ) ;
99- }
100-
101- const fullPathBin = path . resolve ( destination , bin ) ;
102-
103- try {
104- await downloadFuncBinary ( version , osBinName , fullPathBin , binarySource ) ;
105- } catch ( error ) {
106- core . setFailed ( `Download failed: ${ error . message } ` ) ;
107- return ;
108- }
109-
110- await addBinToPath ( fullPathBin ) ;
111- await exec . exec ( fullPathBin , [ 'version' ] ) ;
92+ const osBinName = core . getInput ( 'binary' ) || getOsBinName ( ) ;
93+ if ( osBinName === "unknown" ) {
94+ core . setFailed ( "Invalid os binary determination, try setting it specifically using 'binary'" ) ;
95+ return ;
96+ }
97+
98+ const versionInput = core . getInput ( 'version' ) || DEFAULT_FUNC_VERSION ;
99+ const destination = core . getInput ( 'destination' ) || process . cwd ( ) ;
100+ const binarySourceInput = core . getInput ( 'binarySource' ) ;
101+ let bin = core . getInput ( 'name' ) || 'func' ;
102+ if ( process . env . RUNNER_OS === 'Windows' && ! bin . endsWith ( '.exe' ) ) {
103+ bin += '.exe' ;
104+ }
105+
106+ let url ;
107+ if ( binarySourceInput ) {
108+ core . info ( `Using custom binary source: ${ binarySourceInput } ` ) ;
109+ url = binarySourceInput ;
110+ } else if ( versionInput . toLowerCase ( ) . trim ( ) == 'latest' ) {
111+ // use latest version
112+ core . info ( "Using latest version..." ) ;
113+ url = resolveUrl ( 'latest' , osBinName ) ;
114+ } else {
115+ // try smart version update
116+ try {
117+ const version = smartVersionUpdate ( versionInput ) ;
118+ url = resolveUrl ( version , osBinName )
119+ } catch ( error ) {
120+ core . setFailed ( error . message ) ;
121+ return ;
122+ }
123+ }
124+
125+ if ( ! fs . existsSync ( destination ) ) {
126+ fs . mkdirSync ( destination , { recursive : true } ) ;
127+ }
128+
129+ const fullPathBin = path . resolve ( destination , bin ) ;
130+ try {
131+ await downloadFuncBinary ( url , fullPathBin ) ;
132+ } catch ( error ) {
133+ core . setFailed ( `Download failed: ${ error . message } ` ) ;
134+ return ;
135+ }
136+
137+ await addBinToPath ( fullPathBin ) ;
138+ await exec . exec ( fullPathBin , [ 'version' ] ) ;
112139}
113140
114- run ( ) ;
141+ run ( ) ;
0 commit comments