11const core = require ( '@actions/core' ) ;
2- const exec = require ( '@actions/exec' )
3- const path = require ( 'path' )
2+ const exec = require ( '@actions/exec' ) ;
3+ const 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' ;
68
7- // change this accordingly
8- const DEFAULT_FUNC_VERSION = 'knative-v1.16.1'
9-
10- // detect os system in Github Actions and determine binary name
9+ // Returns the binary name for the current OS/arch from GitHub releases
1110function getOsBinName ( ) {
1211 const runnerOS = process . env . RUNNER_OS ;
1312 const runnerArch = process . env . RUNNER_ARCH ;
@@ -23,106 +22,93 @@ function getOsBinName() {
2322 } else if ( runnerOS === 'macOS' ) {
2423 return runnerArch === 'X64' ? 'func_darwin_amd64' : 'func_darwin_arm64' ;
2524 } else if ( runnerOS === 'Windows' ) {
26- return 'func_windows_amd64' ;
25+ return 'func_windows_amd64.exe ' ;
2726 } else {
2827 return 'unknown' ;
2928 }
3029}
3130
32- // smartVersionParse will check validity of given version and fill in the parts
33- // to make it correct if possible.
34- // Ex.: '1.16' or 'v1.16' will return 'v1.16.0'
35- function smartVersionUpdate ( version ) {
36- versionRegex = / ^ (?< knprefix > k n a t i v e - ) ? (?< prefix > v ? ) (?< major > \d + ) \. (?< minor > \d + ) ( .(?< patch > \d + ) ) ? $ / ;
37- let match = version . match ( versionRegex ) ;
38- if ( match ) {
39- if ( match . groups . knprefix == undefined ) {
40- match . groups . knprefix = "" ;
41- }
42- const prefix = 'v' ;
43- if ( match . groups . patch == undefined ) {
44- match . groups . patch = 0 ;
45- }
46- return `${ match . groups . knprefix } ${ prefix } ${ match . groups . major } .${ match . groups . minor } .${ match . groups . patch } ` ;
47- }
48-
49- core . setFailed ( `Invalid version format (${ version } ). Expected format: "1.16[.X]" or "v1.16[.X]"` ) ;
50- return undefined ;
31+ // Normalizes version to release tag format: knative-vX.Y.Z
32+ // Ex.: '1.16' or 'v1.16' will return 'knative-v1.16.0'
33+ function 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 } ` ;
5143}
5244
53- /**
54- * @param {string } url - Full url to be curled
55- * @param {string } binPath - Full target path of the binary
56- */
57- // download func, set as executable
58- async function cmdConstructAndRun ( url , binPath ) {
59- const cmd = `curl -L -o "${ binPath } " "${ url } "` ;
60- await exec . exec ( cmd ) ;
61-
62- //check if downloaded successfully
63- if ( ! fs . existsSync ( binPath ) ) {
64- core . setFailed ( "Download failed, couldn't find the binary on disk" ) ;
45+ const DEFAULT_BINARY_SOURCE = 'https://github.com/knative/func/releases/download' ;
46+
47+ // 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 } ` ) ;
51+
52+ await exec . exec ( 'curl' , [ '-L' , '--fail' , '-o' , binPath , url ] ) ;
53+
54+ if ( ! fs . existsSync ( binPath ) ) {
55+ throw new Error ( "Download failed, couldn't find the binary on disk" ) ;
6556 }
6657
67- await exec . exec ( `chmod +x ${ binPath } ` ) ;
58+ if ( process . env . RUNNER_OS !== 'Windows' ) {
59+ await exec . exec ( 'chmod' , [ '+x' , binPath ] ) ;
60+ }
6861}
6962
70- /**
71- * @param {string } binPath - full path to Func binary
72- * */
73- async function addBinToPath ( binPath ) {
74- dir = path . dirname ( binPath )
75- // Write to $GITHUB_PATH, making it available for subsequent steps
63+ // Adds binary directory to PATH for current and subsequent steps
64+ async function addBinToPath ( binPath ) {
65+ const dir = path . dirname ( binPath ) ;
7666 fs . appendFileSync ( process . env . GITHUB_PATH , `\n${ dir } ` ) ;
7767
78- // add only if its not in PATH yet
79- if ( ! process . env . PATH . includes ( dir ) ) {
68+ if ( ! process . env . PATH . includes ( dir ) ) {
8069 process . env . PATH = process . env . PATH + path . delimiter + dir ;
81- core . info ( `dir ${ dir } added to $PATH` ) ;
70+ core . info ( `${ dir } added to PATH` ) ;
71+ }
72+ }
73+
74+ async 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' ;
8287 }
83- }
8488
85- // -------------------------------------------------------------------------- \\
86- async function run ( ) {
89+ let version ;
8790 try {
91+ version = smartVersionUpdate ( versionInput ) ;
92+ } catch ( error ) {
93+ core . setFailed ( error . message ) ;
94+ return ;
95+ }
8896
89- // Fetch value of inputs specified in action.yml or use defaults
97+ if ( ! fs . existsSync ( destination ) ) {
98+ fs . mkdirSync ( destination , { recursive : true } ) ;
99+ }
90100
91- // osBin refers to the exact name match of an existing binary available to
92- // download
93- const osBin = core . getInput ( 'binary' ) || getOsBinName ( ) ;
94- if ( osBin == "unknown" ) {
95- core . setFailed ( "Invalid os binary determination, try setting it specifically using 'binary'" ) ;
96- }
97- // version to be downloaded
98- let version = core . getInput ( 'version' ) || DEFAULT_FUNC_VERSION
99- // destination is a directory where to download the Func
100- const destination = core . getInput ( 'destination' ) || process . cwd ( ) ;
101- // bin refers to the name of the binary (Func) that will be downloaded (this
102- // is what it will be called)
103- const bin = core . getInput ( 'name' ) || 'func' ;
104-
105- version = smartVersionUpdate ( version ) ;
106-
107- var url = `https://github.com/knative/func/releases/download/${ version } /${ osBin } ` ;
108- console . log ( `URL: ${ url } ` ) ;
109-
110- fullPathBin = path . resolve ( destination , bin ) ;
111-
112- // download Func
113- await cmdConstructAndRun ( url , fullPathBin ) ;
114-
115- // add final binary to PATH (directory where the bin is ) and add it to
116- // GITHUB_PATH so it can be used bo subsequent 'runs'
117- await addBinToPath ( fullPathBin ) ;
118-
119- await exec . exec ( "ls -la" )
120- // run 'func version' as a test
121- await exec . exec ( `${ bin } version` ) ;
101+ const fullPathBin = path . resolve ( destination , bin ) ;
122102
103+ try {
104+ await downloadFuncBinary ( version , osBinName , fullPathBin , binarySource ) ;
123105 } catch ( error ) {
124- core . setFailed ( error . message ) ;
106+ core . setFailed ( `Download failed: ${ error . message } ` ) ;
107+ return ;
125108 }
109+
110+ await addBinToPath ( fullPathBin ) ;
111+ await exec . exec ( fullPathBin , [ 'version' ] ) ;
126112}
127113
128114run ( ) ;
0 commit comments