actions-up 1.14.1 ā 1.14.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/index.js +169 -164
- package/dist/cli/parse-arguments.d.ts +74 -0
- package/dist/cli/parse-arguments.js +76 -0
- package/dist/core/api/check-updates.js +114 -113
- package/dist/core/ast/update/apply-updates.js +3 -3
- package/dist/core/updates/resolve-target-reference.js +26 -15
- package/dist/core/versions/find-compatible-tag.js +6 -6
- package/dist/core/versions/preserve-tag-format.d.ts +17 -0
- package/dist/core/versions/preserve-tag-format.js +11 -0
- package/dist/package.js +1 -1
- package/package.json +4 -5
- package/readme.md +8 -6
package/dist/cli/index.js
CHANGED
|
@@ -17,192 +17,197 @@ import { mergeScanResults as h } from "./merge-scan-results.js";
|
|
|
17
17
|
import { printModeWarning as g } from "./print-mode-warning.js";
|
|
18
18
|
import { scanRecursive as _ } from "../core/scan-recursive.js";
|
|
19
19
|
import { buildJsonReport as v } from "./build-json-report.js";
|
|
20
|
-
import {
|
|
20
|
+
import { parseArguments as y } from "./parse-arguments.js";
|
|
21
|
+
import { scanGitHubActions as b } from "../core/scan-github-actions.js";
|
|
21
22
|
import "../core/index.js";
|
|
22
|
-
import { version as
|
|
23
|
-
import { createSpinner as
|
|
24
|
-
import { resolve as
|
|
23
|
+
import { version as x } from "../package.js";
|
|
24
|
+
import { createSpinner as S } from "nanospinner";
|
|
25
|
+
import { resolve as C } from "node:path";
|
|
25
26
|
import "node:worker_threads";
|
|
26
|
-
import
|
|
27
|
-
import w from "cac";
|
|
27
|
+
import w from "picocolors";
|
|
28
28
|
function T() {
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
29
|
+
let e = y(process.argv.slice(2), x);
|
|
30
|
+
if (e.kind === "help" || e.kind === "version") {
|
|
31
|
+
console.info(e.text);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
e.kind === "error" && (console.error(w.redBright("\nError:"), e.message), process.exit(1)), E(e.options);
|
|
35
|
+
}
|
|
36
|
+
async function E(y) {
|
|
37
|
+
let x = y.json ?? !1, T = null, E = o({
|
|
38
|
+
recursive: y.recursive,
|
|
39
|
+
cwd: process.cwd(),
|
|
40
|
+
dir: y.dir
|
|
41
|
+
}), D = E.map(({ root: e, dir: t }) => C(e, t)), O = y.includeBranches ?? !1, k = d(y.mode), A = l(y.style), j = [];
|
|
42
|
+
Array.isArray(y.exclude) ? j.push(...y.exclude) : typeof y.exclude == "string" && j.push(y.exclude);
|
|
43
|
+
let M = j.flatMap((e) => e.split(",")).map((e) => e.trim()).filter(Boolean);
|
|
44
|
+
try {
|
|
45
|
+
f({
|
|
46
|
+
yes: y.yes,
|
|
47
|
+
json: x
|
|
48
|
+
}), x || (console.info(w.cyan("\nš Actions Up!\n")), T = S("Scanning GitHub Actions...").start());
|
|
49
|
+
function o({ actionsToCheckCount: e, blockedByMode: t = [], outdated: n = [], skipped: r = [], scanResult: i, status: a }) {
|
|
50
|
+
process.stdout.write(`${JSON.stringify(v({
|
|
51
|
+
recursive: y.recursive ?? !1,
|
|
52
|
+
excludePatterns: M,
|
|
53
|
+
directories: D,
|
|
54
|
+
minAge: y.minAge,
|
|
55
|
+
actionsToCheckCount: e,
|
|
56
|
+
includeBranches: O,
|
|
57
|
+
blockedByMode: t,
|
|
58
|
+
scanResult: i,
|
|
59
|
+
outdated: n,
|
|
60
|
+
skipped: r,
|
|
61
|
+
status: a,
|
|
62
|
+
style: A,
|
|
63
|
+
mode: k
|
|
64
|
+
}), null, 2)}\n`);
|
|
65
|
+
}
|
|
66
|
+
let l = h(y.recursive ? await Promise.all(E.map(({ root: e, dir: t }) => _(e, t))) : await Promise.all(E.map(({ root: e, dir: t }) => b(e, t)))), d = l.actions.length, C = l.workflows.size, j = l.compositeActions.size;
|
|
67
|
+
if (T?.success(`Found ${w.yellow(d)} actions in ${w.yellow(C)} workflows and ${w.yellow(j)} composite actions`), d === 0) {
|
|
68
|
+
if (x) {
|
|
69
|
+
o({
|
|
70
|
+
status: "no-actions-found",
|
|
71
|
+
actionsToCheckCount: 0,
|
|
72
|
+
scanResult: l
|
|
73
|
+
});
|
|
71
74
|
return;
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
76
|
+
console.info(w.green("\n⨠No GitHub Actions found in this repository"));
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
let N = l.actions;
|
|
80
|
+
if (M.length > 0) {
|
|
81
|
+
let { parseExcludePatterns: e } = await import("../core/filters/parse-exclude-patterns.js"), t = e(M);
|
|
82
|
+
t.length > 0 && (N = N.filter((e) => {
|
|
83
|
+
let { name: n } = e;
|
|
84
|
+
for (let e of t) if (e.test(n)) return !1;
|
|
85
|
+
return !0;
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
if (x || (T = S("Checking for updates...").start()), N.length === 0) {
|
|
89
|
+
if (T?.success("No actions to check after excludes"), x) {
|
|
90
|
+
o({
|
|
91
|
+
status: "nothing-to-check",
|
|
92
|
+
actionsToCheckCount: 0,
|
|
93
|
+
scanResult: l
|
|
94
|
+
});
|
|
92
95
|
return;
|
|
93
96
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
let
|
|
113
|
-
|
|
114
|
-
effectiveCurrentVersion: r,
|
|
115
|
-
allowed: k === "minor" ? i === "minor" || i === "patch" || i === "none" : i === "patch" || i === "none",
|
|
116
|
-
update: n
|
|
117
|
-
};
|
|
118
|
-
})), c = [], l = await Promise.all(o.map(async (e) => {
|
|
119
|
-
if (e.allowed) return { update: e.update };
|
|
120
|
-
let t = await i(F, {
|
|
121
|
-
currentVersion: e.effectiveCurrentVersion,
|
|
122
|
-
actionName: e.update.action.name,
|
|
123
|
-
tagsCache: n,
|
|
124
|
-
shaCache: r,
|
|
125
|
-
mode: k
|
|
126
|
-
});
|
|
127
|
-
return t ? { update: {
|
|
128
|
-
...e.update,
|
|
129
|
-
latestVersion: t.version,
|
|
130
|
-
latestSha: t.sha,
|
|
131
|
-
isBreaking: !1,
|
|
132
|
-
hasUpdate: !0
|
|
133
|
-
} } : { blocked: e.update };
|
|
134
|
-
}));
|
|
135
|
-
for (let e of l) {
|
|
136
|
-
if (e.update) {
|
|
137
|
-
c.push(e.update);
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
H.push(e.blocked);
|
|
97
|
+
console.info(w.green("\n⨠Nothing to check after excludes\n"));
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
let P = process.env.GITHUB_TOKEN, F = a(P), I = await m(N, P, {
|
|
101
|
+
client: F,
|
|
102
|
+
includeBranches: O,
|
|
103
|
+
style: A
|
|
104
|
+
}), L = [];
|
|
105
|
+
await Promise.all(I.map(async (e) => {
|
|
106
|
+
await p(e.action.file, e.action.line) || L.push(e);
|
|
107
|
+
}));
|
|
108
|
+
let R = L.filter((e) => e.status === "skipped"), z = L.filter((e) => e.hasUpdate), B = y.minAge * 24 * 60 * 60 * 1e3, V = Date.now();
|
|
109
|
+
z = z.filter((e) => e.publishedAt ? V - e.publishedAt.getTime() >= B : !0);
|
|
110
|
+
let H = [];
|
|
111
|
+
if (k !== "major") {
|
|
112
|
+
let n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map(), a = /* @__PURE__ */ new Map(), o = await Promise.all(z.map(async (n) => {
|
|
113
|
+
let r = n.currentVersion;
|
|
114
|
+
if (t(n.currentVersion)) {
|
|
115
|
+
let t = await e(n.action.file, n.action.line, a);
|
|
116
|
+
t && (r = t);
|
|
141
117
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
118
|
+
let i = s(r, n.latestVersion);
|
|
119
|
+
return {
|
|
120
|
+
effectiveCurrentVersion: r,
|
|
121
|
+
allowed: k === "minor" ? i === "minor" || i === "patch" || i === "none" : i === "patch" || i === "none",
|
|
122
|
+
update: n
|
|
123
|
+
};
|
|
124
|
+
})), c = [], l = await Promise.all(o.map(async (e) => {
|
|
125
|
+
if (e.allowed) return { update: e.update };
|
|
126
|
+
let t = await i(F, {
|
|
127
|
+
currentVersion: e.effectiveCurrentVersion,
|
|
128
|
+
actionName: e.update.action.name,
|
|
129
|
+
tagsCache: n,
|
|
130
|
+
shaCache: r,
|
|
131
|
+
mode: k
|
|
132
|
+
});
|
|
133
|
+
return t ? { update: {
|
|
134
|
+
...e.update,
|
|
135
|
+
latestVersion: t.version,
|
|
136
|
+
latestSha: t.sha,
|
|
137
|
+
isBreaking: !1,
|
|
138
|
+
hasUpdate: !0
|
|
139
|
+
} } : { blocked: e.update };
|
|
150
140
|
}));
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
o({
|
|
156
|
-
actionsToCheckCount: N.length,
|
|
157
|
-
status: "up-to-date",
|
|
158
|
-
blockedByMode: H,
|
|
159
|
-
scanResult: l,
|
|
160
|
-
skipped: R
|
|
161
|
-
});
|
|
162
|
-
return;
|
|
141
|
+
for (let e of l) {
|
|
142
|
+
if (e.update) {
|
|
143
|
+
c.push(e.update);
|
|
144
|
+
continue;
|
|
163
145
|
}
|
|
164
|
-
|
|
165
|
-
return;
|
|
146
|
+
H.push(e.blocked);
|
|
166
147
|
}
|
|
167
|
-
|
|
148
|
+
z = c;
|
|
149
|
+
}
|
|
150
|
+
z = z.map((e) => r(e, A));
|
|
151
|
+
let U = z.filter((e) => !e.targetRef).map((e) => ({
|
|
152
|
+
...e,
|
|
153
|
+
skipReason: "unsupported-style",
|
|
154
|
+
status: "skipped",
|
|
155
|
+
hasUpdate: !1
|
|
156
|
+
}));
|
|
157
|
+
R.push(...U), z = z.filter((e) => e.targetRef);
|
|
158
|
+
let W = z.filter((e) => e.isBreaking);
|
|
159
|
+
if (z.length === 0) {
|
|
160
|
+
if (T?.success("All actions are up to date!"), x) {
|
|
168
161
|
o({
|
|
169
162
|
actionsToCheckCount: N.length,
|
|
170
|
-
status: "
|
|
163
|
+
status: "up-to-date",
|
|
171
164
|
blockedByMode: H,
|
|
172
165
|
scanResult: l,
|
|
173
|
-
outdated: z,
|
|
174
166
|
skipped: R
|
|
175
167
|
});
|
|
176
168
|
return;
|
|
177
169
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
170
|
+
R.length > 0 && u(R, O, A), H.length > 0 && g(H, k), console.info(w.green("\n⨠Everything is already at the latest version!\n"));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (T?.success(`Found ${w.yellow(z.length)} updates available${W.length > 0 ? ` (${w.redBright(W.length)} breaking)` : ""}`), x) {
|
|
174
|
+
o({
|
|
175
|
+
actionsToCheckCount: N.length,
|
|
176
|
+
status: "updates-available",
|
|
177
|
+
blockedByMode: H,
|
|
178
|
+
scanResult: l,
|
|
179
|
+
outdated: z,
|
|
180
|
+
skipped: R
|
|
181
|
+
});
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (R.length > 0 && u(R, O, A), H.length > 0 && g(H, k), y.dryRun) {
|
|
185
|
+
console.info(w.yellow("\nš Dry Run - No changes will be made\n"));
|
|
186
|
+
for (let e of z) {
|
|
187
|
+
let t = e.targetRefStyle === "sha" && e.targetRef ? `${e.latestVersion} ${w.gray(`(${e.targetRef.slice(0, 7)})`)}` : e.targetRef ?? e.latestVersion;
|
|
188
|
+
console.info(`${w.cyan(e.action.file ?? "unknown")}:\n${e.action.name}: ${w.redBright(e.currentVersion)} ā ${w.green(t)}\n`);
|
|
189
|
+
}
|
|
190
|
+
console.info(w.gray(`\n${z.length} actions would be updated\n`));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
if (y.yes) {
|
|
194
|
+
let e = z.filter((e) => e.targetRef);
|
|
195
|
+
if (e.length === 0) {
|
|
196
|
+
console.info(w.yellow("\nā ļø No actionable updates available\n"));
|
|
185
197
|
return;
|
|
186
198
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
} else {
|
|
195
|
-
(R.length > 0 || H.length > 0) && console.info("");
|
|
196
|
-
let e = await n(z, { showAge: b.minAge > 0 });
|
|
197
|
-
if (!e || e.length === 0) {
|
|
198
|
-
console.info(C.gray("\nNo updates applied"));
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
console.info(C.yellow(`\nš Updating ${e.length} selected actions...\n`)), await c(e), console.info(C.green("\nā Updates applied successfully!"));
|
|
199
|
+
console.info(w.yellow(`\nš Updating ${e.length} actions...\n`)), await c(e), console.info(w.green("\nā Updates applied successfully!"));
|
|
200
|
+
} else {
|
|
201
|
+
(R.length > 0 || H.length > 0) && console.info("");
|
|
202
|
+
let e = await n(z, { showAge: y.minAge > 0 });
|
|
203
|
+
if (!e || e.length === 0) {
|
|
204
|
+
console.info(w.gray("\nNo updates applied"));
|
|
205
|
+
return;
|
|
202
206
|
}
|
|
203
|
-
|
|
204
|
-
T?.error("Failed"), e instanceof Error && e.name === "GitHubRateLimitError" ? (console.error(C.yellow("\nā ļø Rate Limit Exceeded\n")), console.error(e.message), console.error(C.gray("\nExample: GITHUB_TOKEN=ghp_xxxx actions-up\n"))) : console.error(C.redBright("\nError:"), e instanceof Error ? e.message : String(e)), process.exit(1);
|
|
207
|
+
console.info(w.yellow(`\nš Updating ${e.length} selected actions...\n`)), await c(e), console.info(w.green("\nā Updates applied successfully!"));
|
|
205
208
|
}
|
|
206
|
-
}
|
|
209
|
+
} catch (e) {
|
|
210
|
+
T?.error("Failed"), e instanceof Error && e.name === "GitHubRateLimitError" ? (console.error(w.yellow("\nā ļø Rate Limit Exceeded\n")), console.error(e.message), console.error(w.gray("\nExample: GITHUB_TOKEN=ghp_xxxx actions-up\n"))) : console.error(w.redBright("\nError:"), e instanceof Error ? e.message : String(e)), process.exit(1);
|
|
211
|
+
}
|
|
207
212
|
}
|
|
208
213
|
export { T as run };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Options.
|
|
3
|
+
*/
|
|
4
|
+
export interface CLIOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Regex patterns to exclude actions by name (repeatable).
|
|
7
|
+
*/
|
|
8
|
+
exclude?: string[] | string;
|
|
9
|
+
/**
|
|
10
|
+
* Whether to include branch references in update checks.
|
|
11
|
+
*/
|
|
12
|
+
includeBranches?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Custom directory name (e.g., '.gitea' instead of '.github').
|
|
15
|
+
*/
|
|
16
|
+
dir?: string[] | string;
|
|
17
|
+
/**
|
|
18
|
+
* Recursively scan directories for YAML files.
|
|
19
|
+
*/
|
|
20
|
+
recursive?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Preview changes without applying them.
|
|
23
|
+
*/
|
|
24
|
+
dryRun: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Update style (sha or preserve).
|
|
27
|
+
*/
|
|
28
|
+
style?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Output a machine-readable JSON report.
|
|
31
|
+
*/
|
|
32
|
+
json?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Minimum age in days for updates.
|
|
35
|
+
*/
|
|
36
|
+
minAge: number;
|
|
37
|
+
/**
|
|
38
|
+
* Update mode (major, minor, patch).
|
|
39
|
+
*/
|
|
40
|
+
mode?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Skip all confirmations.
|
|
43
|
+
*/
|
|
44
|
+
yes: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Result of parsing CLI arguments. `kind` discriminates what the caller should
|
|
48
|
+
* do next.
|
|
49
|
+
*/
|
|
50
|
+
export type ParseArgumentsResult = {
|
|
51
|
+
options: CLIOptions;
|
|
52
|
+
kind: 'options';
|
|
53
|
+
} | {
|
|
54
|
+
message: string;
|
|
55
|
+
kind: 'error';
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'version';
|
|
58
|
+
text: string;
|
|
59
|
+
} | {
|
|
60
|
+
kind: 'help';
|
|
61
|
+
text: string;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Parse CLI arguments into normalized options.
|
|
65
|
+
*
|
|
66
|
+
* Reproduces the previous cac behavior without its runtime magic: numeric
|
|
67
|
+
* coercion for `--min-age` and the option defaults are applied manually here,
|
|
68
|
+
* and kebab-case flags are mapped to the camelCase option shape.
|
|
69
|
+
*
|
|
70
|
+
* @param argv - Raw arguments, typically `process.argv.slice(2)`.
|
|
71
|
+
* @param appVersion - Version string used for `--version`.
|
|
72
|
+
* @returns A discriminated result describing what the caller should do.
|
|
73
|
+
*/
|
|
74
|
+
export declare function parseArguments(argv: string[], appVersion: string): ParseArgumentsResult;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { parseArgs as e } from "node:util";
|
|
2
|
+
var t = "Usage:\n $ actions-up [options]\n\nOptions:\n --dir <directory> Directory to scan (repeatable). Default: .github, or . with --recursive\n --dry-run Preview changes without applying them\n --exclude <regex> Exclude actions by regex (repeatable)\n --include-branches Also check actions pinned to branches (default: false)\n --json Output update information as machine-readable JSON\n --min-age <days> Minimum age in days for updates (default: 0)\n --mode <mode> Update mode: major, minor, or patch (default: major)\n --style <style> Update style: sha or preserve (default: sha)\n -r, --recursive Recursively scan directories for YAML files\n -y, --yes Skip all confirmations\n -h, --help Display this message\n -v, --version Display version number", n = {
|
|
3
|
+
exclude: {
|
|
4
|
+
type: "string",
|
|
5
|
+
multiple: !0
|
|
6
|
+
},
|
|
7
|
+
recursive: {
|
|
8
|
+
type: "boolean",
|
|
9
|
+
short: "r"
|
|
10
|
+
},
|
|
11
|
+
version: {
|
|
12
|
+
type: "boolean",
|
|
13
|
+
short: "v"
|
|
14
|
+
},
|
|
15
|
+
"include-branches": { type: "boolean" },
|
|
16
|
+
dir: {
|
|
17
|
+
type: "string",
|
|
18
|
+
multiple: !0
|
|
19
|
+
},
|
|
20
|
+
help: {
|
|
21
|
+
type: "boolean",
|
|
22
|
+
short: "h"
|
|
23
|
+
},
|
|
24
|
+
yes: {
|
|
25
|
+
type: "boolean",
|
|
26
|
+
short: "y"
|
|
27
|
+
},
|
|
28
|
+
"dry-run": { type: "boolean" },
|
|
29
|
+
"min-age": { type: "string" },
|
|
30
|
+
style: { type: "string" },
|
|
31
|
+
json: { type: "boolean" },
|
|
32
|
+
mode: { type: "string" }
|
|
33
|
+
};
|
|
34
|
+
function r(r, i) {
|
|
35
|
+
try {
|
|
36
|
+
let { values: a } = e({
|
|
37
|
+
allowPositionals: !1,
|
|
38
|
+
options: n,
|
|
39
|
+
strict: !0,
|
|
40
|
+
args: r
|
|
41
|
+
});
|
|
42
|
+
if (a.help) return {
|
|
43
|
+
text: t,
|
|
44
|
+
kind: "help"
|
|
45
|
+
};
|
|
46
|
+
if (a.version) return {
|
|
47
|
+
text: `actions-up/${i} ${process.platform}-${process.arch} node-${process.version}`,
|
|
48
|
+
kind: "version"
|
|
49
|
+
};
|
|
50
|
+
let o = a["min-age"], s = o === void 0 ? 0 : Number(o);
|
|
51
|
+
return !Number.isFinite(s) || s < 0 ? {
|
|
52
|
+
message: `Invalid --min-age "${o}". Expected a non-negative number.`,
|
|
53
|
+
kind: "error"
|
|
54
|
+
} : {
|
|
55
|
+
options: {
|
|
56
|
+
includeBranches: a["include-branches"],
|
|
57
|
+
dryRun: a["dry-run"] ?? !1,
|
|
58
|
+
style: a.style ?? "sha",
|
|
59
|
+
mode: a.mode ?? "major",
|
|
60
|
+
recursive: a.recursive,
|
|
61
|
+
yes: a.yes ?? !1,
|
|
62
|
+
exclude: a.exclude,
|
|
63
|
+
json: a.json,
|
|
64
|
+
dir: a.dir,
|
|
65
|
+
minAge: s
|
|
66
|
+
},
|
|
67
|
+
kind: "options"
|
|
68
|
+
};
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return {
|
|
71
|
+
message: e.message,
|
|
72
|
+
kind: "error"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
export { r as parseArguments };
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import r from "
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { isSemverLike as e } from "../versions/is-semver-like.js";
|
|
2
|
+
import { preserveTagFormat as t } from "../versions/preserve-tag-format.js";
|
|
3
|
+
import { normalizeVersion as n } from "../versions/normalize-version.js";
|
|
4
|
+
import { createGitHubClient as r } from "./create-github-client.js";
|
|
5
|
+
import i from "semver";
|
|
6
|
+
async function a(t, a, s) {
|
|
7
|
+
let d = s?.client ?? r(a), f = s?.includeBranches ?? !1, p = s?.style ?? "sha", m = t.filter((e) => e.type === "external" || e.type === "reusable-workflow");
|
|
7
8
|
if (m.length === 0) return [];
|
|
8
9
|
let h = /* @__PURE__ */ new Map();
|
|
9
10
|
for (let e of m) {
|
|
@@ -13,158 +14,158 @@ async function i(i, o, u) {
|
|
|
13
14
|
let g = {
|
|
14
15
|
rateLimitError: null,
|
|
15
16
|
rateLimitHit: !1
|
|
16
|
-
}, _ = await [...h.keys()].reduce((
|
|
17
|
-
if (g.rateLimitHit) return [...
|
|
17
|
+
}, _ = await [...h.keys()].reduce((t, r) => t.then(async (t) => {
|
|
18
|
+
if (g.rateLimitHit) return [...t, {
|
|
18
19
|
currentRefType: "unknown",
|
|
19
20
|
publishedAt: null,
|
|
20
21
|
version: null,
|
|
21
|
-
actionName:
|
|
22
|
+
actionName: r,
|
|
22
23
|
sha: null
|
|
23
24
|
}];
|
|
24
|
-
let a =
|
|
25
|
-
if (a.length < 2) return [...
|
|
25
|
+
let a = r.split("/");
|
|
26
|
+
if (a.length < 2) return [...t, {
|
|
26
27
|
currentRefType: "unknown",
|
|
27
28
|
publishedAt: null,
|
|
28
29
|
version: null,
|
|
29
|
-
actionName:
|
|
30
|
+
actionName: r,
|
|
30
31
|
sha: null
|
|
31
32
|
}];
|
|
32
|
-
let [o,
|
|
33
|
-
if (!o || !
|
|
33
|
+
let [o, s] = a;
|
|
34
|
+
if (!o || !s) return [...t, {
|
|
34
35
|
currentRefType: "unknown",
|
|
35
36
|
publishedAt: null,
|
|
36
37
|
version: null,
|
|
37
|
-
actionName:
|
|
38
|
+
actionName: r,
|
|
38
39
|
sha: null
|
|
39
40
|
}];
|
|
40
41
|
try {
|
|
41
|
-
let a = h.get(
|
|
42
|
-
if (a && !
|
|
43
|
-
let e = await d.getRefType(o,
|
|
44
|
-
if (p = e === "branch" || e === "tag" ? e : p, e === "branch" && !f) return [...
|
|
42
|
+
let a = h.get(r)[0]?.version, p = l(a);
|
|
43
|
+
if (a && !c(a) && !e(a)) {
|
|
44
|
+
let e = await d.getRefType(o, s, a);
|
|
45
|
+
if (p = e === "branch" || e === "tag" ? e : p, e === "branch" && !f) return [...t, {
|
|
45
46
|
currentRefType: p,
|
|
46
47
|
skipReason: "branch",
|
|
47
48
|
status: "skipped",
|
|
48
49
|
publishedAt: null,
|
|
49
50
|
version: null,
|
|
50
|
-
actionName:
|
|
51
|
+
actionName: r,
|
|
51
52
|
sha: null
|
|
52
53
|
}];
|
|
53
54
|
}
|
|
54
|
-
let m = await d.getLatestRelease(o,
|
|
55
|
+
let m = await d.getLatestRelease(o, s);
|
|
55
56
|
if (!m) {
|
|
56
|
-
let e = await d.getAllReleases(o,
|
|
57
|
+
let e = await d.getAllReleases(o, s, 1);
|
|
57
58
|
m = e.find((e) => !e.isPrerelease) ?? e[0] ?? null;
|
|
58
59
|
}
|
|
59
60
|
if (m) {
|
|
60
|
-
let { publishedAt: a, version:
|
|
61
|
+
let { publishedAt: a, version: c, sha: l } = m, f = !1;
|
|
61
62
|
{
|
|
62
|
-
let
|
|
63
|
-
f = !
|
|
63
|
+
let t = n(c), r = !!(c && c.trim() !== ""), a = r && /^v?\d+$/u.test(c.trim()), o = i.valid(t);
|
|
64
|
+
f = !r || a || !o || !e(c);
|
|
64
65
|
}
|
|
65
66
|
if (f) {
|
|
66
|
-
let a = await d.getAllTags(o,
|
|
67
|
+
let a = await d.getAllTags(o, s, 30);
|
|
67
68
|
if (a.length > 0) {
|
|
68
|
-
let
|
|
69
|
-
v:
|
|
70
|
-
raw:
|
|
69
|
+
let l = a.filter((t) => e(t.tag)).map((e) => ({
|
|
70
|
+
v: i.valid(n(e.tag)),
|
|
71
|
+
raw: e
|
|
71
72
|
}));
|
|
72
|
-
if (
|
|
73
|
-
|
|
74
|
-
let n =
|
|
73
|
+
if (l.length > 0) {
|
|
74
|
+
l.sort((e, t) => {
|
|
75
|
+
let n = i.rcompare(e.v, t.v);
|
|
75
76
|
if (n !== 0) return n;
|
|
76
|
-
let
|
|
77
|
-
return +!!/\d+\.\d+/u.test(t.raw.tag) -
|
|
77
|
+
let r = +!!/\d+\.\d+/u.test(e.raw.tag);
|
|
78
|
+
return +!!/\d+\.\d+/u.test(t.raw.tag) - r;
|
|
78
79
|
});
|
|
79
|
-
let
|
|
80
|
-
if (!a ||
|
|
81
|
-
let
|
|
82
|
-
if (!
|
|
83
|
-
|
|
80
|
+
let e = l[0].raw, a = i.valid(n(c) ?? void 0);
|
|
81
|
+
if (!a || i.gt(l[0].v, a) || i.eq(l[0].v, a) && /\d+\.\d+/u.test(e.tag)) {
|
|
82
|
+
let n = e.tag, i = e.sha?.length ? e.sha : null;
|
|
83
|
+
if (!i && n) try {
|
|
84
|
+
i = await d.getTagSha(o, s, n);
|
|
84
85
|
} catch (e) {
|
|
85
|
-
if (
|
|
86
|
+
if (u(e)) throw e;
|
|
86
87
|
}
|
|
87
|
-
return [...
|
|
88
|
+
return [...t, {
|
|
88
89
|
currentRefType: p,
|
|
89
|
-
version:
|
|
90
|
+
version: n,
|
|
90
91
|
publishedAt: null,
|
|
91
|
-
sha:
|
|
92
|
-
actionName:
|
|
92
|
+
sha: i,
|
|
93
|
+
actionName: r
|
|
93
94
|
}];
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
}
|
|
97
98
|
}
|
|
98
|
-
if (
|
|
99
|
-
let e =
|
|
99
|
+
if (c) {
|
|
100
|
+
let e = l;
|
|
100
101
|
try {
|
|
101
|
-
|
|
102
|
+
l = await d.getTagSha(o, s, c) ?? e;
|
|
102
103
|
} catch (t) {
|
|
103
|
-
if (
|
|
104
|
-
|
|
104
|
+
if (u(t)) throw t;
|
|
105
|
+
l = e;
|
|
105
106
|
}
|
|
106
107
|
}
|
|
107
|
-
return [...
|
|
108
|
+
return [...t, {
|
|
108
109
|
currentRefType: p,
|
|
109
110
|
status: "ok",
|
|
110
111
|
publishedAt: a,
|
|
111
|
-
actionName:
|
|
112
|
-
version:
|
|
113
|
-
sha:
|
|
112
|
+
actionName: r,
|
|
113
|
+
version: c,
|
|
114
|
+
sha: l
|
|
114
115
|
}];
|
|
115
116
|
}
|
|
116
|
-
let g = await d.getAllTags(o,
|
|
117
|
+
let g = await d.getAllTags(o, s, 30);
|
|
117
118
|
if (g.length > 0) {
|
|
118
|
-
let a = g.filter((
|
|
119
|
-
v:
|
|
120
|
-
raw:
|
|
121
|
-
})),
|
|
119
|
+
let a = g.filter((t) => e(t.tag)).map((e) => ({
|
|
120
|
+
v: i.valid(n(e.tag)),
|
|
121
|
+
raw: e
|
|
122
|
+
})), c;
|
|
122
123
|
a.length > 0 ? (a.sort((e, t) => {
|
|
123
|
-
let n =
|
|
124
|
+
let n = i.rcompare(e.v, t.v);
|
|
124
125
|
if (n !== 0) return n;
|
|
125
|
-
let
|
|
126
|
-
return +!!/\d+\.\d+/u.test(t.raw.tag) -
|
|
127
|
-
}),
|
|
128
|
-
let
|
|
129
|
-
if (!f &&
|
|
130
|
-
f = await d.getTagSha(o,
|
|
126
|
+
let r = +!!/\d+\.\d+/u.test(e.raw.tag);
|
|
127
|
+
return +!!/\d+\.\d+/u.test(t.raw.tag) - r;
|
|
128
|
+
}), c = a[0].raw) : c = g[0];
|
|
129
|
+
let l = c.tag, f = c.sha?.length ? c.sha : null;
|
|
130
|
+
if (!f && l) try {
|
|
131
|
+
f = await d.getTagSha(o, s, l);
|
|
131
132
|
} catch (e) {
|
|
132
|
-
if (
|
|
133
|
+
if (u(e)) throw e;
|
|
133
134
|
}
|
|
134
|
-
return [...
|
|
135
|
+
return [...t, {
|
|
135
136
|
currentRefType: p,
|
|
136
137
|
status: "ok",
|
|
137
138
|
publishedAt: null,
|
|
138
|
-
actionName:
|
|
139
|
-
version:
|
|
139
|
+
actionName: r,
|
|
140
|
+
version: l,
|
|
140
141
|
sha: f
|
|
141
142
|
}];
|
|
142
143
|
}
|
|
143
|
-
return [...
|
|
144
|
+
return [...t, {
|
|
144
145
|
currentRefType: p,
|
|
145
146
|
publishedAt: null,
|
|
146
147
|
version: null,
|
|
147
|
-
actionName:
|
|
148
|
+
actionName: r,
|
|
148
149
|
sha: null
|
|
149
150
|
}];
|
|
150
151
|
} catch (e) {
|
|
151
|
-
return e instanceof Error && e.name === "GitHubRateLimitError" ? (g.rateLimitHit = !0, g.rateLimitError = e, [...
|
|
152
|
+
return e instanceof Error && e.name === "GitHubRateLimitError" ? (g.rateLimitHit = !0, g.rateLimitError = e, [...t, {
|
|
152
153
|
currentRefType: "unknown",
|
|
153
154
|
publishedAt: null,
|
|
154
155
|
version: null,
|
|
155
|
-
actionName:
|
|
156
|
+
actionName: r,
|
|
156
157
|
sha: null
|
|
157
|
-
}]) : (console.warn(`Failed to check ${
|
|
158
|
+
}]) : (console.warn(`Failed to check ${r}:`, e), [...t, {
|
|
158
159
|
currentRefType: "unknown",
|
|
159
160
|
publishedAt: null,
|
|
160
161
|
version: null,
|
|
161
|
-
actionName:
|
|
162
|
+
actionName: r,
|
|
162
163
|
sha: null
|
|
163
164
|
}]);
|
|
164
165
|
}
|
|
165
166
|
}), Promise.resolve([]));
|
|
166
167
|
if (g.rateLimitError) {
|
|
167
|
-
let e = !!(
|
|
168
|
+
let e = !!(a ?? process.env.GITHUB_TOKEN), t = `${g.rateLimitError.message || "GitHub API rate limit exceeded."}\n${e ? "Wait for reset or reduce request rate." : "Please set GITHUB_TOKEN environment variable to increase the limit.\nSee: https://github.com/azat-io/actions-up?tab=readme-ov-file#github-token"}`, n = Error(t);
|
|
168
169
|
throw n.name = "GitHubRateLimitError", n;
|
|
169
170
|
}
|
|
170
171
|
let v = /* @__PURE__ */ new Map();
|
|
@@ -180,7 +181,7 @@ async function i(i, o, u) {
|
|
|
180
181
|
let y = [];
|
|
181
182
|
for (let e of m) {
|
|
182
183
|
let t = v.get(e.name);
|
|
183
|
-
t ? y.push(
|
|
184
|
+
t ? y.push(o(e, {
|
|
184
185
|
publishedAt: t.publishedAt,
|
|
185
186
|
version: t.version,
|
|
186
187
|
sha: t.sha
|
|
@@ -189,68 +190,68 @@ async function i(i, o, u) {
|
|
|
189
190
|
skipReason: t.skipReason,
|
|
190
191
|
status: t.status,
|
|
191
192
|
style: p
|
|
192
|
-
})) : y.push(
|
|
193
|
+
})) : y.push(o(e, {
|
|
193
194
|
publishedAt: null,
|
|
194
195
|
version: null,
|
|
195
196
|
sha: null
|
|
196
197
|
}, {
|
|
197
|
-
currentRefType:
|
|
198
|
+
currentRefType: l(e.version),
|
|
198
199
|
style: p
|
|
199
200
|
}));
|
|
200
201
|
}
|
|
201
202
|
return y;
|
|
202
203
|
}
|
|
203
|
-
function
|
|
204
|
-
let { version:
|
|
205
|
-
if (
|
|
204
|
+
function o(e, r, a) {
|
|
205
|
+
let { version: o, sha: l, publishedAt: u } = r, d = e.version ?? "unknown", f = n(d), p = a.currentRefType, { style: m } = a, h = (m === "preserve" && p === "tag" ? t(d, o) : null) ?? o, g = h ? n(h) : null, _ = a.status ?? "ok", v = a.skipReason, y = !1, b = !1;
|
|
206
|
+
if (_ === "skipped") return {
|
|
206
207
|
currentRefType: p,
|
|
207
|
-
currentVersion:
|
|
208
|
+
currentVersion: d,
|
|
208
209
|
isBreaking: !1,
|
|
209
210
|
hasUpdate: !1,
|
|
210
|
-
latestVersion:
|
|
211
|
-
publishedAt:
|
|
212
|
-
skipReason:
|
|
213
|
-
latestSha:
|
|
214
|
-
action:
|
|
215
|
-
status:
|
|
211
|
+
latestVersion: o,
|
|
212
|
+
publishedAt: u,
|
|
213
|
+
skipReason: v,
|
|
214
|
+
latestSha: l,
|
|
215
|
+
action: e,
|
|
216
|
+
status: _
|
|
216
217
|
};
|
|
217
|
-
if (
|
|
218
|
-
else if (
|
|
219
|
-
let
|
|
220
|
-
if (
|
|
221
|
-
if (
|
|
222
|
-
let
|
|
223
|
-
|
|
218
|
+
if (f && c(f)) l ? y = !s(f, l) : g && (y = !0);
|
|
219
|
+
else if (f && g) {
|
|
220
|
+
let t = i.valid(f), n = i.valid(g);
|
|
221
|
+
if (t && n) {
|
|
222
|
+
if (y = i.lt(t, n), y) {
|
|
223
|
+
let e = i.major(t);
|
|
224
|
+
b = i.major(n) > e;
|
|
224
225
|
}
|
|
225
|
-
!
|
|
226
|
-
} else
|
|
226
|
+
!y && i.eq(t, n) && !c(e.version) && l && m === "sha" && (y = !0, b = !1);
|
|
227
|
+
} else f !== g && (y = !0);
|
|
227
228
|
}
|
|
228
229
|
return {
|
|
229
230
|
currentRefType: p,
|
|
230
|
-
currentVersion:
|
|
231
|
-
latestVersion:
|
|
232
|
-
publishedAt:
|
|
233
|
-
isBreaking:
|
|
234
|
-
skipReason:
|
|
235
|
-
latestSha:
|
|
236
|
-
hasUpdate:
|
|
237
|
-
action:
|
|
238
|
-
status:
|
|
231
|
+
currentVersion: d,
|
|
232
|
+
latestVersion: o,
|
|
233
|
+
publishedAt: u,
|
|
234
|
+
isBreaking: b,
|
|
235
|
+
skipReason: v,
|
|
236
|
+
latestSha: l,
|
|
237
|
+
hasUpdate: y,
|
|
238
|
+
action: e,
|
|
239
|
+
status: _
|
|
239
240
|
};
|
|
240
241
|
}
|
|
241
|
-
function
|
|
242
|
+
function s(e, t) {
|
|
242
243
|
let n = e.replace(/^v/u, ""), r = t.replace(/^v/u, ""), i = Math.min(n.length, r.length);
|
|
243
244
|
return i < 7 ? !1 : n.slice(0, Math.max(0, i)).toLowerCase() === r.slice(0, Math.max(0, i)).toLowerCase();
|
|
244
245
|
}
|
|
245
|
-
function
|
|
246
|
+
function c(e) {
|
|
246
247
|
if (!e) return !1;
|
|
247
248
|
let t = e.replace(/^v/u, "");
|
|
248
249
|
return /^[0-9a-f]{7,40}$/iu.test(t);
|
|
249
250
|
}
|
|
250
|
-
function
|
|
251
|
-
return
|
|
251
|
+
function l(t) {
|
|
252
|
+
return t ? c(t) ? "sha" : e(t) ? "tag" : "unknown" : "unknown";
|
|
252
253
|
}
|
|
253
|
-
function
|
|
254
|
+
function u(e) {
|
|
254
255
|
return e instanceof Error && e.name === "GitHubRateLimitError";
|
|
255
256
|
}
|
|
256
|
-
export {
|
|
257
|
+
export { a as checkUpdates };
|
|
@@ -15,7 +15,7 @@ async function n(n) {
|
|
|
15
15
|
function i(e) {
|
|
16
16
|
return e.replaceAll(/[$()*+\-./?[\\\]^{|}]/gu, String.raw`\$&`);
|
|
17
17
|
}
|
|
18
|
-
let o = i(e.action.name), s = e.currentVersion ? i(e.currentVersion) : "";
|
|
18
|
+
let o = i(e.action.name), s = e.currentVersion ? i(e.currentVersion) : "", c = s ? String.raw`(?=(?:['"]|[ \t\]}{,#]|$))` : "";
|
|
19
19
|
if (o.includes("\n") || o.includes("\r")) {
|
|
20
20
|
console.error(`Invalid action name: ${e.action.name}`);
|
|
21
21
|
continue;
|
|
@@ -32,8 +32,8 @@ async function n(n) {
|
|
|
32
32
|
console.error(`Invalid SHA format: ${t}`);
|
|
33
33
|
continue;
|
|
34
34
|
}
|
|
35
|
-
let
|
|
36
|
-
a = a.replace(
|
|
35
|
+
let l = String.raw`['"]?\buses\b['"]?\s*:\s*`, u = String.raw`(?:^[^\S\n]*(?:-[^\S\n]*)?|[{\[,][^\S\n]*)` + l, d = new RegExp(String.raw`(?<prefix>${u})` + String.raw`(?<quote>['"]?)` + String.raw`(?<name>${o})@${s}${c}` + String.raw`\k<quote>` + String.raw`(?<after>[ \t\]}{,]*)` + String.raw`(?<comment>[^\S\r\n]*#[^\r\n]*)?`, "gm");
|
|
36
|
+
a = a.replace(d, (i, ...a) => {
|
|
37
37
|
let o = a.at(-3), c = a.at(-2), l = a.at(-1), u = c.indexOf("\n", o + i.length), d = (u === -1 ? c.slice(o + i.length) : c.slice(o + i.length, u)).trim().length > 0, f = l.after.endsWith(" ") ? "" : " ", p = "";
|
|
38
38
|
if (n === "sha") p = d && !l.comment && s !== "" ? "" : `${f}# ${e.latestVersion}`;
|
|
39
39
|
else if (l.comment && !r(l.comment)) {
|
|
@@ -1,24 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
targetRefStyle: "sha"
|
|
6
|
-
} : {
|
|
7
|
-
...e,
|
|
1
|
+
import { preserveTagFormat as e } from "../versions/preserve-tag-format.js";
|
|
2
|
+
function t(t, n) {
|
|
3
|
+
if (!t.hasUpdate) return {
|
|
4
|
+
...t,
|
|
8
5
|
targetRefStyle: null,
|
|
9
6
|
targetRef: null
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
};
|
|
8
|
+
if (n === "sha" || t.currentRefType === "sha") return t.latestSha ? {
|
|
9
|
+
...t,
|
|
10
|
+
targetRef: t.latestSha,
|
|
11
|
+
targetRefStyle: "sha"
|
|
14
12
|
} : {
|
|
15
|
-
...
|
|
13
|
+
...t,
|
|
16
14
|
targetRefStyle: null,
|
|
17
15
|
targetRef: null
|
|
18
|
-
}
|
|
19
|
-
|
|
16
|
+
};
|
|
17
|
+
if (t.currentRefType === "tag" && t.latestVersion) {
|
|
18
|
+
let n = e(t.currentVersion, t.latestVersion);
|
|
19
|
+
return n ? {
|
|
20
|
+
...t,
|
|
21
|
+
targetRef: n,
|
|
22
|
+
targetRefStyle: "tag"
|
|
23
|
+
} : {
|
|
24
|
+
...t,
|
|
25
|
+
targetRefStyle: null,
|
|
26
|
+
targetRef: null
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
...t,
|
|
20
31
|
targetRefStyle: null,
|
|
21
32
|
targetRef: null
|
|
22
33
|
};
|
|
23
34
|
}
|
|
24
|
-
export {
|
|
35
|
+
export { t as resolveTargetReference };
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isSemverLike as e } from "./is-semver-like.js";
|
|
2
|
+
import { normalizeVersion as t } from "./normalize-version.js";
|
|
3
3
|
import n from "semver";
|
|
4
4
|
function r(r, a, o) {
|
|
5
|
-
if (!a || !
|
|
6
|
-
let s = n.valid(
|
|
5
|
+
if (!a || !e(a) || r.length === 0) return null;
|
|
6
|
+
let s = n.valid(t(a));
|
|
7
7
|
if (!s) return null;
|
|
8
8
|
let c = n.major(s), l = n.minor(s), u = [];
|
|
9
9
|
for (let i of r) {
|
|
10
|
-
if (!
|
|
11
|
-
let r = n.valid(
|
|
10
|
+
if (!e(i.tag)) continue;
|
|
11
|
+
let r = n.valid(t(i.tag));
|
|
12
12
|
r && n.gt(r, s) && n.major(r) === c && (o === "patch" && n.minor(r) !== l || u.push({
|
|
13
13
|
tag: i,
|
|
14
14
|
parsed: r
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Preserve the semver granularity of the current tag when projecting a newer
|
|
3
|
+
* tag reference.
|
|
4
|
+
*
|
|
5
|
+
* Examples:
|
|
6
|
+
*
|
|
7
|
+
* - `v6` + `v7.0.2` -> `v7`
|
|
8
|
+
* - `v6.1` + `v6.2.3` -> `v6.2`
|
|
9
|
+
* - `v6.1.4` + `v6.2.3` -> `v6.2.3`.
|
|
10
|
+
*
|
|
11
|
+
* Returns null when the target tag cannot be preserved safely.
|
|
12
|
+
*
|
|
13
|
+
* @param currentVersion - Current tag reference found in the workflow.
|
|
14
|
+
* @param latestVersion - Latest resolved tag reference.
|
|
15
|
+
* @returns Preserved tag reference or null when preservation is unsafe.
|
|
16
|
+
*/
|
|
17
|
+
export declare function preserveTagFormat(currentVersion: undefined | string | null, latestVersion: undefined | string | null): string | null;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { isSemverLike as e } from "./is-semver-like.js";
|
|
2
|
+
function t(t, n) {
|
|
3
|
+
if (!t || !n) return null;
|
|
4
|
+
let r = t.trim(), i = n.trim();
|
|
5
|
+
if (!e(r) || !e(i)) return null;
|
|
6
|
+
let a = r.startsWith("v");
|
|
7
|
+
if (a !== i.startsWith("v")) return null;
|
|
8
|
+
let o = r.replace(/^v/u, "").split("."), s = i.replace(/^v/u, "").split(".");
|
|
9
|
+
return s.length < o.length ? null : `${a ? "v" : ""}${s.slice(0, o.length).join(".")}`;
|
|
10
|
+
}
|
|
11
|
+
export { t as preserveTagFormat };
|
package/dist/package.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e = "1.14.
|
|
1
|
+
var e = "1.14.3";
|
|
2
2
|
export { e as version };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "actions-up",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.3",
|
|
4
4
|
"description": "Interactive CLI tool to update GitHub Actions with SHA pinning or preserved refs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github-actions",
|
|
@@ -36,14 +36,13 @@
|
|
|
36
36
|
"./dist"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"cac": "^7.0.0",
|
|
40
39
|
"enquirer": "^2.4.1",
|
|
41
40
|
"nanospinner": "^1.2.2",
|
|
42
41
|
"picocolors": "^1.1.1",
|
|
43
|
-
"semver": "^7.
|
|
44
|
-
"yaml": "^2.
|
|
42
|
+
"semver": "^7.8.4",
|
|
43
|
+
"yaml": "^2.9.0"
|
|
45
44
|
},
|
|
46
45
|
"engines": {
|
|
47
|
-
"node": "^18.
|
|
46
|
+
"node": "^18.3.0 || >=20.0.0"
|
|
48
47
|
}
|
|
49
48
|
}
|
package/readme.md
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
<img
|
|
4
4
|
src="https://raw.githubusercontent.com/azat-io/actions-up/main/assets/logo.svg"
|
|
5
5
|
alt="Actions Up logo"
|
|
6
|
-
width="160"
|
|
7
|
-
height="160"
|
|
8
6
|
align="right"
|
|
7
|
+
width="160"
|
|
9
8
|
/>
|
|
10
9
|
|
|
11
10
|
[](https://npmjs.com/package/actions-up)
|
|
@@ -102,7 +101,8 @@ Per-project
|
|
|
102
101
|
npm install --save-dev actions-up
|
|
103
102
|
```
|
|
104
103
|
|
|
105
|
-
Alternatively, you can install Actions Up with
|
|
104
|
+
Alternatively, you can install Actions Up with
|
|
105
|
+
[Homebrew](https://formulae.brew.sh/formula/actions-up)
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
108
|
brew install actions-up
|
|
@@ -214,9 +214,11 @@ Use `--style preserve` to keep the current reference style:
|
|
|
214
214
|
npx actions-up --style preserve
|
|
215
215
|
```
|
|
216
216
|
|
|
217
|
-
`preserve` keeps tag references on tags and SHA references on SHAs.
|
|
218
|
-
`actions/checkout@v5` updates to
|
|
219
|
-
|
|
217
|
+
`preserve` keeps tag references on tags and SHA references on SHAs. Tag refs
|
|
218
|
+
also keep their granularity, so `actions/checkout@v5` updates to
|
|
219
|
+
`actions/checkout@v6`, while `actions/checkout@v5.0` updates to
|
|
220
|
+
`actions/checkout@v6.0`. A SHA-pinned action continues updating to the latest
|
|
221
|
+
resolved SHA.
|
|
220
222
|
|
|
221
223
|
## GitHub Actions Integration
|
|
222
224
|
|