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.
Files changed (51) hide show
  1. package/dist/cli/index.d.ts +3 -1
  2. package/dist/cli/index.js +84 -93
  3. package/dist/cli/merge-scan-results.d.ts +8 -0
  4. package/dist/cli/merge-scan-results.js +18 -0
  5. package/dist/cli/normalize-update-mode.d.ts +8 -0
  6. package/dist/cli/normalize-update-mode.js +6 -0
  7. package/dist/cli/print-mode-warning.d.ts +16 -0
  8. package/dist/cli/print-mode-warning.js +11 -0
  9. package/dist/cli/print-skipped-warning.d.ts +14 -0
  10. package/dist/cli/print-skipped-warning.js +10 -0
  11. package/dist/cli/resolve-scan-directories.d.ts +31 -0
  12. package/dist/cli/resolve-scan-directories.js +24 -0
  13. package/dist/core/api/check-updates.d.ts +4 -1
  14. package/dist/core/api/check-updates.js +119 -116
  15. package/dist/core/api/get-all-releases.d.ts +2 -1
  16. package/dist/core/api/get-compatible-update.d.ts +37 -0
  17. package/dist/core/api/get-compatible-update.js +40 -0
  18. package/dist/core/api/get-latest-release.d.ts +3 -3
  19. package/dist/core/ast/utils/extract-uses-from-steps.d.ts +12 -4
  20. package/dist/core/constants.d.ts +3 -1
  21. package/dist/core/fs/find-yaml-files-recursive.js +1 -1
  22. package/dist/core/interactive/prompt-update-selection.d.ts +3 -1
  23. package/dist/core/interactive/prompt-update-selection.js +9 -9
  24. package/dist/core/parsing/parse-action-reference.d.ts +16 -12
  25. package/dist/core/scan-github-actions.d.ts +4 -1
  26. package/dist/core/scan-github-actions.js +67 -68
  27. package/dist/core/scan-recursive.js +12 -14
  28. package/dist/core/versions/find-compatible-tag.d.ts +16 -0
  29. package/dist/core/versions/find-compatible-tag.js +27 -0
  30. package/dist/core/versions/get-update-level.d.ts +3 -1
  31. package/dist/core/versions/is-semver-like.d.ts +9 -0
  32. package/dist/core/versions/is-semver-like.js +4 -0
  33. package/dist/core/versions/normalize-version.d.ts +14 -0
  34. package/dist/core/versions/normalize-version.js +9 -0
  35. package/dist/package.js +1 -1
  36. package/dist/types/action-update.d.ts +30 -10
  37. package/dist/types/composite-action-runs.d.ts +12 -4
  38. package/dist/types/composite-action-step.d.ts +24 -8
  39. package/dist/types/composite-action-structure.d.ts +21 -7
  40. package/dist/types/github-action.d.ts +27 -9
  41. package/dist/types/github-client-context.d.ts +24 -8
  42. package/dist/types/github-client.d.ts +24 -8
  43. package/dist/types/release-info.d.ts +24 -8
  44. package/dist/types/scan-result.d.ts +12 -4
  45. package/dist/types/tag-info.d.ts +15 -5
  46. package/dist/types/update-mode.d.ts +3 -1
  47. package/dist/types/workflow-job.d.ts +27 -9
  48. package/dist/types/workflow-step.d.ts +21 -7
  49. package/dist/types/workflow-structure.d.ts +15 -5
  50. package/package.json +3 -8
  51. package/readme.md +53 -18
@@ -1,149 +1,161 @@
1
+ import { normalizeVersion } from "../versions/normalize-version.js";
2
+ import { isSemverLike } from "../versions/is-semver-like.js";
1
3
  import { createGitHubClient } from "./create-github-client.js";
