Skip to content

Commit 54b8989

Browse files
committed
warning on old version
1 parent 7660a62 commit 54b8989

2 files changed

Lines changed: 95 additions & 35 deletions

File tree

.github/workflows/test-action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
test-custom-version:
1717
runs-on: ubuntu-latest
1818
env:
19-
TEST_VERSION: '1.19.0'
19+
TEST_VERSION: '1.18.0'
2020
VERSION_OFFSET: 27 # internal version = minor + offset (v1.19 → v0.46)
2121
steps:
2222
- uses: actions/checkout@v4

index.js

Lines changed: 94 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,6 @@ function getOsBinName() {
3535
}
3636
}
3737

38-
function resolveFullPathBin() {
39-
const destination = core.getInput('destination') || process.cwd();
40-
let bin = core.getInput('name') || 'func';
41-
if (process.env.RUNNER_OS === 'Windows' && !bin.endsWith('.exe')) {
42-
bin += '.exe';
43-
}
44-
if (!fs.existsSync(destination)) {
45-
fs.mkdirSync(destination, { recursive: true });
46-
}
47-
return path.resolve(destination, bin);
48-
}
49-
5038
// Normalizes version to release tag format: knative-vX.Y.Z
5139
// Ex.: '1.16' or 'v1.16' will return 'knative-v1.16.0'
5240
function smartVersionUpdate(version) {
@@ -61,6 +49,37 @@ function smartVersionUpdate(version) {
6149
return `${knprefix}${prefix}${match.groups.major}.${match.groups.minor}.${patch}`;
6250
}
6351

52+
function resolveVersion() {
53+
if (core.getInput('binarySource') !== "") return null;
54+
const versionInput = core.getInput('version') || DEFAULT_FUNC_VERSION;
55+
if (versionInput.toLowerCase().trim() === DEFAULT_FUNC_VERSION) return null;
56+
return smartVersionUpdate(versionInput);
57+
}
58+
59+
// Resolve download url based on given input
60+
// binName: name of func binary when it is to be constructed for full URL
61+
// (when not using binarySource)
62+
function resolveDownloadUrl(version, binName) {
63+
const binarySource = core.getInput('binarySource');
64+
if (binarySource !== "") {
65+
core.info(`Using custom binary source: ${binarySource}`);
66+
return binarySource;
67+
}
68+
69+
if (!version) {
70+
core.info("Using latest version...");
71+
return buildUrlString(DEFAULT_FUNC_VERSION);
72+
}
73+
core.info(`Using specific version ${version}`);
74+
return buildUrlString(version);
75+
76+
function buildUrlString(version) {
77+
return version === DEFAULT_FUNC_VERSION
78+
? `${DEFAULT_LATEST_BINARY_SOURCE}/${binName}`
79+
: `${DEFAULT_BINARY_SOURCE}/${version}/${binName}`;
80+
}
81+
}
82+
6483
// Downloads binary from release URL and makes it executable
6584
async function downloadFuncBinary(url, binPath) {
6685
core.info(`Downloading from: ${url}`);
@@ -76,6 +95,18 @@ async function downloadFuncBinary(url, binPath) {
7695
}
7796
}
7897

98+
function resolveFullPathBin() {
99+
const destination = core.getInput('destination') || process.cwd();
100+
let bin = core.getInput('name') || 'func';
101+
if (process.env.RUNNER_OS === 'Windows' && !bin.endsWith('.exe')) {
102+
bin += '.exe';
103+
}
104+
if (!fs.existsSync(destination)) {
105+
fs.mkdirSync(destination, { recursive: true });
106+
}
107+
return path.resolve(destination, bin);
108+
}
109+
79110
// Adds binary directory to PATH for current and subsequent steps
80111
function addBinToPath(binPath) {
81112
const dir = path.dirname(binPath);
@@ -87,29 +118,45 @@ function addBinToPath(binPath) {
87118
}
88119
}
89120

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-
}
121+
// Returns difference of minor versions between 'latest' and 'version'
122+
// subtracts 'version' from 'latest' (returns negative if 'version' is ahead)
123+
// If minor version cannot be extracted on either number - return 0
124+
function versionDiff(latest, version) {
125+
const extractMinor = (v) => {
126+
const match = v.match(/(\d+)\.(\d+)/);
127+
return match ? parseInt(match[2], 10) : null;
128+
};
129+
130+
const latestMinor = extractMinor(latest);
131+
const versionMinor = extractMinor(version);
132+
if (latestMinor === null || versionMinor === null) {
133+
return 0;
134+
}
135+
return latestMinor - versionMinor;
136+
}
99137

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);
138+
// Warn if version requested is more than 2 versions behind latest (>= 3)
139+
// This function does NOT error
140+
async function warnStaleVersion(version) {
141+
const API_LATEST = 'https://api.github.com/repos/knative/func/releases/latest';
142+
const THRESHOLD = 3;
108143

109-
function buildUrlString(version) {
110-
return version === DEFAULT_FUNC_VERSION
111-
? `${DEFAULT_LATEST_BINARY_SOURCE}/${binName}`
112-
: `${DEFAULT_BINARY_SOURCE}/${version}/${binName}`;
144+
try {
145+
const response = await fetch(API_LATEST);
146+
if (!response.ok) {
147+
throw new Error(`failed to fetch latest version: ${response.status}`);
148+
}
149+
150+
const data = await response.json();
151+
const latest = data.tag_name;
152+
const diff = versionDiff(latest, version);
153+
if (diff >= THRESHOLD) {
154+
core.warning(
155+
`You are using func ${version}, which is ${diff} versions behind the latest (${latest}). Upgrading is recommended.`
156+
);
157+
}
158+
} catch (error) {
159+
core.debug(`Skipping stale version check: ${error.message}`);
113160
}
114161
}
115162

@@ -122,9 +169,17 @@ async function run() {
122169
return;
123170
}
124171

172+
let version;
173+
try {
174+
version = resolveVersion();
175+
} catch (error) {
176+
core.setFailed(error.message);
177+
return;
178+
}
179+
125180
let url;
126181
try {
127-
url = resolveDownloadUrl(osBinName);
182+
url = resolveDownloadUrl(version, osBinName);
128183
} catch (error) {
129184
core.setFailed(`Failed to resolve url: ${error.message}`);
130185
return;
@@ -152,6 +207,11 @@ async function run() {
152207
return;
153208
}
154209

210+
// Warn if using an old version (only for specific versions, not binarySource or latest)
211+
if (version) {
212+
await warnStaleVersion(version);
213+
}
214+
155215
try {
156216
await exec.exec(fullPathBin, ['version']);
157217
} catch (error) {

0 commit comments

Comments
 (0)