actions-up 1.3.1 → 1.4.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 +41 -41
- package/dist/core/api/check-updates.js +135 -179
- package/dist/core/api/create-github-client.js +28 -29
- package/dist/core/api/get-all-releases.js +20 -27
- package/dist/core/api/get-all-tags.js +5 -7
- package/dist/core/api/get-latest-release.js +16 -19
- package/dist/core/api/get-reference-type.js +6 -12
- package/dist/core/api/get-tag-info.js +47 -76
- package/dist/core/api/get-tag-sha.js +12 -22
- package/dist/core/api/internal-rate-limit-error.js +3 -4
- package/dist/core/api/make-request.js +18 -21
- package/dist/core/api/resolve-github-token-sync.js +20 -26
- package/dist/core/api/update-rate-limit-info.js +7 -7
- package/dist/core/ast/guards/has-range.js +2 -2
- package/dist/core/ast/guards/is-node.js +2 -2
- package/dist/core/ast/guards/is-pair.js +2 -2
- package/dist/core/ast/guards/is-scalar.js +2 -2
- package/dist/core/ast/guards/is-yaml-map.js +2 -2
- package/dist/core/ast/guards/is-yaml-sequence.js +2 -2
- package/dist/core/ast/scanners/scan-composite-action-ast.js +9 -11
- package/dist/core/ast/scanners/scan-workflow-ast.js +12 -14
- package/dist/core/ast/update/apply-updates.js +24 -27
- package/dist/core/ast/utils/extract-uses-from-steps.js +12 -14
- package/dist/core/ast/utils/find-map-pair.js +2 -5
- package/dist/core/ast/utils/get-line-number.js +4 -4
- package/dist/core/constants.js +1 -3
- package/dist/core/filters/parse-exclude-patterns.d.ts +17 -0
- package/dist/core/filters/parse-exclude-patterns.js +23 -0
- package/dist/core/fs/is-yaml-file.js +2 -2
- package/dist/core/fs/read-yaml-document.js +4 -5
- package/dist/core/ignore/should-ignore.d.ts +23 -0
- package/dist/core/ignore/should-ignore.js +14 -0
- package/dist/core/interactive/format-version.js +16 -30
- package/dist/core/interactive/pad-string.js +5 -6
- package/dist/core/interactive/prompt-update-selection.js +106 -163
- package/dist/core/interactive/strip-ansi.js +10 -17
- package/dist/core/parsing/parse-action-reference.js +23 -23
- package/dist/core/scan-action-file.js +3 -3
- package/dist/core/scan-github-actions.js +87 -136
- package/dist/core/scan-workflow-file.js +3 -3
- package/dist/core/schema/composite/is-composite-action-runs.js +2 -4
- package/dist/core/schema/composite/is-composite-action-structure.js +4 -4
- package/dist/core/schema/workflow/is-workflow-structure.js +4 -4
- package/dist/package.js +1 -1
- package/package.json +1 -1
- package/readme.md +55 -8
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { promptUpdateSelection } from "../core/interactive/prompt-update-selection.js";
|
|
2
2
|
import { applyUpdates } from "../core/ast/update/apply-updates.js";
|
|
3
|
+
import { shouldIgnore } from "../core/ignore/should-ignore.js";
|
|
3
4
|
import { checkUpdates } from "../core/api/check-updates.js";
|
|
4
5
|
import { scanGitHubActions } from "../core/scan-github-actions.js";
|
|
5
6
|
import "../core/index.js";
|
|
@@ -9,65 +10,64 @@ import "node:worker_threads";
|
|
|
9
10
|
import pc from "picocolors";
|
|
10
11
|
import cac from "cac";
|
|
11
12
|
function run() {
|
|
12
|
-
let
|
|
13
|
-
|
|
13
|
+
let l = cac("actions-up");
|
|
14
|
+
l.help().version(version).option("--dry-run", "Preview changes without applying them").option("--exclude <regex>", "Exclude actions by regex (repeatable)").option("--yes, -y", "Skip all confirmations").command("", "Update GitHub Actions").action(async (s) => {
|
|
14
15
|
console.info(pc.cyan("\n🚀 Actions Up!\n"));
|
|
15
|
-
let
|
|
16
|
+
let c = createSpinner("Scanning GitHub Actions...").start();
|
|
16
17
|
try {
|
|
17
|
-
let
|
|
18
|
-
|
|
19
|
-
let totalWorkflows = scanResult.workflows.size;
|
|
20
|
-
let totalCompositeActions = scanResult.compositeActions.size;
|
|
21
|
-
spinner.success(`Found ${pc.yellow(totalActions)} actions in ${pc.yellow(totalWorkflows)} workflows and ${pc.yellow(totalCompositeActions)} composite actions`);
|
|
22
|
-
if (totalActions === 0) {
|
|
18
|
+
let l = await scanGitHubActions(process.cwd()), u = l.actions.length, d = l.workflows.size, f = l.compositeActions.size;
|
|
19
|
+
if (c.success(`Found ${pc.yellow(u)} actions in ${pc.yellow(d)} workflows and ${pc.yellow(f)} composite actions`), u === 0) {
|
|
23
20
|
console.info(pc.green("\n✨ No GitHub Actions found in this repository"));
|
|
24
21
|
return;
|
|
25
22
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
let
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
let p = l.actions, m = [];
|
|
24
|
+
Array.isArray(s.exclude) ? m.push(...s.exclude) : typeof s.exclude == "string" && m.push(s.exclude);
|
|
25
|
+
let h = m.flatMap((e) => e.split(",")).map((e) => e.trim()).filter(Boolean);
|
|
26
|
+
if (h.length > 0) {
|
|
27
|
+
let { parseExcludePatterns: e } = await import("../core/filters/parse-exclude-patterns.js"), a = e(h);
|
|
28
|
+
a.length > 0 && (p = p.filter((e) => {
|
|
29
|
+
let { name: o } = e;
|
|
30
|
+
for (let e of a) if (e.test(o)) return !1;
|
|
31
|
+
return !0;
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
if (c = createSpinner("Checking for updates...").start(), p.length === 0) {
|
|
35
|
+
c.success("No actions to check after excludes"), console.info(pc.green("\n✨ Nothing to check after excludes\n"));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
let g = await checkUpdates(p, process.env.GITHUB_TOKEN), _ = [];
|
|
39
|
+
await Promise.all(g.map(async (e) => {
|
|
40
|
+
await shouldIgnore(e.action.file, e.action.line) || _.push(e);
|
|
41
|
+
}));
|
|
42
|
+
let v = _.filter((e) => e.hasUpdate), y = v.filter((e) => e.isBreaking);
|
|
43
|
+
if (v.length === 0) {
|
|
44
|
+
c.success("All actions are up to date!"), console.info(pc.green("\n✨ Everything is already at the latest version!\n"));
|
|
33
45
|
return;
|
|
34
46
|
}
|
|
35
|
-
|
|
36
|
-
if (options.dryRun) {
|
|
47
|
+
if (c.success(`Found ${pc.yellow(v.length)} updates available${y.length > 0 ? ` (${pc.redBright(y.length)} breaking)` : ""}`), s.dryRun) {
|
|
37
48
|
console.info(pc.yellow("\n📋 Dry Run - No changes will be made\n"));
|
|
38
|
-
for (let
|
|
39
|
-
console.info(pc.gray(`\n${
|
|
49
|
+
for (let e of v) 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`);
|
|
50
|
+
console.info(pc.gray(`\n${v.length} actions would be updated\n`));
|
|
40
51
|
return;
|
|
41
52
|
}
|
|
42
|
-
if (
|
|
43
|
-
let
|
|
44
|
-
if (
|
|
53
|
+
if (s.yes) {
|
|
54
|
+
let e = v.filter((e) => e.latestSha);
|
|
55
|
+
if (e.length === 0) {
|
|
45
56
|
console.info(pc.yellow("\n⚠️ No actions with SHA available for update\n"));
|
|
46
57
|
return;
|
|
47
58
|
}
|
|
48
|
-
console.info(pc.yellow(`\n🔄 Updating ${
|
|
49
|
-
await applyUpdates(toUpdate);
|
|
50
|
-
console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
59
|
+
console.info(pc.yellow(`\n🔄 Updating ${e.length} actions...\n`)), await applyUpdates(e), console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
51
60
|
} else {
|
|
52
|
-
let
|
|
53
|
-
if (!
|
|
61
|
+
let o = await promptUpdateSelection(_);
|
|
62
|
+
if (!o || o.length === 0) {
|
|
54
63
|
console.info(pc.gray("\nNo updates applied"));
|
|
55
64
|
return;
|
|
56
65
|
}
|
|
57
|
-
console.info(pc.yellow(`\n🔄 Updating ${
|
|
58
|
-
await applyUpdates(selected);
|
|
59
|
-
console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
66
|
+
console.info(pc.yellow(`\n🔄 Updating ${o.length} selected actions...\n`)), await applyUpdates(o), console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
60
67
|
}
|
|
61
|
-
} catch (
|
|
62
|
-
|
|
63
|
-
if (error instanceof Error && error.name === "GitHubRateLimitError") {
|
|
64
|
-
console.error(pc.yellow("\n⚠️ Rate Limit Exceeded\n"));
|
|
65
|
-
console.error(error.message);
|
|
66
|
-
console.error(pc.gray("\nExample: GITHUB_TOKEN=ghp_xxxx actions-up\n"));
|
|
67
|
-
} else console.error(pc.redBright("\nError:"), error instanceof Error ? error.message : String(error));
|
|
68
|
-
process.exit(1);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
c.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);
|
|
69
70
|
}
|
|
70
|
-
});
|
|
71
|
-
cli.parse();
|
|
71
|
+
}), l.parse();
|
|
72
72
|
}
|
|
73
73
|
export { run };
|
|
@@ -1,231 +1,187 @@
|
|
|
1
1
|
import { createGitHubClient } from "./create-github-client.js";
|
|
2
2
|
import semver from "semver";
|
|
3
|
-
async function checkUpdates(
|
|
4
|
-
let
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
group.push(action);
|
|
11
|
-
uniqueActions.set(action.name, group);
|
|
3
|
+
async function checkUpdates(r, a) {
|
|
4
|
+
let c = createGitHubClient(a), l = r.filter((e) => e.type === "external");
|
|
5
|
+
if (l.length === 0) return [];
|
|
6
|
+
let u = /* @__PURE__ */ new Map();
|
|
7
|
+
for (let e of l) {
|
|
8
|
+
let n = u.get(e.name) ?? [];
|
|
9
|
+
n.push(e), u.set(e.name, n);
|
|
12
10
|
}
|
|
13
|
-
let
|
|
11
|
+
let d = {
|
|
14
12
|
rateLimitError: null,
|
|
15
|
-
rateLimitHit:
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
if (sharedState.rateLimitHit) return [...results, {
|
|
13
|
+
rateLimitHit: !1
|
|
14
|
+
}, f = await [...u.keys()].reduce((e, r) => e.then(async (e) => {
|
|
15
|
+
if (d.rateLimitHit) return [...e, {
|
|
19
16
|
version: null,
|
|
20
|
-
actionName,
|
|
17
|
+
actionName: r,
|
|
21
18
|
sha: null
|
|
22
19
|
}];
|
|
23
|
-
let
|
|
24
|
-
if (
|
|
20
|
+
let i = r.split("/");
|
|
21
|
+
if (i.length < 2) return [...e, {
|
|
25
22
|
version: null,
|
|
26
|
-
actionName,
|
|
23
|
+
actionName: r,
|
|
27
24
|
sha: null
|
|
28
25
|
}];
|
|
29
|
-
let [
|
|
30
|
-
if (!
|
|
26
|
+
let [a, l] = i;
|
|
27
|
+
if (!a || !l) return [...e, {
|
|
31
28
|
version: null,
|
|
32
|
-
actionName,
|
|
29
|
+
actionName: r,
|
|
33
30
|
sha: null
|
|
34
31
|
}];
|
|
35
32
|
try {
|
|
36
|
-
let
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
let release = await client.getLatestRelease(owner, repo);
|
|
47
|
-
if (!release) {
|
|
48
|
-
let allReleases = await client.getAllReleases(owner, repo, 1);
|
|
49
|
-
let stableRelease = allReleases.find((currentRelease) => !currentRelease.isPrerelease);
|
|
50
|
-
release = stableRelease ?? allReleases[0] ?? null;
|
|
33
|
+
let i = u.get(r)[0]?.version;
|
|
34
|
+
if (i && !isSha(i) && !isSemverLike(i) && await c.getRefType(a, l, i) === "branch") return [...e, {
|
|
35
|
+
version: null,
|
|
36
|
+
actionName: r,
|
|
37
|
+
sha: null
|
|
38
|
+
}];
|
|
39
|
+
let d = await c.getLatestRelease(a, l);
|
|
40
|
+
if (!d) {
|
|
41
|
+
let e = await c.getAllReleases(a, l, 1);
|
|
42
|
+
d = e.find((e) => !e.isPrerelease) ?? e[0] ?? null;
|
|
51
43
|
}
|
|
52
|
-
if (
|
|
53
|
-
let { version, sha } =
|
|
54
|
-
let considerTags = false;
|
|
44
|
+
if (d) {
|
|
45
|
+
let { version: i, sha: o } = d, u = !1;
|
|
55
46
|
{
|
|
56
|
-
let
|
|
57
|
-
|
|
58
|
-
let majorOnly = hasVersion && /^v?\d+$/u.test(version.trim());
|
|
59
|
-
let valid = semver.valid(normalized);
|
|
60
|
-
considerTags = !hasVersion || majorOnly || !valid;
|
|
47
|
+
let e = normalizeVersion(i), r = !!(i && i.trim() !== ""), a = r && /^v?\d+$/u.test(i.trim()), o = semver.valid(e);
|
|
48
|
+
u = !r || a || !o;
|
|
61
49
|
}
|
|
62
|
-
if (
|
|
63
|
-
let
|
|
64
|
-
if (
|
|
65
|
-
let
|
|
66
|
-
v: semver.valid(normalizeVersion(
|
|
67
|
-
raw:
|
|
50
|
+
if (u) {
|
|
51
|
+
let o = await c.getAllTags(a, l, 30);
|
|
52
|
+
if (o.length > 0) {
|
|
53
|
+
let u = o.filter((e) => isSemverLike(e.tag)).map((e) => ({
|
|
54
|
+
v: semver.valid(normalizeVersion(e.tag)),
|
|
55
|
+
raw: e
|
|
68
56
|
}));
|
|
69
|
-
if (
|
|
70
|
-
|
|
71
|
-
let
|
|
72
|
-
if (
|
|
73
|
-
let
|
|
74
|
-
|
|
75
|
-
return bSpecific - aSpecific;
|
|
57
|
+
if (u.length > 0) {
|
|
58
|
+
u.sort((e, r) => {
|
|
59
|
+
let i = semver.rcompare(e.v, r.v);
|
|
60
|
+
if (i !== 0) return i;
|
|
61
|
+
let a = /\d+\.\d+/u.test(e.raw.tag) ? 1 : 0;
|
|
62
|
+
return (/\d+\.\d+/u.test(r.raw.tag) ? 1 : 0) - a;
|
|
76
63
|
});
|
|
77
|
-
let
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (!tagSha && tagVersion) try {
|
|
83
|
-
tagSha = await client.getTagSha(owner, repo, tagVersion);
|
|
64
|
+
let o = u[0].raw, s = semver.valid(normalizeVersion(i) ?? void 0);
|
|
65
|
+
if (!s || semver.gt(u[0].v, s) || semver.eq(u[0].v, s) && /\d+\.\d+/u.test(o.tag)) {
|
|
66
|
+
let n = o.tag, i = o.sha?.length ? o.sha : null;
|
|
67
|
+
if (!i && n) try {
|
|
68
|
+
i = await c.getTagSha(a, l, n);
|
|
84
69
|
} catch {}
|
|
85
|
-
return [...
|
|
86
|
-
version:
|
|
87
|
-
sha:
|
|
88
|
-
actionName
|
|
70
|
+
return [...e, {
|
|
71
|
+
version: n,
|
|
72
|
+
sha: i,
|
|
73
|
+
actionName: r
|
|
89
74
|
}];
|
|
90
75
|
}
|
|
91
76
|
}
|
|
92
77
|
}
|
|
93
78
|
}
|
|
94
|
-
if (!
|
|
95
|
-
|
|
79
|
+
if (!o && i) try {
|
|
80
|
+
o = await c.getTagSha(a, l, i);
|
|
96
81
|
} catch {}
|
|
97
|
-
return [...
|
|
98
|
-
actionName,
|
|
99
|
-
version,
|
|
100
|
-
sha
|
|
82
|
+
return [...e, {
|
|
83
|
+
actionName: r,
|
|
84
|
+
version: i,
|
|
85
|
+
sha: o
|
|
101
86
|
}];
|
|
102
87
|
}
|
|
103
|
-
let
|
|
104
|
-
if (
|
|
105
|
-
let
|
|
106
|
-
v: semver.valid(normalizeVersion(
|
|
107
|
-
raw:
|
|
108
|
-
}));
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
best = semverCandidates[0].raw;
|
|
119
|
-
} else best = tags[0];
|
|
120
|
-
let version = best.tag;
|
|
121
|
-
let sha = best.sha?.length ? best.sha : null;
|
|
122
|
-
if (!sha && version) try {
|
|
123
|
-
sha = await client.getTagSha(owner, repo, version);
|
|
88
|
+
let f = await c.getAllTags(a, l, 30);
|
|
89
|
+
if (f.length > 0) {
|
|
90
|
+
let i = f.filter((e) => isSemverLike(e.tag)).map((e) => ({
|
|
91
|
+
v: semver.valid(normalizeVersion(e.tag)),
|
|
92
|
+
raw: e
|
|
93
|
+
})), o;
|
|
94
|
+
i.length > 0 ? (i.sort((e, r) => {
|
|
95
|
+
let i = semver.rcompare(e.v, r.v);
|
|
96
|
+
if (i !== 0) return i;
|
|
97
|
+
let a = /\d+\.\d+/u.test(e.raw.tag) ? 1 : 0;
|
|
98
|
+
return (/\d+\.\d+/u.test(r.raw.tag) ? 1 : 0) - a;
|
|
99
|
+
}), o = i[0].raw) : o = f[0];
|
|
100
|
+
let u = o.tag, d = o.sha?.length ? o.sha : null;
|
|
101
|
+
if (!d && u) try {
|
|
102
|
+
d = await c.getTagSha(a, l, u);
|
|
124
103
|
} catch {}
|
|
125
|
-
return [...
|
|
126
|
-
actionName,
|
|
127
|
-
version,
|
|
128
|
-
sha
|
|
104
|
+
return [...e, {
|
|
105
|
+
actionName: r,
|
|
106
|
+
version: u,
|
|
107
|
+
sha: d
|
|
129
108
|
}];
|
|
130
109
|
}
|
|
131
|
-
return [...
|
|
110
|
+
return [...e, {
|
|
132
111
|
version: null,
|
|
133
|
-
actionName,
|
|
112
|
+
actionName: r,
|
|
134
113
|
sha: null
|
|
135
114
|
}];
|
|
136
|
-
} catch (
|
|
137
|
-
|
|
138
|
-
sharedState.rateLimitHit = true;
|
|
139
|
-
sharedState.rateLimitError = error;
|
|
140
|
-
return [...results, {
|
|
141
|
-
version: null,
|
|
142
|
-
actionName,
|
|
143
|
-
sha: null
|
|
144
|
-
}];
|
|
145
|
-
}
|
|
146
|
-
console.warn(`Failed to check ${actionName}:`, error);
|
|
147
|
-
return [...results, {
|
|
115
|
+
} catch (n) {
|
|
116
|
+
return n instanceof Error && n.name === "GitHubRateLimitError" ? (d.rateLimitHit = !0, d.rateLimitError = n, [...e, {
|
|
148
117
|
version: null,
|
|
149
|
-
actionName,
|
|
118
|
+
actionName: r,
|
|
150
119
|
sha: null
|
|
151
|
-
}]
|
|
120
|
+
}]) : (console.warn(`Failed to check ${r}:`, n), [...e, {
|
|
121
|
+
version: null,
|
|
122
|
+
actionName: r,
|
|
123
|
+
sha: null
|
|
124
|
+
}]);
|
|
152
125
|
}
|
|
153
126
|
}), Promise.resolve([]));
|
|
154
|
-
if (
|
|
155
|
-
let
|
|
156
|
-
|
|
157
|
-
throw error;
|
|
127
|
+
if (d.rateLimitError) {
|
|
128
|
+
let e = !!(a ?? process.env.GITHUB_TOKEN), n = `${d.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"}`, r = Error(n);
|
|
129
|
+
throw r.name = "GitHubRateLimitError", r;
|
|
158
130
|
}
|
|
159
|
-
let
|
|
160
|
-
for (let
|
|
161
|
-
version:
|
|
162
|
-
sha:
|
|
131
|
+
let p = /* @__PURE__ */ new Map();
|
|
132
|
+
for (let e of f) p.set(e.actionName, {
|
|
133
|
+
version: e.version,
|
|
134
|
+
sha: e.sha
|
|
163
135
|
});
|
|
164
|
-
let
|
|
165
|
-
for (let
|
|
166
|
-
let
|
|
167
|
-
|
|
168
|
-
else updates.push(createUpdate(action, null, null));
|
|
136
|
+
let m = [];
|
|
137
|
+
for (let e of l) {
|
|
138
|
+
let n = p.get(e.name);
|
|
139
|
+
n ? m.push(createUpdate(e, n.version, n.sha)) : m.push(createUpdate(e, null, null));
|
|
169
140
|
}
|
|
170
|
-
return
|
|
141
|
+
return m;
|
|
171
142
|
}
|
|
172
|
-
function createUpdate(
|
|
173
|
-
let
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
let current = semver.valid(currentVersion);
|
|
182
|
-
let latest = semver.valid(normalized);
|
|
183
|
-
if (current && latest) {
|
|
184
|
-
hasUpdate = semver.lt(current, latest);
|
|
185
|
-
if (hasUpdate) {
|
|
186
|
-
let currentMajor = semver.major(current);
|
|
187
|
-
let latestMajor = semver.major(latest);
|
|
188
|
-
isBreaking = latestMajor > currentMajor;
|
|
189
|
-
}
|
|
190
|
-
if (!hasUpdate && semver.eq(current, latest) && !isSha(action.version) && latestSha) {
|
|
191
|
-
hasUpdate = true;
|
|
192
|
-
isBreaking = false;
|
|
143
|
+
function createUpdate(e, r, i) {
|
|
144
|
+
let s = normalizeVersion(e.version ?? ""), c = r ? normalizeVersion(r) : null, l = !1, u = !1;
|
|
145
|
+
if (s && isSha(s)) i ? l = !compareSha(s, i) : c && (l = !0);
|
|
146
|
+
else if (s && c) {
|
|
147
|
+
let r = semver.valid(s), a = semver.valid(c);
|
|
148
|
+
if (r && a) {
|
|
149
|
+
if (l = semver.lt(r, a), l) {
|
|
150
|
+
let e = semver.major(r);
|
|
151
|
+
u = semver.major(a) > e;
|
|
193
152
|
}
|
|
194
|
-
|
|
153
|
+
!l && semver.eq(r, a) && !isSha(e.version) && i && (l = !0, u = !1);
|
|
154
|
+
} else s !== c && (l = !0);
|
|
195
155
|
}
|
|
196
156
|
return {
|
|
197
|
-
currentVersion:
|
|
198
|
-
latestVersion,
|
|
199
|
-
isBreaking,
|
|
200
|
-
latestSha,
|
|
201
|
-
hasUpdate,
|
|
202
|
-
action
|
|
157
|
+
currentVersion: e.version ?? "unknown",
|
|
158
|
+
latestVersion: r,
|
|
159
|
+
isBreaking: u,
|
|
160
|
+
latestSha: i,
|
|
161
|
+
hasUpdate: l,
|
|
162
|
+
action: e
|
|
203
163
|
};
|
|
204
164
|
}
|
|
205
|
-
function compareSha(
|
|
206
|
-
if (!
|
|
207
|
-
let
|
|
208
|
-
|
|
209
|
-
let minLength = Math.min(normalized1.length, normalized2.length);
|
|
210
|
-
if (minLength < 7) return false;
|
|
211
|
-
return normalized1.slice(0, Math.max(0, minLength)).toLowerCase() === normalized2.slice(0, Math.max(0, minLength)).toLowerCase();
|
|
165
|
+
function compareSha(e, n) {
|
|
166
|
+
if (!e || !n) return !1;
|
|
167
|
+
let r = e.replace(/^v/u, ""), i = n.replace(/^v/u, ""), a = Math.min(r.length, i.length);
|
|
168
|
+
return a < 7 ? !1 : r.slice(0, Math.max(0, a)).toLowerCase() === i.slice(0, Math.max(0, a)).toLowerCase();
|
|
212
169
|
}
|
|
213
|
-
function normalizeVersion(
|
|
214
|
-
if (!
|
|
215
|
-
let
|
|
216
|
-
if (/^[0-9a-f]{7,40}$/iu.test(
|
|
217
|
-
let
|
|
218
|
-
|
|
219
|
-
return version;
|
|
170
|
+
function normalizeVersion(e) {
|
|
171
|
+
if (!e) return null;
|
|
172
|
+
let r = e.replace(/^v/u, "");
|
|
173
|
+
if (/^[0-9a-f]{7,40}$/iu.test(r)) return e;
|
|
174
|
+
let i = semver.coerce(r);
|
|
175
|
+
return i ? i.version : e;
|
|
220
176
|
}
|
|
221
|
-
function isSha(
|
|
222
|
-
if (!
|
|
223
|
-
let
|
|
224
|
-
return /^[0-9a-f]{7,40}$/iu.test(
|
|
177
|
+
function isSha(e) {
|
|
178
|
+
if (!e) return !1;
|
|
179
|
+
let n = e.replace(/^v/u, "");
|
|
180
|
+
return /^[0-9a-f]{7,40}$/iu.test(n);
|
|
225
181
|
}
|
|
226
|
-
function isSemverLike(
|
|
227
|
-
if (!
|
|
228
|
-
let
|
|
229
|
-
return /^v?\d+(?:\.\d+){0,2}$/u.test(
|
|
182
|
+
function isSemverLike(e) {
|
|
183
|
+
if (!e) return !1;
|
|
184
|
+
let n = e.trim();
|
|
185
|
+
return /^v?\d+(?:\.\d+){0,2}$/u.test(n);
|
|
230
186
|
}
|
|
231
187
|
export { checkUpdates };
|
|
@@ -5,50 +5,49 @@ import { getAllReleases } from "./get-all-releases.js";
|
|
|
5
5
|
import { getTagInfo } from "./get-tag-info.js";
|
|
6
6
|
import { getAllTags } from "./get-all-tags.js";
|
|
7
7
|
import { getTagSha } from "./get-tag-sha.js";
|
|
8
|
-
function createGitHubClient(
|
|
9
|
-
let
|
|
10
|
-
let context = {
|
|
8
|
+
function createGitHubClient(s) {
|
|
9
|
+
let c = s ?? process.env.GITHUB_TOKEN ?? resolveGitHubTokenSync(), l = {
|
|
11
10
|
caches: {
|
|
12
11
|
refType: /* @__PURE__ */ new Map(),
|
|
13
12
|
tagInfo: /* @__PURE__ */ new Map(),
|
|
14
13
|
tagSha: /* @__PURE__ */ new Map()
|
|
15
14
|
},
|
|
16
|
-
rateLimitRemaining:
|
|
15
|
+
rateLimitRemaining: c ? 5e3 : 60,
|
|
17
16
|
baseUrl: "https://api.github.com",
|
|
18
17
|
rateLimitReset: /* @__PURE__ */ new Date(),
|
|
19
|
-
token:
|
|
18
|
+
token: c
|
|
20
19
|
};
|
|
21
20
|
return {
|
|
22
21
|
getRateLimitStatus: () => ({
|
|
23
|
-
remaining:
|
|
24
|
-
resetAt:
|
|
22
|
+
remaining: l.rateLimitRemaining,
|
|
23
|
+
resetAt: l.rateLimitReset
|
|
25
24
|
}),
|
|
26
|
-
getRefType: (
|
|
27
|
-
reference,
|
|
28
|
-
owner,
|
|
29
|
-
repo
|
|
25
|
+
getRefType: (e, a, o) => getReferenceType(l, {
|
|
26
|
+
reference: o,
|
|
27
|
+
owner: e,
|
|
28
|
+
repo: a
|
|
30
29
|
}),
|
|
31
|
-
shouldWaitForRateLimit: (
|
|
32
|
-
getAllReleases: (
|
|
33
|
-
owner,
|
|
34
|
-
limit,
|
|
35
|
-
repo
|
|
30
|
+
shouldWaitForRateLimit: (e = 100) => l.rateLimitRemaining < e,
|
|
31
|
+
getAllReleases: (e, i, a) => getAllReleases(l, {
|
|
32
|
+
owner: e,
|
|
33
|
+
limit: a,
|
|
34
|
+
repo: i
|
|
36
35
|
}),
|
|
37
|
-
getAllTags: (
|
|
38
|
-
owner,
|
|
39
|
-
limit,
|
|
40
|
-
repo
|
|
36
|
+
getAllTags: (e, i, a) => getAllTags(l, {
|
|
37
|
+
owner: e,
|
|
38
|
+
limit: a,
|
|
39
|
+
repo: i
|
|
41
40
|
}),
|
|
42
|
-
getTagInfo: (
|
|
43
|
-
owner,
|
|
44
|
-
repo,
|
|
45
|
-
tag
|
|
41
|
+
getTagInfo: (e, i, a) => getTagInfo(l, {
|
|
42
|
+
owner: e,
|
|
43
|
+
repo: i,
|
|
44
|
+
tag: a
|
|
46
45
|
}),
|
|
47
|
-
getLatestRelease: (
|
|
48
|
-
getTagSha: (
|
|
49
|
-
owner,
|
|
50
|
-
repo,
|
|
51
|
-
tag
|
|
46
|
+
getLatestRelease: (e, i) => getLatestRelease(l, e, i),
|
|
47
|
+
getTagSha: (e, i, a) => getTagSha(l, {
|
|
48
|
+
owner: e,
|
|
49
|
+
repo: i,
|
|
50
|
+
tag: a
|
|
52
51
|
})
|
|
53
52
|
};
|
|
54
53
|
}
|
|
@@ -1,35 +1,28 @@
|
|
|
1
1
|
import { makeRequest } from "./make-request.js";
|
|
2
2
|
import { GitHubRateLimitError } from "./internal-rate-limit-error.js";
|
|
3
|
-
async function getAllReleases(
|
|
3
|
+
async function getAllReleases(r, i) {
|
|
4
4
|
try {
|
|
5
|
-
let { limit = 10, owner, repo } =
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
isPrerelease: release.prerelease,
|
|
18
|
-
version: release.tag_name,
|
|
19
|
-
url: release.html_url,
|
|
20
|
-
sha
|
|
21
|
-
});
|
|
22
|
-
i++;
|
|
5
|
+
let { limit: n = 10, owner: a, repo: o } = i, s = (await makeRequest(r, `/repos/${a}/${o}/releases?per_page=${n}`)).data, c = [], l = 0;
|
|
6
|
+
for (let e of s) {
|
|
7
|
+
let n = null;
|
|
8
|
+
l === 0 && e.tag_name && (n = isLikelySha(e.target_commitish) ? e.target_commitish : null), c.push({
|
|
9
|
+
publishedAt: new Date(e.published_at),
|
|
10
|
+
name: e.name ?? e.tag_name,
|
|
11
|
+
description: e.body ?? null,
|
|
12
|
+
isPrerelease: e.prerelease,
|
|
13
|
+
version: e.tag_name,
|
|
14
|
+
url: e.html_url,
|
|
15
|
+
sha: n
|
|
16
|
+
}), l++;
|
|
23
17
|
}
|
|
24
|
-
return
|
|
25
|
-
} catch (
|
|
26
|
-
|
|
27
|
-
throw error;
|
|
18
|
+
return c;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
throw e instanceof Error && e.message.includes("rate limit") ? new GitHubRateLimitError(r.rateLimitReset) : e;
|
|
28
21
|
}
|
|
29
22
|
}
|
|
30
|
-
function isLikelySha(
|
|
31
|
-
if (typeof
|
|
32
|
-
let
|
|
33
|
-
return /^[0-9a-f]{7,40}$/iu.test(
|
|
23
|
+
function isLikelySha(e) {
|
|
24
|
+
if (typeof e != "string" || e.trim() === "") return !1;
|
|
25
|
+
let n = e.replace(/^v/u, "");
|
|
26
|
+
return /^[0-9a-f]{7,40}$/iu.test(n);
|
|
34
27
|
}
|
|
35
28
|
export { getAllReleases };
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { makeRequest } from "./make-request.js";
|
|
2
|
-
async function getAllTags(
|
|
3
|
-
let { limit = 30, owner, repo } =
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
sha: tag.commit.sha,
|
|
8
|
-
tag: tag.name,
|
|
2
|
+
async function getAllTags(t, n) {
|
|
3
|
+
let { limit: r = 30, owner: i, repo: a } = n;
|
|
4
|
+
return (await makeRequest(t, `/repos/${i}/${a}/tags?per_page=${r}`)).data.map((e) => ({
|
|
5
|
+
sha: e.commit.sha,
|
|
6
|
+
tag: e.name,
|
|
9
7
|
message: null,
|
|
10
8
|
date: null
|
|
11
9
|
}));
|