2
4
  import semver from "semver";
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);
5
+ async function checkUpdates(i, o, l) {
6
+ let u = l?.client ?? createGitHubClient(o), d = l?.includeBranches ?? !1, f = i.filter((e) => e.type === "external" || e.type === "reusable-workflow");
7
+ if (f.length === 0) return [];
8
+ let p = /* @__PURE__ */ new Map();
9
+ for (let e of f) {
10
+ let t = p.get(e.name) ?? [];
11
+ t.push(e), p.set(e.name, t);
10
12
  }
11
- let p = {
13
+ let m = {
12
14
  rateLimitError: null,
13
15
  rateLimitHit: !1
14
- }, m = await [...f.keys()].reduce((e, n) => e.then(async (e) => {
15
- if (p.rateLimitHit) return [...e, {
16
+ }, h = await [...p.keys()].reduce((n, i) => n.then(async (n) => {
17
+ if (m.rateLimitHit) return [...n, {
16
18
  publishedAt: null,
17
19
  version: null,
18
- actionName: n,
20
+ actionName: i,
19
21
  sha: null
20
22
  }];
21
- let r = n.split("/");
22
- if (r.length < 2) return [...e, {
23
+ let a = i.split("/");
24
+ if (a.length < 2) return [...n, {
23
25
  publishedAt: null,
24
26
  version: null,
25
- actionName: n,
27
+ actionName: i,
26
28
  sha: null
27
29
  }];
28
- let [i, c] = r;
29
- if (!i || !c) return [...e, {
30
+ let [o, l] = a;
31
+ if (!o || !l) return [...n, {
30
32
  publishedAt: null,
31
33
  version: null,
32
- actionName: n,
34
+ actionName: i,
33
35
  sha: null
34
36
  }];
35
37
  try {
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
+ let a = p.get(i)[0]?.version;
39
+ if (a && !isSha(a) && !isSemverLike(a) && await u.getRefType(o, l, a) === "branch" && !d) return [...n, {
38
40
  skipReason: "branch",
39
41
  status: "skipped",
40
42
  publishedAt: null,
41
43
  version: null,
42
- actionName: n,
44
+ actionName: i,
43
45
  sha: null
44
46
  }];
45
- let d = await l.getLatestRelease(i, c);
46
- if (!d) {
47
- let e = await l.getAllReleases(i, c, 1);
48
- d = e.find((e) => !e.isPrerelease) ?? e[0] ?? null;
47
+ let f = await u.getLatestRelease(o, l);
48
+ if (!f) {
49
+ let e = await u.getAllReleases(o, l, 1);
50
+ f = e.find((e) => !e.isPrerelease) ?? e[0] ?? null;
49
51
  }
50
- if (d) {
51
- let { publishedAt: r, version: o, sha: u } = d, f = !1;
52
+ if (f) {
53
+ let { publishedAt: a, version: s, sha: d } = f, p = !1;
52
54
  {
53
- let e = normalizeVersion(o), n = !!(o && o.trim() !== ""), r = n && /^v?\d+$/u.test(o.trim()), i = semver.valid(e);
54
- f = !n || r || !i || !isSemverLike(o);
55
+ let n = normalizeVersion(s), i = !!(s && s.trim() !== ""), a = i && /^v?\d+$/u.test(s.trim()), o = semver.valid(n);
56
+ p = !i || a || !o || !isSemverLike(s);
55
57
  }
56
- if (f) {
57
- let r = await l.getAllTags(i, c, 30);
58
- if (r.length > 0) {
59
- let u = r.filter((e) => isSemverLike(e.tag)).map((e) => ({
60
- v: semver.valid(normalizeVersion(e.tag)),
61
- raw: e
58
+ if (p) {
59
+ let a = await u.getAllTags(o, l, 30);
60
+ if (a.length > 0) {
61
+ let d = a.filter((e) => isSemverLike(e.tag)).map((t) => ({
62
+ v: semver.valid(normalizeVersion(t.tag)),
63
+ raw: t
62
64
  }));
63
- if (u.length > 0) {
64
- u.sort((e, n) => {
65
- let r = semver.rcompare(e.v, n.v);
66
- if (r !== 0) return r;
65
+ if (d.length > 0) {
66
+ d.sort((e, t) => {
67
+ let n = semver.rcompare(e.v, t.v);
68
+ if (n !== 0) return n;
67
69
  let i = /\d+\.\d+/u.test(e.raw.tag) ? 1 : 0;
68
- return (/\d+\.\d+/u.test(n.raw.tag) ? 1 : 0) - i;
70
+ return (/\d+\.\d+/u.test(t.raw.tag) ? 1 : 0) - i;
69
71
  });
70
- let r = u[0].raw, s = semver.valid(normalizeVersion(o) ?? void 0);
71
- if (!s || semver.gt(u[0].v, s) || semver.eq(u[0].v, s) && /\d+\.\d+/u.test(r.tag)) {
72
- let t = r.tag, a = r.sha?.length ? r.sha : null;
73
- if (!a && t) try {
74
- a = await l.getTagSha(i, c, t);
75
- } catch {}
76
- return [...e, {
77
- version: t,
72
+ let t = d[0].raw, a = semver.valid(normalizeVersion(s) ?? void 0);
73
+ if (!a || semver.gt(d[0].v, a) || semver.eq(d[0].v, a) && /\d+\.\d+/u.test(t.tag)) {
74
+ let e = t.tag, r = t.sha?.length ? t.sha : null;
75
+ if (!r && e) try {
76
+ r = await u.getTagSha(o, l, e);
77
+ } catch (e) {
78
+ if (isRateLimitError(e)) throw e;
79
+ }
80
+ return [...n, {
81
+ version: e,
78
82
  publishedAt: null,
79
- sha: a,
80
- actionName: n
83
+ sha: r,
84
+ actionName: i
81
85
  }];
82
86
  }
83
87
  }
84
88
  }
85
89
  }
86
- if (!u && o) try {
87
- u = await l.getTagSha(i, c, o);
88
- } catch {}
89
- return [...e, {
90
+ if (s) {
91
+ let e = d;
92
+ try {
93
+ d = await u.getTagSha(o, l, s) ?? e;
94
+ } catch (t) {
95
+ if (isRateLimitError(t)) throw t;
96
+ d = e;
97
+ }
98
+ }
99
+ return [...n, {
90
100
  status: "ok",
91
- publishedAt: r,
92
- actionName: n,
93
- version: o,
94
- sha: u
101
+ publishedAt: a,
102
+ actionName: i,
103
+ version: s,
104
+ sha: d
95
105
  }];
96
106
  }
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) => ({
100
- v: semver.valid(normalizeVersion(e.tag)),
101
- raw: e
102
- })), o;
103
- r.length > 0 ? (r.sort((e, n) => {
104
- let r = semver.rcompare(e.v, n.v);
105
- if (r !== 0) return r;
107
+ let m = await u.getAllTags(o, l, 30);
108
+ if (m.length > 0) {
109
+ let a = m.filter((e) => isSemverLike(e.tag)).map((t) => ({
110
+ v: semver.valid(normalizeVersion(t.tag)),
111
+ raw: t
112
+ })), s;
113
+ a.length > 0 ? (a.sort((e, t) => {
114
+ let n = semver.rcompare(e.v, t.v);
115
+ if (n !== 0) return n;
106
116
  let i = /\d+\.\d+/u.test(e.raw.tag) ? 1 : 0;
107
- return (/\d+\.\d+/u.test(n.raw.tag) ? 1 : 0) - i;
108
- }), o = r[0].raw) : o = p[0];
109
- let u = o.tag, d = o.sha?.length ? o.sha : null;
110
- if (!d && u) try {
111
- d = await l.getTagSha(i, c, u);
112
- } catch {}
113
- return [...e, {
117
+ return (/\d+\.\d+/u.test(t.raw.tag) ? 1 : 0) - i;
118
+ }), s = a[0].raw) : s = m[0];
119
+ let d = s.tag, f = s.sha?.length ? s.sha : null;
120
+ if (!f && d) try {
121
+ f = await u.getTagSha(o, l, d);
122
+ } catch (e) {
123
+ if (isRateLimitError(e)) throw e;
124
+ }
125
+ return [...n, {
114
126
  status: "ok",
115
127
  publishedAt: null,
116
- actionName: n,
117
- version: u,
118
- sha: d
128
+ actionName: i,
129
+ version: d,
130
+ sha: f
119
131
  }];
120
132
  }
121
- return [...e, {
133
+ return [...n, {
122
134
  publishedAt: null,
123
135
  version: null,
124
- actionName: n,
136
+ actionName: i,
125
137
  sha: null
126
138
  }];
127
- } catch (t) {
128
- return t instanceof Error && t.name === "GitHubRateLimitError" ? (p.rateLimitHit = !0, p.rateLimitError = t, [...e, {
139
+ } catch (e) {
140
+ return e instanceof Error && e.name === "GitHubRateLimitError" ? (m.rateLimitHit = !0, m.rateLimitError = e, [...n, {
129
141
  publishedAt: null,
130
142
  version: null,
131
- actionName: n,
143
+ actionName: i,
132
144
  sha: null
133
- }]) : (console.warn(`Failed to check ${n}:`, t), [...e, {
145
+ }]) : (console.warn(`Failed to check ${i}:`, e), [...n, {
134
146
  publishedAt: null,
135
147
  version: null,
136
- actionName: n,
148
+ actionName: i,
137
149
  sha: null
138
150
  }]);
139
151
  }
140
152
  }), Promise.resolve([]));
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);
153
+ if (m.rateLimitError) {
154
+ let e = !!(o ?? process.env.GITHUB_TOKEN), t = `${m.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);
143
155
  throw n.name = "GitHubRateLimitError", n;
144
156
  }
145
- let h = /* @__PURE__ */ new Map();
146
- for (let e of m) h.set(e.actionName, {
157
+ let g = /* @__PURE__ */ new Map();
158
+ for (let e of h) g.set(e.actionName, {
147
159
  publishedAt: e.publishedAt,
148
160
  actionName: e.actionName,
149
161
  skipReason: e.skipReason,
@@ -151,57 +163,57 @@ async function checkUpdates(n, i, c) {
151
163
  status: e.status,
152
164
  sha: e.sha
153
165
  });
154
- let g = [];
155
- for (let e of d) {
156
- let t = h.get(e.name);
157
- t ? g.push(createUpdate(e, {
166
+ let _ = [];
167
+ for (let e of f) {
168
+ let t = g.get(e.name);
169
+ t ? _.push(createUpdate(e, {
158
170
  publishedAt: t.publishedAt,
159
171
  version: t.version,
160
172
  sha: t.sha
161
173
  }, {
162
174
  skipReason: t.skipReason,
163
175
  status: t.status
164
- })) : g.push(createUpdate(e, {
176
+ })) : _.push(createUpdate(e, {
165
177
  publishedAt: null,
166
178
  version: null,
167
179
  sha: null
168
180
  }));
169
181
  }
170
- return g;
182
+ return _;
171
183
  }
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;
184
+ function createUpdate(t, n, i = {}) {
185
+ let { version: a, sha: c, publishedAt: l } = n, u = t.version ?? "unknown", d = normalizeVersion(u), f = a ? normalizeVersion(a) : null, p = i.status ?? "ok", m = i.skipReason, h = !1, g = !1;
174
186
  if (p === "skipped") return {
175
187
  currentVersion: u,
176
188
  isBreaking: !1,
177
189
  hasUpdate: !1,
178
- latestVersion: s,
190
+ latestVersion: a,
179
191
  publishedAt: l,
180
192
  skipReason: m,
181
193
  latestSha: c,
182
- action: e,
194
+ action: t,
183
195
  status: p
184
196
  };
185
197
  if (d && isSha(d)) c ? h = !compareSha(d, c) : f && (h = !0);
186
198
  else if (d && f) {
187
- let n = semver.valid(d), r = semver.valid(f);
188
- if (n && r) {
189
- if (h = semver.lt(n, r), h) {
190
- let e = semver.major(n);
191
- g = semver.major(r) > e;
199
+ let e = semver.valid(d), n = semver.valid(f);
200
+ if (e && n) {
201
+ if (h = semver.lt(e, n), h) {
202
+ let t = semver.major(e);
203
+ g = semver.major(n) > t;
192
204
  }
193
- !h && semver.eq(n, r) && !isSha(e.version) && c && (h = !0, g = !1);
205
+ !h && semver.eq(e, n) && !isSha(t.version) && c && (h = !0, g = !1);
194
206
  } else d !== f && (h = !0);
195
207
  }
196
208
  return {
197
209
  currentVersion: u,
198
- latestVersion: s,
210
+ latestVersion: a,
199
211
  publishedAt: l,
200
212
  isBreaking: g,
201
213
  skipReason: m,
202
214
  latestSha: c,
203
215
  hasUpdate: h,
204
- action: e,
216
+ action: t,
205
217
  status: p
206
218
  };
207
219
  }
@@ -209,21 +221,12 @@ function compareSha(e, t) {
209
221
  let n = e.replace(/^v/u, ""), r = t.replace(/^v/u, ""), i = Math.min(n.length, r.length);
210
222
  return i < 7 ? !1 : n.slice(0, Math.max(0, i)).toLowerCase() === r.slice(0, Math.max(0, i)).toLowerCase();
211
223
  }
212
- function normalizeVersion(e) {
213
- if (!e) return null;
214
- let n = e.replace(/^v/u, "");
215
- if (/^[0-9a-f]{7,40}$/iu.test(n)) return e;
216
- let r = semver.coerce(n);
217
- return r ? r.version : e;
218
- }
219
224
  function isSha(e) {
220
225
  if (!e) return !1;
221
226
  let t = e.replace(/^v/u, "");
222
227
  return /^[0-9a-f]{7,40}$/iu.test(t);
223
228
  }
224
- function isSemverLike(e) {
225
- if (!e) return !1;
226
- let t = e.trim();
227
- return /^v?\d+(?:\.\d+){0,2}$/u.test(t);
229
+ function isRateLimitError(e) {
230
+ return e instanceof Error && e.name === "GitHubRateLimitError";
228
231
  }
229
232
  export { checkUpdates };
@@ -4,7 +4,8 @@ import { ReleaseInfo } from '../../types/release-info';
4
4
  * Fetch releases for a repository.
5
5
  *
6
6
  * Resolves SHA only for the first returned release via target_commitish when it
7
- * looks like a SHA; further enrichment happens at higher levels when needed.
7
+ * looks like a SHA; callers can resolve the tag via git refs later when
8
+ * pinning.
8
9
  *
9
10
  * @param context - Client context.
10
11
  * @param parameters - Request parameters.
@@ -0,0 +1,37 @@
1
+ import { GitHubClient } from '../../types/github-client';
2
+ import { UpdateMode } from '../../types/update-mode';
3
+ import { TagInfo } from '../../types/tag-info';
4
+ interface GetCompatibleUpdateParameters {
5
+ /**
6
+ * Optional in-memory cache for resolved tag SHAs.
7
+ */
8
+ shaCache?: Map<string, string | null>;
9
+ /**
10
+ * Update mode that limits which tag can be selected.
11
+ */
12
+ mode: Exclude<UpdateMode, 'major'>;
13
+ /**
14
+ * Optional in-memory cache for action tags.
15
+ */
16
+ tagsCache?: Map<string, TagInfo[]>;
17
+ /**
18
+ * Current action version used as compatibility baseline.
19
+ */
20
+ currentVersion: string | null;
21
+ /**
22
+ * Action name in `owner/repo` format (path suffix is allowed).
23
+ */
24
+ actionName: string;
25
+ }
26
+ /**
27
+ * Resolve the newest compatible update for an action.
28
+ *
29
+ * @param client - GitHub client instance.
30
+ * @param parameters - Lookup parameters.
31
+ * @returns Compatible target version and SHA, or null when none found.
32
+ */
33
+ export declare function getCompatibleUpdate(client: GitHubClient, parameters: GetCompatibleUpdateParameters): Promise<{
34
+ sha: string | null;
35
+ version: string;
36
+ } | null>;
37
+ export {};
@@ -0,0 +1,40 @@
1
+ import { isSemverLike } from "../versions/is-semver-like.js";
2
+ import { findCompatibleTag } from "../versions/find-compatible-tag.js";
3
+ async function getCompatibleUpdate(n, r) {
4
+ let { currentVersion: i, actionName: a, mode: o } = r;
5
+ if (!i || !isSemverLike(i)) return null;
6
+ let s = a.split("/");
7
+ if (s.length < 2) return null;
8
+ let [c, l] = s;
9
+ if (!c || !l) return null;
10
+ let u = r.tagsCache ?? /* @__PURE__ */ new Map(), d = r.shaCache ?? /* @__PURE__ */ new Map(), f = u.get(a);
11
+ if (!f) {
12
+ try {
13
+ f = await n.getAllTags(c, l, 100);
14
+ } catch {
15
+ return null;
16
+ }
17
+ u.set(a, f);
18
+ }
19
+ let p = findCompatibleTag(f, i, o);
20
+ if (!p) return null;
21
+ let m = p.tag, h = p.sha?.length ? p.sha : null;
22
+ if (!h) {
23
+ let e = `${a}@${m}`;
24
+ if (d.has(e)) return {
25
+ sha: d.get(e) ?? null,
26
+ version: m
27
+ };
28
+ try {
29
+ h = await n.getTagSha(c, l, m);
30
+ } catch {
31
+ h = null;
32
+ }
33
+ d.set(e, h);
34
+ }
35
+ return {
36
+ version: m,
37
+ sha: h
38
+ };
39
+ }
40
+ export { getCompatibleUpdate };
@@ -3,9 +3,9 @@ import { ReleaseInfo } from '../../types/release-info';
3
3
  /**
4
4
  * Fetch the latest release for a repository.
5
5
  *
6
- * If the latest release does not exist (404), returns null. The commit SHA is
7
- * taken from target_commitish only when it looks like a SHA; otherwise SHA is
8
- * left null and may be resolved later via tag lookups.
6
+ * If the latest release does not exist (404), returns null. The commit SHA may
7
+ * be taken from target_commitish when it looks like a SHA; callers can resolve
8
+ * the tag via git refs later when pinning.
9
9
  *
10
10
  * @param context - Client context.
11
11
  * @param owner - Repository owner.
@@ -1,12 +1,20 @@
1
1
  import { GitHubAction } from '../../../types/github-action';
2
2
  interface ExtractUsesOptions {
3
- /** YAML sequence node containing workflow/action steps. */
3
+ /**
4
+ * YAML sequence node containing workflow/action steps.
5
+ */
4
6
  stepsNode: unknown;
5
- /** Path of the file being scanned (for metadata). */
7
+ /**
8
+ * Path of the file being scanned (for metadata).
9
+ */
6
10
  filePath: string;
7
- /** Name of the job containing these steps (for workflows). */
11
+ /**
12
+ * Name of the job containing these steps (for workflows).
13
+ */
8
14
  jobName?: string;
9
- /** Original YAML file content (for line number calculation). */
15
+ /**
16
+ * Original YAML file content (for line number calculation).
17
+ */
10
18
  content: string;
11
19
  }
12
20
  /**
@@ -1,4 +1,6 @@
1
- /** Constants for directory names used in the project. */
1
+ /**
2
+ * Constants for directory names used in the project.
3
+ */
2
4
  export declare const GITHUB_DIRECTORY: ".github";
3
5
  export declare const WORKFLOWS_DIRECTORY: "workflows";
4
6
  export declare const ACTIONS_DIRECTORY: "actions";
@@ -1,6 +1,6 @@
1
1
  import { isYamlFile } from "./is-yaml-file.js";
2
- import { join } from "node:path";
3
2
  import { lstat, readdir } from "node:fs/promises";
3
+ import { join } from "node:path";
4
4
  async function findYamlFilesRecursive(i) {
5
5
  let a = [], o = /* @__PURE__ */ new Set();
6
6
  async function s(i) {
@@ -1,6 +1,8 @@
1
1
  import { ActionUpdate } from '../../types/action-update';
2
2
  interface PromptUpdateSelectionOptions {
3
- /** Whether to show the Age column. */
3
+ /**
4
+ * Whether to show the Age column.
5
+ */
4
6
  showAge?: boolean;
5
7
  }
6
8
  export declare function promptUpdateSelection(updates: ActionUpdate[], options?: PromptUpdateSelectionOptions): Promise<ActionUpdate[] | null>;
@@ -4,10 +4,10 @@ import { GITHUB_DIRECTORY } from "../constants.js";
4
4
  import { isSha } from "../versions/is-sha.js";
5
5
  import { stripAnsi } from "./strip-ansi.js";
6
6
  import { padString } from "./pad-string.js";
7
- import path from "node:path";
8
7
  import "node:worker_threads";
9
8
  import pc from "picocolors";
10
9
  import enquirer from "enquirer";
10
+ import path from "node:path";
11
11
  var MIN_ACTION_WIDTH = 40, MIN_JOB_WIDTH = 4, MIN_CURRENT_WIDTH = 16, MAX_VERSION_WIDTH = 7;
12
12
  async function promptUpdateSelection(g, v = {}) {
13
13
  let { showAge: y = !1 } = v;
@@ -41,8 +41,8 @@ async function promptUpdateSelection(g, v = {}) {
41
41
  };
42
42
  })), C = [], w = stripAnsi("Action").length, T = stripAnsi("Current").length, E = stripAnsi("Job").length, D = 0, O = !1;
43
43
  for (let [t, a] of b.entries()) {
44
- let o = a.action.name, l = S[t], d = l.display, f = a.action.job ?? "–";
45
- if (w = Math.max(w, o.length), T = Math.max(T, stripAnsi(d).length, l.versionForPadding && l.shortSha ? stripAnsi(`${padString(l.versionForPadding, D + 1)}${pc.gray(`(${l.shortSha})`)}`).length : 0), E = Math.max(E, f.length), a.latestVersion) {
44
+ let o = a.action.name, u = S[t], d = u.display, f = a.action.job ?? "–";
45
+ if (w = Math.max(w, o.length), T = Math.max(T, stripAnsi(d).length, u.versionForPadding && u.shortSha ? stripAnsi(`${padString(u.versionForPadding, D + 1)}${pc.gray(`(${u.shortSha})`)}`).length : 0), E = Math.max(E, f.length), a.latestVersion) {
46
46
  let o = formatVersion(a.latestVersion, S[t]?.effectiveForDiff ?? a.currentVersion);
47
47
  D = Math.max(D, stripAnsi(o).length);
48
48
  }
@@ -56,7 +56,7 @@ async function promptUpdateSelection(g, v = {}) {
56
56
  console.warn(`Unexpected missing group for file: ${a}`);
57
57
  continue;
58
58
  }
59
- let s = [], l = o;
59
+ let s = [], u = o;
60
60
  s.push({
61
61
  current: "Current",
62
62
  action: "Action",
@@ -65,10 +65,10 @@ async function promptUpdateSelection(g, v = {}) {
65
65
  job: "Job",
66
66
  age: "Age"
67
67
  });
68
- for (let { update: t, index: a } of l) {
69
- let o = !!t.latestSha, l = S[a], d = l.display;
70
- l.versionForPadding && l.shortSha && (d = `${padString(l.versionForPadding, M + 1)}${pc.gray(`(${l.shortSha})`)}`);
71
- let f = l.effectiveForDiff ?? t.currentVersion, p = formatVersion(t.latestVersion, f), m = t.action.name;
68
+ for (let { update: t, index: a } of u) {
69
+ let o = !!t.latestSha, u = S[a], d = u.display;
70
+ u.versionForPadding && u.shortSha && (d = `${padString(u.versionForPadding, M + 1)}${pc.gray(`(${u.shortSha})`)}`);
71
+ let f = u.effectiveForDiff ?? t.currentVersion, p = formatVersion(t.latestVersion, f), m = t.action.name;
72
72
  if (t.latestSha) {
73
73
  let i = t.latestSha.slice(0, 7);
74
74
  p = `${padString(p, M + 1)}${pc.gray(`(${i})`)}`;
@@ -101,7 +101,7 @@ async function promptUpdateSelection(g, v = {}) {
101
101
  name: ""
102
102
  });
103
103
  else {
104
- let { update: i, index: a } = l[t - 1], s = !!i.latestSha, c = s && !i.isBreaking;
104
+ let { update: i, index: a } = u[t - 1], s = !!i.latestSha, c = s && !i.isBreaking;
105
105
  _.push({
106
106
  message: o,
107
107
  value: String(a),
@@ -4,18 +4,22 @@ import { GitHubAction } from '../../types/github-action';
4
4
  * object.
5
5
  *
6
6
  * @example
7
- * const action = parseActionReference(
8
- * 'actions/checkout@v3',
9
- * 'workflow.yml',
10
- * 10,
11
- * )
12
- * // Returns: {
13
- * // type: 'external',
14
- * // name: 'actions/checkout',
15
- * // version: 'v3',
16
- * // file: 'workflow.yml',
17
- * // line: 10,
18
- * // }
7
+ *
8
+ * ```ts
9
+ * const action = parseActionReference(
10
+ * 'actions/checkout@v3',
11
+ * 'workflow.yml',
12
+ * 10,
13
+ * )
14
+ * // Returns:
15
+ * // {
16
+ * // type: 'external',
17
+ * // name: 'actions/checkout',
18
+ * // version: 'v3',
19
+ * // file: 'workflow.yml',
20
+ * // line: 10,
21
+ * // }
22
+ * ```
19
23
  *
20
24
  * @param reference - The action reference string to parse. Can be:
21
25
  *
@@ -4,7 +4,10 @@ import { ScanResult } from '../types/scan-result';
4
4
  * actions.
5
5
  *
6
6
  * @example
7
- * const result = await scanGitHubActions('/path/to/repo')
7
+ *
8
+ * ```ts
9
+ * const result = await scanGitHubActions('/path/to/repo')
10
+ * ```
8
11
  *
9
12
  * @param rootPath - The root path of the repository to scan. Defaults to
10
13
  * current working directory.