Skip to content

Commit 776a279

Browse files
committed
support latest version
1 parent 675fe07 commit 776a279

4 files changed

Lines changed: 103 additions & 88 deletions

File tree

.github/workflows/test-action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: test-action
22
on: [pull_request, workflow_dispatch]
33

44
jobs:
5-
test-default:
5+
test-default-latest:
66
strategy:
77
matrix:
88
os: [ubuntu-latest,windows-latest,macos-latest]

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@ GitHub Action to download and setup the func CLI. Automatically detects OS and a
77
```yaml
88
- uses: functions-dev/action@main
99
with:
10-
version: 'v1.20.0' # optional
11-
name: 'func' # optional
10+
version: 'v1.20.0' # optional - uses latest as default
1211
```
1312
1413
## Inputs
1514
1615
| Input | Description | Default |
1716
|-------|-------------|---------|
18-
| `version` | Version to download (e.g. `v1.20.0`) | recent stable |
17+
| `version` | Version to download (e.g. `v1.20.0`) | latest |
1918
| `name` | Binary name | `func` |
2019
| `binary` | Specific binary to download | auto-detected |
2120
| `destination` | Download directory | cwd |
21+
| `binarySource` | Base URL for downloading binaries | Github release |

action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ inputs:
66
binary:
77
description: '(optional) Binary you want to download (exact string expected), otherwise will be determined via the OS of GH Runner'
88
version:
9-
description: '(optional) Provide version to download. Any version in release pages works https://github.com/knative/func/tags'
9+
description: '(optional) Version to download. Use "latest" or specify a version from release pages https://github.com/knative/func/tags'
1010
destination:
11-
description: '(optional) Provide a path where to move the desired downloaded binary, otherwise cwd is used'
11+
description: '(optional) Path where to move the desired downloaded binary, otherwise cwd is used'
1212
binarySource:
1313
description: '(optional) Base URL for downloading binaries. Defaults to GitHub releases. Pattern: <url-base>/<version>/<os-bin-name>'
1414
runs:

index.js

Lines changed: 97 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -3,112 +3,127 @@ const exec = require('@actions/exec');
33
const path = require('path');
44
const 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
1010
function 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'
3333
function smartVersionUpdate(version) {
34-
const versionRegex = /^(?<knprefix>knative-)?(?<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>knative-)?(?<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

4545
const DEFAULT_BINARY_SOURCE = 'https://github.com/knative/func/releases/download';
46+
const DEFAULT_LATEST_BINARY_SOURCE = 'https://github.com/knative/func/releases/latest/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
6464
async 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+
}
7272
}
7373

7474
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';
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']);
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 binarySourceInput = core.getInput('binarySource');
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+
let binarySource;
91+
92+
// resolve version 'latest'
93+
if (versionInput.toLowerCase().trim() == 'latest') {
94+
core.info("Using latest version...");
95+
binarySource = binarySourceInput || DEFAULT_LATEST_BINARY_SOURCE;
96+
} else {
97+
// try smart version update
98+
try {
99+
binarySource = binarySourceInput || DEFAULT_BINARY_SOURCE;
100+
version = smartVersionUpdate(versionInput);
101+
} catch (error) {
102+
core.setFailed(error.message);
103+
return;
104+
}
105+
}
106+
107+
if (!fs.existsSync(destination)) {
108+
fs.mkdirSync(destination, { recursive: true });
109+
}
110+
111+
const fullPathBin = path.resolve(destination, bin);
112+
113+
// resolve url based on <specific/latest> version
114+
const url = version
115+
? `${binarySource}/${version}/${osBinName}`
116+
: `${binarySource}/${osBinName}`
117+
118+
try {
119+
await downloadFuncBinary(url, fullPathBin);
120+
} catch (error) {
121+
core.setFailed(`Download failed: ${error.message}`);
122+
return;
123+
}
124+
125+
await addBinToPath(fullPathBin);
126+
await exec.exec(fullPathBin, ['version']);
112127
}
113128

114-
run();
129+
run();

0 commit comments

Comments
 (0)