actions-up 1.6.0 → 1.8.0
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 +38 -29
- package/dist/core/api/check-updates.d.ts +4 -1
- package/dist/core/api/check-updates.js +74 -51
- package/dist/core/ast/update/apply-updates.js +5 -2
- package/dist/core/interactive/prompt-update-selection.js +7 -7
- package/dist/package.js +1 -1
- package/dist/types/action-update.d.ts +6 -0
- package/package.json +2 -2
- package/readme.md +4 -0
package/dist/cli/index.js
CHANGED
|
@@ -10,57 +10,57 @@ import "node:worker_threads";
|
|
|
10
10
|
import pc from "picocolors";
|
|
11
11
|
import cac from "cac";
|
|
12
12
|
function run() {
|
|
13
|
-
let
|
|
14
|
-
|
|
13
|
+
let u = cac("actions-up");
|
|
14
|
+
u.help().version(version).option("--dir <directory>", "Custom directory name (default: .github)").option("--dry-run", "Preview changes without applying them").option("--exclude <regex>", "Exclude actions by regex (repeatable)").option("--include-branches", "Also check actions pinned to branches (default: false)").option("--min-age <days>", "Minimum age in days for updates (default: 0)", { default: 0 }).option("--yes, -y", "Skip all confirmations").command("", "Update GitHub Actions").action(async (c) => {
|
|
15
15
|
console.info(pc.cyan("\n🚀 Actions Up!\n"));
|
|
16
|
-
let
|
|
16
|
+
let l = createSpinner("Scanning GitHub Actions...").start();
|
|
17
17
|
try {
|
|
18
|
-
let
|
|
19
|
-
if (
|
|
18
|
+
let u = await scanGitHubActions(process.cwd(), c.dir), d = u.actions.length, f = u.workflows.size, p = u.compositeActions.size;
|
|
19
|
+
if (l.success(`Found ${pc.yellow(d)} actions in ${pc.yellow(f)} workflows and ${pc.yellow(p)} composite actions`), d === 0) {
|
|
20
20
|
console.info(pc.green("\n✨ No GitHub Actions found in this repository"));
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
let
|
|
24
|
-
Array.isArray(
|
|
25
|
-
let
|
|
26
|
-
if (
|
|
27
|
-
let { parseExcludePatterns: e } = await import("../core/filters/parse-exclude-patterns.js"), a = e(
|
|
28
|
-
a.length > 0 && (
|
|
23
|
+
let m = u.actions, h = [];
|
|
24
|
+
Array.isArray(c.exclude) ? h.push(...c.exclude) : typeof c.exclude == "string" && h.push(c.exclude);
|
|
25
|
+
let g = h.flatMap((e) => e.split(",")).map((e) => e.trim()).filter(Boolean);
|
|
26
|
+
if (g.length > 0) {
|
|
27
|
+
let { parseExcludePatterns: e } = await import("../core/filters/parse-exclude-patterns.js"), a = e(g);
|
|
28
|
+
a.length > 0 && (m = m.filter((e) => {
|
|
29
29
|
let { name: o } = e;
|
|
30
30
|
for (let e of a) if (e.test(o)) return !1;
|
|
31
31
|
return !0;
|
|
32
32
|
}));
|
|
33
33
|
}
|
|
34
|
-
if (
|
|
35
|
-
|
|
34
|
+
if (l = createSpinner("Checking for updates...").start(), m.length === 0) {
|
|
35
|
+
l.success("No actions to check after excludes"), console.info(pc.green("\n✨ Nothing to check after excludes\n"));
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
|
-
let
|
|
39
|
-
await Promise.all(
|
|
40
|
-
await shouldIgnore(e.action.file, e.action.line) ||
|
|
38
|
+
let _ = c.includeBranches ?? !1, v = await checkUpdates(m, process.env.GITHUB_TOKEN, { includeBranches: _ }), y = [];
|
|
39
|
+
await Promise.all(v.map(async (e) => {
|
|
40
|
+
await shouldIgnore(e.action.file, e.action.line) || y.push(e);
|
|
41
41
|
}));
|
|
42
|
-
let
|
|
43
|
-
|
|
44
|
-
let
|
|
45
|
-
if (
|
|
46
|
-
|
|
42
|
+
let b = y.filter((e) => e.status === "skipped"), x = y.filter((e) => e.hasUpdate), S = c.minAge * 24 * 60 * 60 * 1e3, C = Date.now();
|
|
43
|
+
x = x.filter((e) => e.publishedAt ? C - e.publishedAt.getTime() >= S : !0);
|
|
44
|
+
let w = x.filter((e) => e.isBreaking);
|
|
45
|
+
if (x.length === 0) {
|
|
46
|
+
l.success("All actions are up to date!"), b.length > 0 && printSkippedWarning(b, _), console.info(pc.green("\n✨ Everything is already at the latest version!\n"));
|
|
47
47
|
return;
|
|
48
48
|
}
|
|
49
|
-
if (
|
|
49
|
+
if (l.success(`Found ${pc.yellow(x.length)} updates available${w.length > 0 ? ` (${pc.redBright(w.length)} breaking)` : ""}`), b.length > 0 && printSkippedWarning(b, _), c.dryRun) {
|
|
50
50
|
console.info(pc.yellow("\n📋 Dry Run - No changes will be made\n"));
|
|
51
|
-
for (let e of
|
|
52
|
-
console.info(pc.gray(`\n${
|
|
51
|
+
for (let e of x) console.info(`${pc.cyan(e.action.file ?? "unknown")}:\n${e.action.name}: ${pc.redBright(e.currentVersion)} → ${pc.green(e.latestVersion)} ${e.latestSha ? pc.gray(`(${e.latestSha.slice(0, 7)})`) : ""}\n`);
|
|
52
|
+
console.info(pc.gray(`\n${x.length} actions would be updated\n`));
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
if (
|
|
56
|
-
let e =
|
|
55
|
+
if (c.yes) {
|
|
56
|
+
let e = x.filter((e) => e.latestSha);
|
|
57
57
|
if (e.length === 0) {
|
|
58
58
|
console.info(pc.yellow("\n⚠️ No actions with SHA available for update\n"));
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
console.info(pc.yellow(`\n🔄 Updating ${e.length} actions...\n`)), await applyUpdates(e), console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
62
62
|
} else {
|
|
63
|
-
let o = await promptUpdateSelection(
|
|
63
|
+
let o = await promptUpdateSelection(x, { showAge: c.minAge > 0 });
|
|
64
64
|
if (!o || o.length === 0) {
|
|
65
65
|
console.info(pc.gray("\nNo updates applied"));
|
|
66
66
|
return;
|
|
@@ -68,8 +68,17 @@ function run() {
|
|
|
68
68
|
console.info(pc.yellow(`\n🔄 Updating ${o.length} selected actions...\n`)), await applyUpdates(o), console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
69
69
|
}
|
|
70
70
|
} catch (e) {
|
|
71
|
-
|
|
71
|
+
l.error("Failed"), e instanceof Error && e.name === "GitHubRateLimitError" ? (console.error(pc.yellow("\n⚠️ Rate Limit Exceeded\n")), console.error(e.message), console.error(pc.gray("\nExample: GITHUB_TOKEN=ghp_xxxx actions-up\n"))) : console.error(pc.redBright("\nError:"), e instanceof Error ? e.message : String(e)), process.exit(1);
|
|
72
72
|
}
|
|
73
|
-
}),
|
|
73
|
+
}), u.parse();
|
|
74
|
+
}
|
|
75
|
+
function printSkippedWarning(e, a) {
|
|
76
|
+
let o = new Intl.PluralRules("en-US", { type: "cardinal" }).select(e.length) === "one" ? "action" : "actions", s = a ? "" : " (use --include-branches to check them)";
|
|
77
|
+
console.info(pc.yellow(`\n⚠️ Skipped ${e.length} ${o} pinned to branches${s}`));
|
|
78
|
+
for (let a of e) {
|
|
79
|
+
let e = a.action.uses ?? `${a.action.name}@${a.currentVersion ?? "unknown"}`;
|
|
80
|
+
console.info(pc.gray(` • ${e}`));
|
|
81
|
+
}
|
|
82
|
+
console.info("");
|
|
74
83
|
}
|
|
75
84
|
export { run };
|
|
@@ -5,6 +5,9 @@ import { ActionUpdate } from '../../types/action-update';
|
|
|
5
5
|
*
|
|
6
6
|
* @param actions - Array of GitHub Actions to check.
|
|
7
7
|
* @param token - Optional GitHub token for authentication.
|
|
8
|
+
* @param options - Additional options (e.g., include branch refs).
|
|
8
9
|
* @returns Array of update information.
|
|
9
10
|
*/
|
|
10
|
-
export declare function checkUpdates(actions: GitHubAction[], token?: string
|
|
11
|
+
export declare function checkUpdates(actions: GitHubAction[], token?: string, options?: {
|
|
12
|
+
includeBranches?: boolean;
|
|
13
|
+
}): Promise<ActionUpdate[]>;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { createGitHubClient } from "./create-github-client.js";
|
|
2
2
|
import semver from "semver";
|
|
3
|
-
async function checkUpdates(n, i) {
|
|
4
|
-
let
|
|
5
|
-
if (
|
|
6
|
-
let
|
|
7
|
-
for (let e of
|
|
8
|
-
let t =
|
|
9
|
-
t.push(e),
|
|
3
|
+
async function checkUpdates(n, i, c) {
|
|
4
|
+
let l = createGitHubClient(i), u = c?.includeBranches ?? !1, d = n.filter((e) => e.type === "external" || e.type === "reusable-workflow");
|
|
5
|
+
if (d.length === 0) return [];
|
|
6
|
+
let f = /* @__PURE__ */ new Map();
|
|
7
|
+
for (let e of d) {
|
|
8
|
+
let t = f.get(e.name) ?? [];
|
|
9
|
+
t.push(e), f.set(e.name, t);
|
|
10
10
|
}
|
|
11
|
-
let
|
|
11
|
+
let p = {
|
|
12
12
|
rateLimitError: null,
|
|
13
13
|
rateLimitHit: !1
|
|
14
|
-
},
|
|
15
|
-
if (
|
|
14
|
+
}, m = await [...f.keys()].reduce((e, n) => e.then(async (e) => {
|
|
15
|
+
if (p.rateLimitHit) return [...e, {
|
|
16
16
|
publishedAt: null,
|
|
17
17
|
version: null,
|
|
18
18
|
actionName: n,
|
|
@@ -25,24 +25,26 @@ async function checkUpdates(n, i) {
|
|
|
25
25
|
actionName: n,
|
|
26
26
|
sha: null
|
|
27
27
|
}];
|
|
28
|
-
let [i,
|
|
29
|
-
if (!i || !
|
|
28
|
+
let [i, c] = r;
|
|
29
|
+
if (!i || !c) return [...e, {
|
|
30
30
|
publishedAt: null,
|
|
31
31
|
version: null,
|
|
32
32
|
actionName: n,
|
|
33
33
|
sha: null
|
|
34
34
|
}];
|
|
35
35
|
try {
|
|
36
|
-
let r =
|
|
37
|
-
if (r && !isSha(r) && !isSemverLike(r) && await
|
|
36
|
+
let r = f.get(n)[0]?.version;
|
|
37
|
+
if (r && !isSha(r) && !isSemverLike(r) && await l.getRefType(i, c, r) === "branch" && !u) return [...e, {
|
|
38
|
+
skipReason: "branch",
|
|
39
|
+
status: "skipped",
|
|
38
40
|
publishedAt: null,
|
|
39
41
|
version: null,
|
|
40
42
|
actionName: n,
|
|
41
43
|
sha: null
|
|
42
44
|
}];
|
|
43
|
-
let d = await
|
|
45
|
+
let d = await l.getLatestRelease(i, c);
|
|
44
46
|
if (!d) {
|
|
45
|
-
let e = await
|
|
47
|
+
let e = await l.getAllReleases(i, c, 1);
|
|
46
48
|
d = e.find((e) => !e.isPrerelease) ?? e[0] ?? null;
|
|
47
49
|
}
|
|
48
50
|
if (d) {
|
|
@@ -52,7 +54,7 @@ async function checkUpdates(n, i) {
|
|
|
52
54
|
f = !n || r || !i;
|
|
53
55
|
}
|
|
54
56
|
if (f) {
|
|
55
|
-
let r = await
|
|
57
|
+
let r = await l.getAllTags(i, c, 30);
|
|
56
58
|
if (r.length > 0) {
|
|
57
59
|
let u = r.filter((e) => isSemverLike(e.tag)).map((e) => ({
|
|
58
60
|
v: semver.valid(normalizeVersion(e.tag)),
|
|
@@ -69,7 +71,7 @@ async function checkUpdates(n, i) {
|
|
|
69
71
|
if (!s || semver.gt(u[0].v, s) || semver.eq(u[0].v, s) && /\d+\.\d+/u.test(r.tag)) {
|
|
70
72
|
let t = r.tag, a = r.sha?.length ? r.sha : null;
|
|
71
73
|
if (!a && t) try {
|
|
72
|
-
a = await
|
|
74
|
+
a = await l.getTagSha(i, c, t);
|
|
73
75
|
} catch {}
|
|
74
76
|
return [...e, {
|
|
75
77
|
version: t,
|
|
@@ -82,18 +84,19 @@ async function checkUpdates(n, i) {
|
|
|
82
84
|
}
|
|
83
85
|
}
|
|
84
86
|
if (!u && o) try {
|
|
85
|
-
u = await
|
|
87
|
+
u = await l.getTagSha(i, c, o);
|
|
86
88
|
} catch {}
|
|
87
89
|
return [...e, {
|
|
90
|
+
status: "ok",
|
|
88
91
|
publishedAt: r,
|
|
89
92
|
actionName: n,
|
|
90
93
|
version: o,
|
|
91
94
|
sha: u
|
|
92
95
|
}];
|
|
93
96
|
}
|
|
94
|
-
let
|
|
95
|
-
if (
|
|
96
|
-
let r =
|
|
97
|
+
let p = await l.getAllTags(i, c, 30);
|
|
98
|
+
if (p.length > 0) {
|
|
99
|
+
let r = p.filter((e) => isSemverLike(e.tag)).map((e) => ({
|
|
97
100
|
v: semver.valid(normalizeVersion(e.tag)),
|
|
98
101
|
raw: e
|
|
99
102
|
})), o;
|
|
@@ -102,12 +105,13 @@ async function checkUpdates(n, i) {
|
|
|
102
105
|
if (r !== 0) return r;
|
|
103
106
|
let i = /\d+\.\d+/u.test(e.raw.tag) ? 1 : 0;
|
|
104
107
|
return (/\d+\.\d+/u.test(n.raw.tag) ? 1 : 0) - i;
|
|
105
|
-
}), o = r[0].raw) : o =
|
|
108
|
+
}), o = r[0].raw) : o = p[0];
|
|
106
109
|
let u = o.tag, d = o.sha?.length ? o.sha : null;
|
|
107
110
|
if (!d && u) try {
|
|
108
|
-
d = await
|
|
111
|
+
d = await l.getTagSha(i, c, u);
|
|
109
112
|
} catch {}
|
|
110
113
|
return [...e, {
|
|
114
|
+
status: "ok",
|
|
111
115
|
publishedAt: null,
|
|
112
116
|
actionName: n,
|
|
113
117
|
version: u,
|
|
@@ -121,7 +125,7 @@ async function checkUpdates(n, i) {
|
|
|
121
125
|
sha: null
|
|
122
126
|
}];
|
|
123
127
|
} catch (t) {
|
|
124
|
-
return t instanceof Error && t.name === "GitHubRateLimitError" ? (
|
|
128
|
+
return t instanceof Error && t.name === "GitHubRateLimitError" ? (p.rateLimitHit = !0, p.rateLimitError = t, [...e, {
|
|
125
129
|
publishedAt: null,
|
|
126
130
|
version: null,
|
|
127
131
|
actionName: n,
|
|
@@ -134,52 +138,71 @@ async function checkUpdates(n, i) {
|
|
|
134
138
|
}]);
|
|
135
139
|
}
|
|
136
140
|
}), Promise.resolve([]));
|
|
137
|
-
if (
|
|
138
|
-
let e = !!(i ?? process.env.GITHUB_TOKEN), t = `${
|
|
141
|
+
if (p.rateLimitError) {
|
|
142
|
+
let e = !!(i ?? process.env.GITHUB_TOKEN), t = `${p.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#using-github-token-for-higher-rate-limits"}`, n = Error(t);
|
|
139
143
|
throw n.name = "GitHubRateLimitError", n;
|
|
140
144
|
}
|
|
141
|
-
let
|
|
142
|
-
for (let e of
|
|
145
|
+
let h = /* @__PURE__ */ new Map();
|
|
146
|
+
for (let e of m) h.set(e.actionName, {
|
|
143
147
|
publishedAt: e.publishedAt,
|
|
148
|
+
actionName: e.actionName,
|
|
149
|
+
skipReason: e.skipReason,
|
|
144
150
|
version: e.version,
|
|
151
|
+
status: e.status,
|
|
145
152
|
sha: e.sha
|
|
146
153
|
});
|
|
147
|
-
let
|
|
148
|
-
for (let e of
|
|
149
|
-
let t =
|
|
150
|
-
t ?
|
|
154
|
+
let g = [];
|
|
155
|
+
for (let e of d) {
|
|
156
|
+
let t = h.get(e.name);
|
|
157
|
+
t ? g.push(createUpdate(e, {
|
|
151
158
|
publishedAt: t.publishedAt,
|
|
152
159
|
version: t.version,
|
|
153
160
|
sha: t.sha
|
|
154
|
-
}
|
|
161
|
+
}, {
|
|
162
|
+
skipReason: t.skipReason,
|
|
163
|
+
status: t.status
|
|
164
|
+
})) : g.push(createUpdate(e, {
|
|
155
165
|
publishedAt: null,
|
|
156
166
|
version: null,
|
|
157
167
|
sha: null
|
|
158
168
|
}));
|
|
159
169
|
}
|
|
160
|
-
return
|
|
170
|
+
return g;
|
|
161
171
|
}
|
|
162
|
-
function createUpdate(e, n) {
|
|
163
|
-
let { version:
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
172
|
+
function createUpdate(e, n, r = {}) {
|
|
173
|
+
let { version: s, sha: c, publishedAt: l } = n, u = e.version ?? "unknown", d = normalizeVersion(u), f = s ? normalizeVersion(s) : null, p = r.status ?? "ok", m = r.skipReason, h = !1, g = !1;
|
|
174
|
+
if (p === "skipped") return {
|
|
175
|
+
currentVersion: u,
|
|
176
|
+
isBreaking: !1,
|
|
177
|
+
hasUpdate: !1,
|
|
178
|
+
latestVersion: s,
|
|
179
|
+
publishedAt: l,
|
|
180
|
+
skipReason: m,
|
|
181
|
+
latestSha: c,
|
|
182
|
+
action: e,
|
|
183
|
+
status: p
|
|
184
|
+
};
|
|
185
|
+
if (d && isSha(d)) c ? h = !compareSha(d, c) : f && (h = !0);
|
|
186
|
+
else if (d && f) {
|
|
187
|
+
let n = semver.valid(d), r = semver.valid(f);
|
|
167
188
|
if (n && r) {
|
|
168
|
-
if (
|
|
189
|
+
if (h = semver.lt(n, r), h) {
|
|
169
190
|
let e = semver.major(n);
|
|
170
|
-
|
|
191
|
+
g = semver.major(r) > e;
|
|
171
192
|
}
|
|
172
|
-
!
|
|
173
|
-
} else
|
|
193
|
+
!h && semver.eq(n, r) && !isSha(e.version) && c && (h = !0, g = !1);
|
|
194
|
+
} else d !== f && (h = !0);
|
|
174
195
|
}
|
|
175
196
|
return {
|
|
176
|
-
currentVersion:
|
|
177
|
-
latestVersion:
|
|
178
|
-
publishedAt:
|
|
179
|
-
isBreaking:
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
197
|
+
currentVersion: u,
|
|
198
|
+
latestVersion: s,
|
|
199
|
+
publishedAt: l,
|
|
200
|
+
isBreaking: g,
|
|
201
|
+
skipReason: m,
|
|
202
|
+
latestSha: c,
|
|
203
|
+
hasUpdate: h,
|
|
204
|
+
action: e,
|
|
205
|
+
status: p
|
|
183
206
|
};
|
|
184
207
|
}
|
|
185
208
|
function compareSha(e, t) {
|
|
@@ -27,8 +27,11 @@ async function applyUpdates(n) {
|
|
|
27
27
|
console.error(`Invalid SHA format: ${e.latestSha}`);
|
|
28
28
|
continue;
|
|
29
29
|
}
|
|
30
|
-
let a =
|
|
31
|
-
i = i.replace(
|
|
30
|
+
let a = String.raw`['"]?\buses\b['"]?\s*:\s*`, o = String.raw`(?:^[^\S\n]*(?:-[^\S\n]*)?|[{\[,][^\S\n]*)` + a, s = new RegExp(String.raw`(?<prefix>${o})` + String.raw`(?<quote>['"]?)` + String.raw`(?<name>${n})@${r}` + String.raw`\k<quote>` + String.raw`(?<after>[ \t\]}{,]*)` + String.raw`(?<comment>[^\S\r\n]*#[^\r\n]*)?`, "gm");
|
|
31
|
+
i = i.replace(s, (t, ...n) => {
|
|
32
|
+
let i = n.at(-3), a = n.at(-2), o = n.at(-1), s = a.indexOf("\n", i + t.length), c = (s === -1 ? a.slice(i + t.length) : a.slice(i + t.length, s)).trim().length > 0, l = o.after.endsWith(" ") ? "" : " ", u = c && !o.comment && r !== "" ? "" : `${l}# ${e.latestVersion}`;
|
|
33
|
+
return `${`${o.prefix}${o.quote}${o.name}`}@${`${e.latestSha}${o.quote}${o.after}${u}`}`;
|
|
34
|
+
});
|
|
32
35
|
}
|
|
33
36
|
await writeFile(n, i, "utf8");
|
|
34
37
|
});
|
|
@@ -39,14 +39,14 @@ async function promptUpdateSelection(l, g = {}) {
|
|
|
39
39
|
display: a
|
|
40
40
|
};
|
|
41
41
|
})), C = [], w = stripAnsi("Action").length, T = stripAnsi("Current").length, E = stripAnsi("Job").length, D = 0, O = !1;
|
|
42
|
-
for (let [a,
|
|
43
|
-
let
|
|
44
|
-
if (w = Math.max(w,
|
|
45
|
-
let
|
|
46
|
-
D = Math.max(D, stripAnsi(
|
|
42
|
+
for (let [a, l] of b.entries()) {
|
|
43
|
+
let u = l.action.name, d = S[a], f = d.display, p = l.action.job ?? "–";
|
|
44
|
+
if (w = Math.max(w, u.length), T = Math.max(T, stripAnsi(f).length, d.versionForPadding && d.shortSha ? stripAnsi(`${padString(d.versionForPadding, D + 1)}${pc.gray(`(${d.shortSha})`)}`).length : 0), E = Math.max(E, p.length), l.latestVersion) {
|
|
45
|
+
let s = formatVersion(l.latestVersion, S[a]?.effectiveForDiff ?? l.currentVersion);
|
|
46
|
+
D = Math.max(D, stripAnsi(s).length);
|
|
47
47
|
}
|
|
48
|
-
let
|
|
49
|
-
|
|
48
|
+
let m = S[a]?.versionForPadding;
|
|
49
|
+
m && (D = Math.max(D, stripAnsi(m).length)), l.publishedAt && (O = !0);
|
|
50
50
|
}
|
|
51
51
|
let k = Math.max(w, MIN_ACTION_WIDTH), A = Math.max(T, MIN_CURRENT_WIDTH), j = Math.max(E, MIN_JOB_WIDTH), M = Math.min(D, MAX_VERSION_WIDTH), N = M + 1 + 9, P = y && O ? 6 : 0, F = [...x.keys()].toSorted();
|
|
52
52
|
for (let [a, o] of F.entries()) {
|
package/dist/package.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const version = "1.
|
|
1
|
+
const version = "1.8.0";
|
|
2
2
|
export { version };
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { GitHubAction } from './github-action';
|
|
2
2
|
/** Update information for a GitHub Action. */
|
|
3
3
|
export interface ActionUpdate {
|
|
4
|
+
/** Reason for skipping the update check. */
|
|
5
|
+
skipReason?: 'unknown' | 'branch'
|
|
6
|
+
|
|
4
7
|
/** Current version string. */
|
|
5
8
|
currentVersion: string | null
|
|
6
9
|
|
|
7
10
|
/** Latest available version. */
|
|
8
11
|
latestVersion: string | null
|
|
9
12
|
|
|
13
|
+
/** Status of the check for this action. */
|
|
14
|
+
status?: 'skipped' | 'ok'
|
|
15
|
+
|
|
10
16
|
/** SHA hash of the latest version. */
|
|
11
17
|
latestSha: string | null
|
|
12
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "actions-up",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "Interactive CLI tool to update GitHub Actions to latest versions with SHA pinning",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"github-actions",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"nanospinner": "^1.2.2",
|
|
42
42
|
"picocolors": "^1.1.1",
|
|
43
43
|
"semver": "^7.7.3",
|
|
44
|
-
"yaml": "^2.8.
|
|
44
|
+
"yaml": "^2.8.2"
|
|
45
45
|
},
|
|
46
46
|
"engines": {
|
|
47
47
|
"node": "^18.0.0 || >=20.0.0"
|
package/readme.md
CHANGED
|
@@ -131,6 +131,10 @@ By default, Actions Up scans the `.github` directory. You can specify a differen
|
|
|
131
131
|
npx actions-up --dir .gitea
|
|
132
132
|
```
|
|
133
133
|
|
|
134
|
+
### Branch References
|
|
135
|
+
|
|
136
|
+
By default, actions pinned to branch refs (e.g., `@main`, `@release/v1`) are skipped to avoid changing intentionally floating references. Skipped entries are listed in the output. To include them in update checks, pass `--include-branches`.
|
|
137
|
+
|
|
134
138
|
## GitHub Actions Integration
|
|
135
139
|
|
|
136
140
|
### Automated PR Checks
|