actions-up 1.11.0 → 1.12.1
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.d.ts +3 -1
- package/dist/cli/index.js +84 -93
- package/dist/cli/merge-scan-results.d.ts +8 -0
- package/dist/cli/merge-scan-results.js +18 -0
- package/dist/cli/normalize-update-mode.d.ts +8 -0
- package/dist/cli/normalize-update-mode.js +6 -0
- package/dist/cli/print-mode-warning.d.ts +16 -0
- package/dist/cli/print-mode-warning.js +11 -0
- package/dist/cli/print-skipped-warning.d.ts +14 -0
- package/dist/cli/print-skipped-warning.js +10 -0
- package/dist/cli/resolve-scan-directories.d.ts +31 -0
- package/dist/cli/resolve-scan-directories.js +24 -0
- package/dist/core/api/check-updates.d.ts +4 -1
- package/dist/core/api/check-updates.js +119 -116
- package/dist/core/api/get-all-releases.d.ts +2 -1
- package/dist/core/api/get-compatible-update.d.ts +37 -0
- package/dist/core/api/get-compatible-update.js +40 -0
- package/dist/core/api/get-latest-release.d.ts +3 -3
- package/dist/core/ast/utils/extract-uses-from-steps.d.ts +12 -4
- package/dist/core/constants.d.ts +3 -1
- package/dist/core/fs/find-yaml-files-recursive.js +1 -1
- package/dist/core/interactive/prompt-update-selection.d.ts +3 -1
- package/dist/core/interactive/prompt-update-selection.js +9 -9
- package/dist/core/parsing/parse-action-reference.d.ts +16 -12
- package/dist/core/scan-github-actions.d.ts +4 -1
- package/dist/core/scan-github-actions.js +67 -68
- package/dist/core/scan-recursive.js +12 -14
- package/dist/core/versions/find-compatible-tag.d.ts +16 -0
- package/dist/core/versions/find-compatible-tag.js +27 -0
- package/dist/core/versions/get-update-level.d.ts +3 -1
- package/dist/core/versions/is-semver-like.d.ts +9 -0
- package/dist/core/versions/is-semver-like.js +4 -0
- package/dist/core/versions/normalize-version.d.ts +14 -0
- package/dist/core/versions/normalize-version.js +9 -0
- package/dist/package.js +1 -1
- package/dist/types/action-update.d.ts +30 -10
- package/dist/types/composite-action-runs.d.ts +12 -4
- package/dist/types/composite-action-step.d.ts +24 -8
- package/dist/types/composite-action-structure.d.ts +21 -7
- package/dist/types/github-action.d.ts +27 -9
- package/dist/types/github-client-context.d.ts +24 -8
- package/dist/types/github-client.d.ts +24 -8
- package/dist/types/release-info.d.ts +24 -8
- package/dist/types/scan-result.d.ts +12 -4
- package/dist/types/tag-info.d.ts +15 -5
- package/dist/types/update-mode.d.ts +3 -1
- package/dist/types/workflow-job.d.ts +27 -9
- package/dist/types/workflow-step.d.ts +21 -7
- package/dist/types/workflow-structure.d.ts +15 -5
- package/package.json +3 -8
- package/readme.md +53 -18
package/dist/cli/index.d.ts
CHANGED
package/dist/cli/index.js
CHANGED
|
@@ -1,143 +1,134 @@
|
|
|
1
1
|
import { readInlineVersionComment } from "../core/versions/read-inline-version-comment.js";
|
|
2
|
-
import { GITHUB_DIRECTORY } from "../core/constants.js";
|
|
3
2
|
import { isSha } from "../core/versions/is-sha.js";
|
|
4
3
|
import { promptUpdateSelection } from "../core/interactive/prompt-update-selection.js";
|
|
4
|
+
import { getCompatibleUpdate } from "../core/api/get-compatible-update.js";
|
|
5
|
+
import { createGitHubClient } from "../core/api/create-github-client.js";
|
|
6
|
+
import { resolveScanDirectories } from "./resolve-scan-directories.js";
|
|
5
7
|
import { getUpdateLevel } from "../core/versions/get-update-level.js";
|
|
6
8
|
import { applyUpdates } from "../core/ast/update/apply-updates.js";
|
|
9
|
+
import { printSkippedWarning } from "./print-skipped-warning.js";
|
|
10
|
+
import { normalizeUpdateMode } from "./normalize-update-mode.js";
|
|
7
11
|
import { shouldIgnore } from "../core/ignore/should-ignore.js";
|
|
8
12
|
import { checkUpdates } from "../core/api/check-updates.js";
|
|
13
|
+
import { mergeScanResults } from "./merge-scan-results.js";
|
|
14
|
+
import { printModeWarning } from "./print-mode-warning.js";
|
|
9
15
|
import { scanRecursive } from "../core/scan-recursive.js";
|
|
10
16
|
import { scanGitHubActions } from "../core/scan-github-actions.js";
|
|
11
17
|
import "../core/index.js";
|
|
12
18
|
import { version } from "../package.js";
|
|
13
|
-
import { relative, resolve } from "node:path";
|
|
14
19
|
import { createSpinner } from "nanospinner";
|
|
15
20
|
import "node:worker_threads";
|
|
16
21
|
import pc from "picocolors";
|
|
17
22
|
import cac from "cac";
|
|
18
23
|
function run() {
|
|
19
24
|
let b = cac("actions-up");
|
|
20
|
-
b.help().version(version).option("--dir <directory>", "
|
|
25
|
+
b.help().version(version).option("--dir <directory>", "Directory to scan (repeatable). Default: .github, or . with --recursive").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("--mode <mode>", "Update mode: major, minor, or patch (default: major)", { default: "major" }).option("--recursive, -r", "Recursively scan directories for YAML files").option("--yes, -y", "Skip all confirmations").command("", "Update GitHub Actions").action(async (v) => {
|
|
21
26
|
console.info(pc.cyan("\n🚀 Actions Up!\n"));
|
|
22
|
-
let y = createSpinner("Scanning GitHub Actions...").start(), b =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}))];
|
|
27
|
+
let y = createSpinner("Scanning GitHub Actions...").start(), b = resolveScanDirectories({
|
|
28
|
+
recursive: v.recursive,
|
|
29
|
+
cwd: process.cwd(),
|
|
30
|
+
dir: v.dir
|
|
31
|
+
});
|
|
28
32
|
try {
|
|
29
|
-
let
|
|
30
|
-
if (y.success(`Found ${pc.yellow(
|
|
33
|
+
let m = mergeScanResults(v.recursive ? await Promise.all(b.map(({ root: t, dir: u }) => scanRecursive(t, u))) : await Promise.all(b.map(({ root: t, dir: u }) => scanGitHubActions(t, u)))), x = m.actions.length, S = m.workflows.size, C = m.compositeActions.size;
|
|
34
|
+
if (y.success(`Found ${pc.yellow(x)} actions in ${pc.yellow(S)} workflows and ${pc.yellow(C)} composite actions`), x === 0) {
|
|
31
35
|
console.info(pc.green("\n✨ No GitHub Actions found in this repository"));
|
|
32
36
|
return;
|
|
33
37
|
}
|
|
34
|
-
let
|
|
35
|
-
Array.isArray(
|
|
36
|
-
let
|
|
37
|
-
if (
|
|
38
|
-
let { parseExcludePatterns:
|
|
39
|
-
|
|
40
|
-
let { name:
|
|
41
|
-
for (let
|
|
38
|
+
let w = m.actions, T = [];
|
|
39
|
+
Array.isArray(v.exclude) ? T.push(...v.exclude) : typeof v.exclude == "string" && T.push(v.exclude);
|
|
40
|
+
let E = T.flatMap((t) => t.split(",")).map((t) => t.trim()).filter(Boolean);
|
|
41
|
+
if (E.length > 0) {
|
|
42
|
+
let { parseExcludePatterns: t } = await import("../core/filters/parse-exclude-patterns.js"), u = t(E);
|
|
43
|
+
u.length > 0 && (w = w.filter((t) => {
|
|
44
|
+
let { name: d } = t;
|
|
45
|
+
for (let t of u) if (t.test(d)) return !1;
|
|
42
46
|
return !0;
|
|
43
47
|
}));
|
|
44
48
|
}
|
|
45
|
-
if (y = createSpinner("Checking for updates...").start(),
|
|
49
|
+
if (y = createSpinner("Checking for updates...").start(), w.length === 0) {
|
|
46
50
|
y.success("No actions to check after excludes"), console.info(pc.green("\n✨ Nothing to check after excludes\n"));
|
|
47
51
|
return;
|
|
48
52
|
}
|
|
49
|
-
let
|
|
50
|
-
|
|
51
|
-
|
|
53
|
+
let D = process.env.GITHUB_TOKEN, O = createGitHubClient(D), k = v.includeBranches ?? !1, A = await checkUpdates(w, D, {
|
|
54
|
+
client: O,
|
|
55
|
+
includeBranches: k
|
|
56
|
+
}), j = [];
|
|
57
|
+
await Promise.all(A.map(async (t) => {
|
|
58
|
+
await shouldIgnore(t.action.file, t.action.line) || j.push(t);
|
|
52
59
|
}));
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
let
|
|
56
|
-
if (
|
|
57
|
-
let d = /* @__PURE__ */ new Map(), p = await Promise.all(
|
|
58
|
-
let
|
|
59
|
-
if (isSha(
|
|
60
|
-
let
|
|
61
|
-
|
|
60
|
+
let M = j.filter((t) => t.status === "skipped"), N = j.filter((t) => t.hasUpdate), P = v.minAge * 24 * 60 * 60 * 1e3, F = Date.now();
|
|
61
|
+
N = N.filter((t) => t.publishedAt ? F - t.publishedAt.getTime() >= P : !0);
|
|
62
|
+
let I = normalizeUpdateMode(v.mode), L = [];
|
|
63
|
+
if (I !== "major") {
|
|
64
|
+
let d = /* @__PURE__ */ new Map(), p = /* @__PURE__ */ new Map(), m = /* @__PURE__ */ new Map(), h = await Promise.all(N.map(async (d) => {
|
|
65
|
+
let f = d.currentVersion;
|
|
66
|
+
if (isSha(d.currentVersion)) {
|
|
67
|
+
let u = await readInlineVersionComment(d.action.file, d.action.line, m);
|
|
68
|
+
u && (f = u);
|
|
62
69
|
}
|
|
63
|
-
let
|
|
70
|
+
let p = getUpdateLevel(f, d.latestVersion);
|
|
64
71
|
return {
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
effectiveCurrentVersion: f,
|
|
73
|
+
allowed: I === "minor" ? p === "minor" || p === "patch" || p === "none" : p === "patch" || p === "none",
|
|
74
|
+
update: d
|
|
67
75
|
};
|
|
68
|
-
})),
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
})), g = [], _ = await Promise.all(h.map(async (t) => {
|
|
77
|
+
if (t.allowed) return { update: t.update };
|
|
78
|
+
let u = await getCompatibleUpdate(O, {
|
|
79
|
+
currentVersion: t.effectiveCurrentVersion,
|
|
80
|
+
actionName: t.update.action.name,
|
|
81
|
+
tagsCache: d,
|
|
82
|
+
shaCache: p,
|
|
83
|
+
mode: I
|
|
84
|
+
});
|
|
85
|
+
return u ? { update: {
|
|
86
|
+
...t.update,
|
|
87
|
+
latestVersion: u.version,
|
|
88
|
+
latestSha: u.sha,
|
|
89
|
+
isBreaking: !1,
|
|
90
|
+
hasUpdate: !0
|
|
91
|
+
} } : { blocked: t.update };
|
|
92
|
+
}));
|
|
93
|
+
for (let t of _) {
|
|
94
|
+
if (t.update) {
|
|
95
|
+
g.push(t.update);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
L.push(t.blocked);
|
|
99
|
+
}
|
|
100
|
+
N = g;
|
|
71
101
|
}
|
|
72
|
-
let
|
|
73
|
-
if (
|
|
74
|
-
y.success("All actions are up to date!"),
|
|
102
|
+
let R = N.filter((t) => t.isBreaking);
|
|
103
|
+
if (N.length === 0) {
|
|
104
|
+
y.success("All actions are up to date!"), M.length > 0 && printSkippedWarning(M, k), L.length > 0 && printModeWarning(L, I), console.info(pc.green("\n✨ Everything is already at the latest version!\n"));
|
|
75
105
|
return;
|
|
76
106
|
}
|
|
77
|
-
if (y.success(`Found ${pc.yellow(
|
|
107
|
+
if (y.success(`Found ${pc.yellow(N.length)} updates available${R.length > 0 ? ` (${pc.redBright(R.length)} breaking)` : ""}`), M.length > 0 && printSkippedWarning(M, k), L.length > 0 && printModeWarning(L, I), v.dryRun) {
|
|
78
108
|
console.info(pc.yellow("\n📋 Dry Run - No changes will be made\n"));
|
|
79
|
-
for (let
|
|
80
|
-
console.info(pc.gray(`\n${
|
|
109
|
+
for (let t of N) console.info(`${pc.cyan(t.action.file ?? "unknown")}:\n${t.action.name}: ${pc.redBright(t.currentVersion)} → ${pc.green(t.latestVersion)} ${t.latestSha ? pc.gray(`(${t.latestSha.slice(0, 7)})`) : ""}\n`);
|
|
110
|
+
console.info(pc.gray(`\n${N.length} actions would be updated\n`));
|
|
81
111
|
return;
|
|
82
112
|
}
|
|
83
|
-
if (
|
|
84
|
-
let
|
|
85
|
-
if (
|
|
113
|
+
if (v.yes) {
|
|
114
|
+
let t = N.filter((t) => t.latestSha);
|
|
115
|
+
if (t.length === 0) {
|
|
86
116
|
console.info(pc.yellow("\n⚠️ No actions with SHA available for update\n"));
|
|
87
117
|
return;
|
|
88
118
|
}
|
|
89
|
-
console.info(pc.yellow(`\n🔄 Updating ${
|
|
119
|
+
console.info(pc.yellow(`\n🔄 Updating ${t.length} actions...\n`)), await applyUpdates(t), console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
90
120
|
} else {
|
|
91
|
-
(
|
|
92
|
-
let
|
|
93
|
-
if (!
|
|
121
|
+
(M.length > 0 || L.length > 0) && console.info("");
|
|
122
|
+
let t = await promptUpdateSelection(N, { showAge: v.minAge > 0 });
|
|
123
|
+
if (!t || t.length === 0) {
|
|
94
124
|
console.info(pc.gray("\nNo updates applied"));
|
|
95
125
|
return;
|
|
96
126
|
}
|
|
97
|
-
console.info(pc.yellow(`\n🔄 Updating ${
|
|
127
|
+
console.info(pc.yellow(`\n🔄 Updating ${t.length} selected actions...\n`)), await applyUpdates(t), console.info(pc.green("\n✓ Updates applied successfully!"));
|
|
98
128
|
}
|
|
99
|
-
} catch (
|
|
100
|
-
y.error("Failed"),
|
|
129
|
+
} catch (t) {
|
|
130
|
+
y.error("Failed"), t instanceof Error && t.name === "GitHubRateLimitError" ? (console.error(pc.yellow("\n⚠️ Rate Limit Exceeded\n")), console.error(t.message), console.error(pc.gray("\nExample: GITHUB_TOKEN=ghp_xxxx actions-up\n"))) : console.error(pc.redBright("\nError:"), t instanceof Error ? t.message : String(t)), process.exit(1);
|
|
101
131
|
}
|
|
102
132
|
}), b.parse();
|
|
103
133
|
}
|
|
104
|
-
function mergeScanResults(e) {
|
|
105
|
-
let d = {
|
|
106
|
-
compositeActions: /* @__PURE__ */ new Map(),
|
|
107
|
-
workflows: /* @__PURE__ */ new Map(),
|
|
108
|
-
actions: []
|
|
109
|
-
};
|
|
110
|
-
for (let f of e) {
|
|
111
|
-
for (let [e, p] of f.workflows) d.workflows.set(e, p);
|
|
112
|
-
for (let [, e] of f.compositeActions) d.compositeActions.set(e, e);
|
|
113
|
-
d.actions.push(...f.actions);
|
|
114
|
-
}
|
|
115
|
-
let f = /* @__PURE__ */ new Set();
|
|
116
|
-
return d.actions = d.actions.filter((e) => {
|
|
117
|
-
let d = `${e.file}:${e.line}:${e.name}:${e.version}`;
|
|
118
|
-
return f.has(d) ? !1 : (f.add(d), !0);
|
|
119
|
-
}), d;
|
|
120
|
-
}
|
|
121
|
-
function printModeWarning(e, d) {
|
|
122
|
-
if (e.length === 0) return;
|
|
123
|
-
let f = new Intl.PluralRules("en-US", { type: "cardinal" }).select(e.length) === "one" ? "action" : "actions", p = d === "minor" ? "major" : "major/minor";
|
|
124
|
-
console.info(pc.yellow(`\n⚠️ Skipped ${e.length} ${f} due to ${p} updates`));
|
|
125
|
-
for (let d of e) {
|
|
126
|
-
let e = d.action.uses ?? `${d.action.name}@${d.currentVersion ?? "unknown"}`;
|
|
127
|
-
console.info(pc.gray(` • ${e}`));
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
function printSkippedWarning(e, d) {
|
|
131
|
-
let f = new Intl.PluralRules("en-US", { type: "cardinal" }).select(e.length) === "one" ? "action" : "actions", p = d ? "" : " (use --include-branches to check them)";
|
|
132
|
-
console.info(pc.yellow(`\n⚠️ Skipped ${e.length} ${f} pinned to branches${p}`));
|
|
133
|
-
for (let d of e) {
|
|
134
|
-
let e = d.action.uses ?? `${d.action.name}@${d.currentVersion ?? "unknown"}`;
|
|
135
|
-
console.info(pc.gray(` • ${e}`));
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
function normalizeUpdateMode(e) {
|
|
139
|
-
let d = (e ?? "major").toLowerCase();
|
|
140
|
-
if (d === "major" || d === "minor" || d === "patch") return d;
|
|
141
|
-
throw Error(`Invalid mode "${e}". Expected "major", "minor", or "patch".`);
|
|
142
|
-
}
|
|
143
134
|
export { run };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function mergeScanResults(e) {
|
|
2
|
+
let t = {
|
|
3
|
+
compositeActions: /* @__PURE__ */ new Map(),
|
|
4
|
+
workflows: /* @__PURE__ */ new Map(),
|
|
5
|
+
actions: []
|
|
6
|
+
};
|
|
7
|
+
for (let [n, r] of e.entries()) {
|
|
8
|
+
for (let [e, i] of r.workflows) t.workflows.set(`${n}:${e}`, i);
|
|
9
|
+
for (let [, e] of r.compositeActions) t.compositeActions.set(`${n}:${e}`, e);
|
|
10
|
+
t.actions.push(...r.actions);
|
|
11
|
+
}
|
|
12
|
+
let n = /* @__PURE__ */ new Set();
|
|
13
|
+
return t.actions = t.actions.filter((e) => {
|
|
14
|
+
let t = `${e.file}:${e.line}:${e.name}:${e.version}`;
|
|
15
|
+
return n.has(t) ? !1 : (n.add(t), !0);
|
|
16
|
+
}), t;
|
|
17
|
+
}
|
|
18
|
+
export { mergeScanResults };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { UpdateMode } from '../types/update-mode';
|
|
2
|
+
/**
|
|
3
|
+
* Prints a warning message for actions that were skipped due to update mode
|
|
4
|
+
* restrictions.
|
|
5
|
+
*
|
|
6
|
+
* @param blocked - Array of blocked actions with their current versions.
|
|
7
|
+
* @param mode - The current update mode (patch/minor/major).
|
|
8
|
+
*/
|
|
9
|
+
export declare function printModeWarning(blocked: {
|
|
10
|
+
action: {
|
|
11
|
+
version?: string | null;
|
|
12
|
+
uses?: string;
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
15
|
+
currentVersion: string | null;
|
|
16
|
+
}[], mode: UpdateMode): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
function printModeWarning(t, n) {
|
|
3
|
+
if (t.length === 0) return;
|
|
4
|
+
let r = new Intl.PluralRules("en-US", { type: "cardinal" }).select(t.length) === "one" ? "action" : "actions", i = n === "minor" ? "major" : "major/minor";
|
|
5
|
+
console.info(pc.yellow(`\n⚠️ Skipped ${t.length} ${r} due to ${i} updates`));
|
|
6
|
+
for (let n of t) {
|
|
7
|
+
let t = n.action.uses ?? `${n.action.name}@${n.currentVersion ?? "unknown"}`;
|
|
8
|
+
console.info(pc.gray(` • ${t}`));
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
export { printModeWarning };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prints a warning message for actions that were skipped during scanning.
|
|
3
|
+
*
|
|
4
|
+
* @param skipped - Array of skipped actions with their current versions.
|
|
5
|
+
* @param includeBranches - Whether branch-pinned actions are being checked.
|
|
6
|
+
*/
|
|
7
|
+
export declare function printSkippedWarning(skipped: {
|
|
8
|
+
action: {
|
|
9
|
+
version?: string | null;
|
|
10
|
+
uses?: string;
|
|
11
|
+
name: string;
|
|
12
|
+
};
|
|
13
|
+
currentVersion: string | null;
|
|
14
|
+
}[], includeBranches: boolean): void;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
function printSkippedWarning(t, n) {
|
|
3
|
+
let r = new Intl.PluralRules("en-US", { type: "cardinal" }).select(t.length) === "one" ? "action" : "actions", i = n ? "" : " (use --include-branches to check them)";
|
|
4
|
+
console.info(pc.yellow(`\n⚠️ Skipped ${t.length} ${r} pinned to branches${i}`));
|
|
5
|
+
for (let n of t) {
|
|
6
|
+
let t = n.action.uses ?? `${n.action.name}@${n.currentVersion ?? "unknown"}`;
|
|
7
|
+
console.info(pc.gray(` • ${t}`));
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export { printSkippedWarning };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for resolving scan directories from CLI flags.
|
|
3
|
+
*/
|
|
4
|
+
interface ResolveScanDirectoriesOptions {
|
|
5
|
+
dir?: string[] | string;
|
|
6
|
+
recursive?: boolean;
|
|
7
|
+
cwd: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Resolved directory with root and relative directory.
|
|
11
|
+
*/
|
|
12
|
+
interface ResolvedDirectory {
|
|
13
|
+
root: string;
|
|
14
|
+
dir: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve directories to scan from CLI options.
|
|
18
|
+
*
|
|
19
|
+
* Defaults:
|
|
20
|
+
*
|
|
21
|
+
* - Non-recursive mode: `.github`
|
|
22
|
+
* - Recursive mode without --dir: `.`.
|
|
23
|
+
*
|
|
24
|
+
* @param options - CLI options used to compute scan directories.
|
|
25
|
+
* @param options.cwd - Current working directory.
|
|
26
|
+
* @param options.dir - Optional directory flag value(s).
|
|
27
|
+
* @param options.recursive - Whether recursive mode is enabled.
|
|
28
|
+
* @returns Unique resolved directories.
|
|
29
|
+
*/
|
|
30
|
+
export declare function resolveScanDirectories(options: ResolveScanDirectoriesOptions): ResolvedDirectory[];
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { GITHUB_DIRECTORY } from "../core/constants.js";
|
|
2
|
+
import { basename, dirname, isAbsolute, relative, resolve } from "node:path";
|
|
3
|
+
function resolveScanDirectories(o) {
|
|
4
|
+
let { recursive: s, cwd: c, dir: l } = o, u = [];
|
|
5
|
+
Array.isArray(l) ? u.push(...l) : typeof l == "string" ? u.push(l) : s ? u.push(".") : u.push(GITHUB_DIRECTORY);
|
|
6
|
+
let d = /* @__PURE__ */ new Set(), f = [];
|
|
7
|
+
for (let e of u) {
|
|
8
|
+
let o = resolve(c, e), l = relative(c, o), u = l.startsWith("..") || isAbsolute(l) || resolve(c, l) !== o, p;
|
|
9
|
+
p = s ? {
|
|
10
|
+
root: o,
|
|
11
|
+
dir: "."
|
|
12
|
+
} : u ? {
|
|
13
|
+
dir: basename(o),
|
|
14
|
+
root: dirname(o)
|
|
15
|
+
} : {
|
|
16
|
+
dir: l || ".github",
|
|
17
|
+
root: c
|
|
18
|
+
};
|
|
19
|
+
let m = `${p.root}\0${p.dir}`;
|
|
20
|
+
d.has(m) || (d.add(m), f.push(p));
|
|
21
|
+
}
|
|
22
|
+
return f;
|
|
23
|
+
}
|
|
24
|
+
export { resolveScanDirectories };
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GitHubClient } from '../../types/github-client';
|
|
1
2
|
import { GitHubAction } from '../../types/github-action';
|
|
2
3
|
import { ActionUpdate } from '../../types/action-update';
|
|
3
4
|
/**
|
|
@@ -5,9 +6,11 @@ import { ActionUpdate } from '../../types/action-update';
|
|
|
5
6
|
*
|
|
6
7
|
* @param actions - Array of GitHub Actions to check.
|
|
7
8
|
* @param token - Optional GitHub token for authentication.
|
|
8
|
-
* @param options - Additional options (e.g., include branch refs
|
|
9
|
+
* @param options - Additional options (e.g., include branch refs, shared
|
|
10
|
+
* client).
|
|
9
11
|
* @returns Array of update information.
|
|
10
12
|
*/
|
|
11
13
|
export declare function checkUpdates(actions: GitHubAction[], token?: string, options?: {
|
|
12
14
|
includeBranches?: boolean;
|
|
15
|
+
client?: GitHubClient;
|
|
13
16
|
}): Promise<ActionUpdate[]>;
|