actions-up 1.4.1 → 1.4.2

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/bin/actions-up.js CHANGED
File without changes
@@ -19,10 +19,9 @@ async function makeRequest(t, n, r = {}) {
19
19
  }
20
20
  throw e;
21
21
  }
22
- let s = await a.json();
23
22
  return {
24
23
  headers: o,
25
- data: s
24
+ data: await a.json()
26
25
  };
27
26
  }
28
27
  export { makeRequest };
@@ -19,20 +19,20 @@ function resolveGitHubTokenSync() {
19
19
  if (e) return e;
20
20
  } catch {}
21
21
  try {
22
- let t = join(process.cwd(), ".git", "config"), r = readFileSync(t, "utf8"), i = r.match(/^\s*(?:github\.(?:oauth-token|token)|hub\.oauthtoken)\s*=\s*(?<token>\S[^\n\r]*)$/mu)?.groups?.token?.trim();
23
- if (i) return i;
24
- let a = null;
25
- for (let e of r.split(/\r?\n/u)) {
22
+ let t = readFileSync(join(process.cwd(), ".git", "config"), "utf8"), r = t.match(/^\s*(?:github\.(?:oauth-token|token)|hub\.oauthtoken)\s*=\s*(?<token>\S[^\n\r]*)$/mu)?.groups?.token?.trim();
23
+ if (r) return r;
24
+ let i = null;
25
+ for (let e of t.split(/\r?\n/u)) {
26
26
  let t = e.trim(), n = t.match(/^\[(?<name>[^\]]+)\]$/u);
27
27
  if (n?.groups) {
28
- a = n.groups.name.toLowerCase();
28
+ i = n.groups.name.toLowerCase();
29
29
  continue;
30
30
  }
31
- if (a === "github") {
31
+ if (i === "github") {
32
32
  let e = t.match(/^(?:oauth-token|token)\s*=\s*(?<val>\S[^\n\r]*)$/u);
33
33
  if (e?.groups?.val) return e.groups.val.trim();
34
34
  }
35
- if (a === "hub") {
35
+ if (i === "hub") {
36
36
  let e = t.match(/^oauthtoken\s*=\s*(?<val>\S[^\n\r]*)$/u);
37
37
  if (e?.groups?.val) return e.groups.val.trim();
38
38
  }
@@ -5,17 +5,15 @@ import { isPair } from "../guards/is-pair.js";
5
5
  import { extractUsesFromSteps } from "../utils/extract-uses-from-steps.js";
6
6
  import { findMapPair } from "../utils/find-map-pair.js";
7
7
  function scanWorkflowAst(o, s, c) {
8
- let l = o.toJSON();
9
- if (!isWorkflowStructure(l) || !o.contents || !isYAMLMap(o.contents)) return [];
10
- let u = findMapPair(o.contents, "jobs");
11
- if (!u?.value || !isYAMLMap(u.value)) return [];
12
- let d = [];
13
- for (let e of u.value.items) {
8
+ if (!isWorkflowStructure(o.toJSON()) || !o.contents || !isYAMLMap(o.contents)) return [];
9
+ let l = findMapPair(o.contents, "jobs");
10
+ if (!l?.value || !isYAMLMap(l.value)) return [];
11
+ let u = [];
12
+ for (let e of l.value.items) {
14
13
  if (!isPair(e) || !e.value || !isNode(e.value) || !isYAMLMap(e.value)) continue;
15
14
  let o = findMapPair(e.value, "steps");
16
- if (!o?.value) continue;
17
- d.push(...extractUsesFromSteps(o.value, c, s));
15
+ o?.value && u.push(...extractUsesFromSteps(o.value, c, s));
18
16
  }
19
- return d;
17
+ return u;
20
18
  }
21
19
  export { scanWorkflowAst };
@@ -1,8 +1,6 @@
1
1
  import { stripAnsi } from "./strip-ansi.js";
2
2
  function padString(t, n) {
3
- let r = stripAnsi(t), i = n - r.length;
4
- if (i <= 0) return t;
5
- let a = " ".repeat(i);
6
- return t + a;
3
+ let r = n - stripAnsi(t).length;
4
+ return r <= 0 ? t : t + " ".repeat(r);
7
5
  }
8
6
  export { padString };
@@ -7,98 +7,99 @@ import pc from "picocolors";
7
7
  import { readFile } from "node:fs/promises";
8
8
  import enquirer from "enquirer";
9
9
  import path from "node:path";
10
- async function promptUpdateSelection(a) {
11
- if (a.length === 0) return null;
12
- let s = a.filter((e) => e.hasUpdate);
13
- if (s.length === 0) return console.info(pc.green("✓ All actions are up to date!")), null;
14
- let u = /* @__PURE__ */ new Map();
15
- for (let [e, i] of s.entries()) {
16
- let a = i.action.file ?? "unknown file", o = path.relative(path.join(process.cwd(), GITHUB_DIRECTORY), a);
17
- o === "" && (o = a);
18
- let s = u.get(o) ?? [];
19
- s.push({
20
- update: i,
10
+ var MIN_ACTION_WIDTH = 56, MIN_CURRENT_WIDTH = 16;
11
+ async function promptUpdateSelection(o) {
12
+ if (o.length === 0) return null;
13
+ let c = o.filter((e) => e.hasUpdate);
14
+ if (c.length === 0) return console.info(pc.green("✓ All actions are up to date!")), null;
15
+ let p = /* @__PURE__ */ new Map();
16
+ for (let [e, a] of c.entries()) {
17
+ let o = a.action.file ?? "unknown file", s = path.relative(path.join(process.cwd(), GITHUB_DIRECTORY), o);
18
+ s === "" && (s = o);
19
+ let c = p.get(s) ?? [];
20
+ c.push({
21
+ update: a,
21
22
  index: e
22
- }), u.set(o, s);
23
+ }), p.set(s, c);
23
24
  }
24
- let p = await Promise.all(s.map(async (e) => {
25
- let r = formatVersionOrSha(e.currentVersion), i = e.currentVersion ?? void 0;
25
+ let g = await Promise.all(c.map(async (e) => {
26
+ let i = formatVersionOrSha(e.currentVersion), a = e.currentVersion ?? void 0;
26
27
  if (!e.currentVersion || !isSha(e.currentVersion)) return {
27
- effectiveForDiff: i,
28
- display: r
28
+ effectiveForDiff: a,
29
+ display: i
29
30
  };
30
- let a = await tryReadInlineVersionComment(e.action.file, e.action.line);
31
- if (a) {
32
- let s = e.currentVersion.slice(0, 7);
33
- r = `${formatVersionOrSha(a)} ${pc.gray(`(${s})`)}`, i = a;
31
+ let o = await tryReadInlineVersionComment(e.action.file, e.action.line);
32
+ if (o) {
33
+ let c = e.currentVersion.slice(0, 7);
34
+ i = `${formatVersionOrSha(o)} ${pc.gray(`(${c})`)}`, a = o;
34
35
  }
35
36
  return {
36
- effectiveForDiff: i,
37
- display: r
37
+ effectiveForDiff: a,
38
+ display: i
38
39
  };
39
- })), m = [], h = stripAnsi("Action").length, g = stripAnsi("Current").length;
40
- for (let [e, r] of s.entries()) {
41
- let a = r.action.name, o = p[e].display;
42
- h = Math.max(h, a.length), g = Math.max(g, stripAnsi(o).length);
40
+ })), _ = [], v = stripAnsi("Action").length, y = stripAnsi("Current").length;
41
+ for (let [e, i] of c.entries()) {
42
+ let o = i.action.name, s = g[e].display;
43
+ v = Math.max(v, o.length), y = Math.max(y, stripAnsi(s).length);
43
44
  }
44
- let _ = Math.max(h, 56), v = Math.max(g, 16), y = [...u.keys()].toSorted();
45
- for (let [r, i] of y.entries()) {
46
- let a = u.get(i);
47
- if (!a) {
48
- console.warn(`Unexpected missing group for file: ${i}`);
45
+ let b = Math.max(v, MIN_ACTION_WIDTH), x = Math.max(y, MIN_CURRENT_WIDTH), S = [...p.keys()].toSorted();
46
+ for (let [i, a] of S.entries()) {
47
+ let o = p.get(a);
48
+ if (!o) {
49
+ console.warn(`Unexpected missing group for file: ${a}`);
49
50
  continue;
50
51
  }
51
- let s = [], c = a;
52
- s.push({
52
+ let c = [], l = o;
53
+ c.push({
53
54
  current: "Current",
54
55
  action: "Action",
55
56
  target: "Target",
56
57
  arrow: "❯"
57
58
  });
58
- for (let { update: r, index: i } of c) {
59
- let a = !!r.latestSha, c = p[i].display, l = p[i]?.effectiveForDiff ?? r.currentVersion, u = formatVersion(r.latestVersion, l), d = r.action.name;
60
- if (r.latestSha) {
61
- let e = r.latestSha.slice(0, 7);
62
- u = `${u} ${pc.gray(`(${e})`)}`;
59
+ for (let { update: i, index: a } of l) {
60
+ let o = !!i.latestSha, l = g[a].display, u = g[a]?.effectiveForDiff ?? i.currentVersion, d = formatVersion(i.latestVersion, u), f = i.action.name;
61
+ if (i.latestSha) {
62
+ let e = i.latestSha.slice(0, 7);
63
+ d = `${d} ${pc.gray(`(${e})`)}`;
63
64
  }
64
- a || (u = pc.gray(u), c = pc.gray(c), d = pc.gray(d)), s.push({
65
- action: d,
66
- target: u,
65
+ o || (d = pc.gray(d), l = pc.gray(l), f = pc.gray(f)), c.push({
66
+ action: f,
67
+ target: d,
67
68
  arrow: "❯",
68
- current: c
69
+ current: l
69
70
  });
70
71
  }
71
- let l = Math.max(_, 56), d = Math.max(v, 16), f = [];
72
- for (let [e, r] of s.entries()) {
73
- let i = e === 0, a = formatTableRow(r, l, d);
74
- if (i) f.push({
75
- message: pc.gray(` ○ ${a}`),
72
+ let u = Math.max(b, MIN_ACTION_WIDTH), m = Math.max(x, MIN_CURRENT_WIDTH), h = [];
73
+ for (let [e, i] of c.entries()) {
74
+ let a = e === 0, o = formatTableRow(i, u, m);
75
+ if (a) h.push({
76
+ message: pc.gray(` ○ ${o}`),
76
77
  role: "separator",
77
78
  indent: "",
78
79
  name: ""
79
80
  });
80
81
  else {
81
- let r = c[e - 1];
82
- if (!r) continue;
83
- let { update: i, index: o } = r, s = !!i.latestSha, l = s && !i.isBreaking;
84
- f.push({
85
- message: a,
86
- value: String(o),
87
- name: String(o),
88
- disabled: !s,
82
+ let i = l[e - 1];
83
+ if (!i) continue;
84
+ let { update: a, index: s } = i, c = !!a.latestSha, u = c && !a.isBreaking;
85
+ h.push({
86
+ message: o,
87
+ value: String(s),
88
+ name: String(s),
89
+ disabled: !c,
89
90
  indent: "",
90
- enabled: l
91
+ enabled: u
91
92
  });
92
93
  }
93
94
  }
94
- m.push({
95
- message: pc.gray(i),
96
- value: `label|${i}`,
97
- choices: f,
98
- name: `label|${i}`,
95
+ _.push({
96
+ message: pc.gray(a),
97
+ value: `label|${a}`,
98
+ choices: h,
99
+ name: `label|${a}`,
99
100
  isGroupLabel: !0,
100
101
  enabled: !1
101
- }), r < y.length - 1 && m.push({
102
+ }), i < S.length - 1 && _.push({
102
103
  role: "separator",
103
104
  message: " ",
104
105
  name: ""
@@ -106,22 +107,22 @@ async function promptUpdateSelection(a) {
106
107
  }
107
108
  try {
108
109
  let e = {
109
- indicator(e, r) {
110
- if (r.isGroupLabel) {
111
- let e = (r.choices ?? []).filter((e) => !("role" in e)), i = e.length, a = e.filter((e) => !!e.enabled).length === i ? "●" : "○";
112
- return ` ${pc.gray(a)}`;
110
+ indicator(e, i) {
111
+ if (i.isGroupLabel) {
112
+ let e = (i.choices ?? []).filter((e) => !("role" in e)), a = e.length, o = e.filter((e) => !!e.enabled).length === a ? "●" : "○";
113
+ return ` ${pc.gray(o)}`;
113
114
  }
114
- return ` ${r.enabled ? "●" : "○"}`;
115
+ return ` ${i.enabled ? "●" : "○"}`;
115
116
  },
116
117
  message: `Choose which actions to update (Press ${pc.cyan("<space>")} to select, ${pc.cyan("<a>")} to toggle all, ${pc.cyan("<i>")} to invert selection)`,
117
- cancel() {
118
- return console.info(pc.yellow("\nSelection cancelled")), null;
119
- },
120
118
  styles: {
121
119
  success: pc.reset,
122
120
  em: pc.bgBlack,
123
121
  dark: pc.reset
124
122
  },
123
+ cancel() {
124
+ return logSelectionCancelled(), null;
125
+ },
125
126
  j() {
126
127
  return this.down?.() ?? Promise.resolve([]);
127
128
  },
@@ -132,49 +133,52 @@ async function promptUpdateSelection(a) {
132
133
  type: "multiselect",
133
134
  name: "selected",
134
135
  pointer: "❯",
135
- choices: m
136
- }, { selected: r } = await enquirer.prompt(e), i = /* @__PURE__ */ new Set();
137
- for (let e of r) {
136
+ choices: _
137
+ }, { selected: i } = await enquirer.prompt(e), a = /* @__PURE__ */ new Set();
138
+ for (let e of i) {
138
139
  if (e.startsWith("label|")) {
139
- let r = e.slice(6), a = u.get(r) ?? [];
140
- for (let { update: e, index: r } of a) e.latestSha && i.add(r);
140
+ let i = e.slice(6), o = p.get(i) ?? [];
141
+ for (let { update: e, index: i } of o) e.latestSha && a.add(i);
141
142
  continue;
142
143
  }
143
- let r = Number.parseInt(e, 10);
144
- Number.isFinite(r) && i.add(r);
144
+ let i = Number.parseInt(e, 10);
145
+ Number.isFinite(i) && a.add(i);
145
146
  }
146
- let a = [];
147
- for (let [e, r] of s.entries()) i.has(e) && r.latestSha && a.push(r);
148
- return a.length === 0 ? (console.info(pc.yellow("\nNo actions selected")), null) : a;
147
+ let o = [];
148
+ for (let [e, i] of c.entries()) a.has(e) && i.latestSha && o.push(i);
149
+ return o.length === 0 ? (console.info(pc.yellow("\nNo actions selected")), null) : o;
149
150
  } catch (e) {
150
- if (e instanceof Error && (e.message.includes("cancelled") || e.message.includes("ESC") || e.name === "ExitPromptError")) return console.info(pc.yellow("\nSelection cancelled")), null;
151
+ if (e instanceof Error && (e.message.includes("cancelled") || e.message.includes("ESC") || e.name === "ExitPromptError")) return logSelectionCancelled(), null;
151
152
  throw console.error(pc.red("Unexpected error during selection:"), e), e;
152
153
  }
153
154
  }
154
- async function tryReadInlineVersionComment(e, r) {
155
+ async function tryReadInlineVersionComment(e, i) {
155
156
  try {
156
- if (!e || !r || r <= 0) return null;
157
- let i = (await readFile(e, "utf8")).split("\n"), a = r - 1;
158
- if (a < 0 || a >= i.length) return null;
159
- let o = i[a].match(/#\s*(?<version>[Vv]?\d+(?:\.\d+){0,2}(?:[+-][\w\-.]+)?)/u);
160
- if (o?.groups?.version) return o.groups.version;
157
+ if (!e || !i || i <= 0) return null;
158
+ let a = (await readFile(e, "utf8")).split("\n"), o = i - 1;
159
+ if (o < 0 || o >= a.length) return null;
160
+ let s = a[o].match(/#\s*(?<version>[Vv]?\d+(?:\.\d+){0,2}(?:[+-][\w\-.]+)?)/u);
161
+ if (s?.groups?.version) return s.groups.version;
161
162
  } catch {}
162
163
  return null;
163
164
  }
164
- function formatTableRow(e, r, i) {
165
+ function formatTableRow(e, i, a) {
165
166
  return [
166
- padString(e.action, r),
167
- padString(e.current, i),
167
+ padString(e.action, i),
168
+ padString(e.current, a),
168
169
  e.arrow,
169
170
  e.target
170
171
  ].join(" ").replace(/\s+$/u, "");
171
172
  }
172
173
  function isSha(e) {
173
174
  if (!e) return !1;
174
- let r = e.replace(/^v/u, "");
175
- return /^[0-9a-f]{7,40}$/iu.test(r);
175
+ let i = e.replace(/^v/u, "");
176
+ return /^[0-9a-f]{7,40}$/iu.test(i);
176
177
  }
177
178
  function formatVersionOrSha(e) {
178
179
  return e ? isSha(e) ? e.slice(0, 7) : e.replace(/^v/u, "") : pc.gray("unknown");
179
180
  }
181
+ function logSelectionCancelled() {
182
+ console.info(`\r\u001B[K${pc.yellow("Selection cancelled")}`);
183
+ }
180
184
  export { promptUpdateSelection };
@@ -93,8 +93,7 @@ async function scanGitHubActions(d = process.cwd()) {
93
93
  let l = c.name.split("/");
94
94
  if (l.length < 3 || `${l[0]}/${l[1]}` !== e) continue;
95
95
  let u = join(h, ...l.slice(2));
96
- if (!g(h, u) || o.has(u)) continue;
97
- o.add(u), s.push(u);
96
+ g(h, u) && (o.has(u) || (o.add(u), s.push(u)));
98
97
  }
99
98
  async function c() {
100
99
  if (s.length === 0) return;
@@ -115,8 +114,7 @@ async function scanGitHubActions(d = process.cwd()) {
115
114
  let c = s.name.split("/");
116
115
  if (c.length < 3 || `${c[0]}/${c[1]}` !== e) continue;
117
116
  let l = join(h, ...c.slice(2));
118
- if (!g(h, l) || o.has(l)) continue;
119
- o.add(l), p.push(l);
117
+ g(h, l) && (o.has(l) || (o.add(l), p.push(l)));
120
118
  }
121
119
  return p;
122
120
  } catch {
@@ -135,10 +133,10 @@ async function getCurrentRepoSlug(e) {
135
133
  let o = process.env.GITHUB_REPOSITORY;
136
134
  if (o && /^[^\s/]+\/[^\s/]+$/u.test(o)) return o;
137
135
  try {
138
- let o = join(e, ".git", "config"), s = await readFile(o, "utf8"), c = s.match(/\[remote "origin"\][\s\S]*?url\s*=\s*(?<url>.+)/u)?.groups?.url?.trim();
139
- if (c ||= s.match(/url\s*=\s*(?<url>.+)/u)?.groups?.url?.trim(), !c) return null;
140
- let l = c.match(/github\.com[/:](?<owner>[^/]+)\/(?<repo>[^./]+)(?:\.git)?$/u);
141
- if (l?.groups) return `${l.groups.owner}/${l.groups.repo}`;
136
+ let o = await readFile(join(e, ".git", "config"), "utf8"), s = o.match(/\[remote "origin"\][\s\S]*?url\s*=\s*(?<url>.+)/u)?.groups?.url?.trim();
137
+ if (s ||= o.match(/url\s*=\s*(?<url>.+)/u)?.groups?.url?.trim(), !s) return null;
138
+ let c = s.match(/github\.com[/:](?<owner>[^/]+)\/(?<repo>[^./]+)(?:\.git)?$/u);
139
+ if (c?.groups) return `${c.groups.owner}/${c.groups.repo}`;
142
140
  } catch {}
143
141
  return null;
144
142
  }
package/dist/package.js CHANGED
@@ -1,2 +1,2 @@
1
- const version = "1.4.1";
1
+ const version = "1.4.2";
2
2
  export { version };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "actions-up",
3
- "version": "1.4.1",
3
+ "version": "1.4.2",
4
4
  "description": "Interactive CLI tool to update GitHub Actions to latest versions with SHA pinning",
5
5
  "keywords": [
6
6
  "github-actions",
@@ -40,7 +40,7 @@
40
40
  "enquirer": "^2.4.1",
41
41
  "nanospinner": "^1.2.2",
42
42
  "picocolors": "^1.1.1",
43
- "semver": "^7.7.2",
43
+ "semver": "^7.7.3",
44
44
  "yaml": "^2.8.1"
45
45
  },
46
46
  "engines": {