@@ -3,112 +3,135 @@ 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' ;
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' ;
810
911// Returns the binary name for the current OS/arch from GitHub releases
1012function 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' ;
13+ const runnerOS = process . env . RUNNER_OS ;
14+ const runnerArch = process . env . RUNNER_ARCH ;
15+
16+ if ( runnerOS === 'Linux' ) {
17+ switch ( runnerArch ) {
18+ case 'X64' : return 'func_linux_amd64' ;
19+ case 'ARM64' : return 'func_linux_arm64' ;
20+ case 'PPC64LE' : return 'func_linux_ppc64le' ;
21+ case 'S390X' : return 'func_linux_s390x' ;
22+ default : return 'unknown' ;
23+ }
24+ } else if ( runnerOS === 'macOS' ) {
25+ return runnerArch === 'X64' ? 'func_darwin_amd64' : 'func_darwin_arm64' ;
26+ } else if ( runnerOS === 'Windows' ) {
27+ return 'func_windows_amd64.exe' ;
28+ } else {
29+ return 'unknown' ;
2130 }
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- }
2931}
3032
3133// Normalizes version to release tag format: knative-vX.Y.Z
3234// Ex.: '1.16' or 'v1.16' will return 'knative-v1.16.0'
3335function 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 } ` ;
36+ const versionRegex = / ^ (?< knprefix > k n a t i v e - ) ? (?< prefix > v ? ) (?< major > \d + ) \. (?< minor > \d + ) ( \ .(?< patch > \d + ) ) ? $ / ;
37+ const match = version . match ( versionRegex ) ;
38+ if ( ! match ) {
39+ throw new Error ( `Invalid version format (${ version } ). Expected format: "1.16[.X]" or "v1.16[.X]"` ) ;
40+ }
41+ const knprefix = 'knative-' ;
42+ const prefix = 'v' ;
43+ const patch = match . groups . patch ?? 0 ;
44+ return `${ knprefix } ${ prefix } ${ match . groups . major } .${ match . groups . minor } .${ patch } ` ;
4345}
4446
45- const DEFAULT_BINARY_SOURCE = 'https://github.com/knative/func/releases/download' ;
4647
4748// 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 } ` ) ;
49+ async function downloadFuncBinary ( url , binPath ) {
50+ core . info ( `Downloading from: ${ url } ` ) ;
5151
52- await exec . exec ( 'curl' , [ '-L' , '--fail' , '-o' , binPath , url ] ) ;
52+ await exec . exec ( 'curl' , [ '-L' , '--fail' , '-o' , binPath , url ] ) ;
5353
54- if ( ! fs . existsSync ( binPath ) ) {
55- throw new Error ( "Download failed, couldn't find the binary on disk" ) ;
56- }
54+ if ( ! fs . existsSync ( binPath ) ) {
55+ throw new Error ( "Download failed, couldn't find the binary on disk" ) ;
56+ }
5757
58- if ( process . env . RUNNER_OS !== 'Windows' ) {
59- await exec . exec ( 'chmod' , [ '+x' , binPath ] ) ;
60- }
58+ if ( process . env . RUNNER_OS !== 'Windows' ) {
59+ await exec . exec ( 'chmod' , [ '+x' , binPath ] ) ;
60+ }
6161}
6262
6363// Adds binary directory to PATH for current and subsequent steps
6464async function addBinToPath ( binPath ) {
65- const dir = path . dirname ( binPath ) ;
66- fs . appendFileSync ( process . env . GITHUB_PATH , `\n${ dir } ` ) ;
65+ const dir = path . dirname ( binPath ) ;
66+ fs . appendFileSync ( process . env . GITHUB_PATH , `\n${ dir } ` ) ;
6767
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- }
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+ }
73+
74+ // Resolve download url based on given input
75+ // binName: name of func binary when it is to be constructed for full URL
76+ // (when not using binarySource)
77+ function resolveDownloadUrl ( binName ) {
78+ const binarySource = core . getInput ( 'binarySource' ) ;
79+ if ( binarySource !== "" ) {
80+ core . info ( `Using custom binary source: ${ binarySource } ` ) ;
81+ return binarySource ;
82+ }
83+
84+ const versionInput = core . getInput ( 'version' ) || DEFAULT_FUNC_VERSION ;
85+ if ( versionInput . toLowerCase ( ) . trim ( ) === DEFAULT_FUNC_VERSION ) {
86+ core . info ( "Using latest version..." ) ;
87+ return buildUrlString ( DEFAULT_FUNC_VERSION ) ;
88+ }
89+ const version = smartVersionUpdate ( versionInput ) ;
90+ core . info ( `Using specific version ${ version } ` ) ;
91+ return buildUrlString ( version ) ;
92+
93+ function buildUrlString ( version ) {
94+ return version === DEFAULT_FUNC_VERSION
95+ ? `${ DEFAULT_LATEST_BINARY_SOURCE } /${ binName } `
96+ : `${ DEFAULT_BINARY_SOURCE } /${ version } /${ binName } ` ;
97+ }
7298}
7399
74100async 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' ] ) ;
101+ const osBinName = core . getInput ( 'binary' ) || getOsBinName ( ) ;
102+ if ( osBinName === "unknown" ) {
103+ core . setFailed ( "Invalid os binary determination, try setting it specifically using 'binary'" ) ;
104+ return ;
105+ }
106+
107+ const destination = core . getInput ( 'destination' ) || process . cwd ( ) ;
108+ let bin = core . getInput ( 'name' ) || 'func' ;
109+ if ( process . env . RUNNER_OS === 'Windows' && ! bin . endsWith ( '.exe' ) ) {
110+ bin += '.exe' ;
111+ }
112+
113+ let url ;
114+ try {
115+ url = resolveDownloadUrl ( osBinName ) ;
116+ } catch ( error ) {
117+ core . setFailed ( `Failed to resolve url: ${ error . message } ` ) ;
118+ return ;
119+ }
120+
121+ if ( ! fs . existsSync ( destination ) ) {
122+ fs . mkdirSync ( destination , { recursive : true } ) ;
123+ }
124+
125+ const fullPathBin = path . resolve ( destination , bin ) ;
126+ try {
127+ await downloadFuncBinary ( url , fullPathBin ) ;
128+ } catch ( error ) {
129+ core . setFailed ( `Download failed: ${ error . message } ` ) ;
130+ return ;
131+ }
132+
133+ await addBinToPath ( fullPathBin ) ;
134+ await exec . exec ( fullPathBin , [ 'version' ] ) ;
112135}
113136
114- run ( ) ;
137+ run ( ) ;
0 commit comments