actions-up 1.13.0 → 1.14.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.
@@ -1,4 +1,5 @@
1
1
  import { ActionUpdate } from '../types/action-update';
2
+ import { UpdateStyle } from '../types/update-style';
2
3
  import { ScanResult } from '../types/scan-result';
3
4
  import { UpdateMode } from '../types/update-mode';
4
5
  /**
@@ -49,6 +50,10 @@ interface BuildJsonReportOptions {
49
50
  * Whether recursive scanning mode is enabled.
50
51
  */
51
52
  recursive: boolean;
53
+ /**
54
+ * Effective update style for the run.
55
+ */
56
+ style: UpdateStyle;
52
57
  /**
53
58
  * Effective update mode for the run.
54
59
  */
@@ -66,6 +71,14 @@ interface BuildJsonReportOptions {
66
71
  * Serialized update entry in the JSON report.
67
72
  */
68
73
  interface JsonReportUpdate {
74
+ /**
75
+ * Style of the final reference.
76
+ */
77
+ targetRefStyle: NonNullable<ActionUpdate['targetRefStyle']> | null;
78
+ /**
79
+ * Detected style of the current reference in the source file.
80
+ */
81
+ currentRefType: ActionUpdate['currentRefType'] | null;
69
82
  /**
70
83
  * Reason why this entry was skipped, if any.
71
84
  */
@@ -94,6 +107,10 @@ interface JsonReportUpdate {
94
107
  * Resolved SHA for the target version.
95
108
  */
96
109
  latestSha: string | null;
110
+ /**
111
+ * Final reference that would be written back to the file.
112
+ */
113
+ targetRef: string | null;
97
114
  /**
98
115
  * Whether this update crosses a major version boundary.
99
116
  */
@@ -141,78 +158,82 @@ interface JsonReportSummary {
141
158
  totalUpdates: number;
142
159
  }
143
160
  /**
144
- * Serialized action reference included in each update entry.
161
+ * Effective CLI options serialized into the report.
145
162
  */
146
- interface JsonReportAction {
163
+ interface JsonReportOptions {
147
164
  /**
148
- * Action reference type detected during scanning.
165
+ * Regex patterns supplied through `--exclude`.
149
166
  */
150
- type: ActionUpdate['action']['type'];
167
+ excludePatterns: string[];
151
168
  /**
152
- * Original version or ref from the file, if available.
169
+ * Whether branch references were checked.
153
170
  */
154
- version: string | null;
171
+ includeBranches: boolean;
155
172
  /**
156
- * Relative or absolute file path for the action reference.
173
+ * Resolved scan directories.
157
174
  */
158
- file: string | null;
175
+ directories: string[];
159
176
  /**
160
- * Line number of the action reference.
177
+ * Whether recursive scanning mode is enabled.
161
178
  */
162
- line: number | null;
179
+ recursive: boolean;
163
180
  /**
164
- * Original `uses` value, if available.
181
+ * Effective update style.
165
182
  */
166
- uses: string | null;
183
+ style: UpdateStyle;
167
184
  /**
168
- * Workflow job name, when applicable.
185
+ * Effective update mode.
169
186
  */
170
- job: string | null;
187
+ mode: UpdateMode;
171
188
  /**
172
- * Full `owner/repo@ref` string, when available.
189
+ * Indicates that JSON mode never applies changes.
173
190
  */
174
- ref: string | null;
191
+ reportOnly: true;
175
192
  /**
176
- * Normalized action name.
193
+ * Minimum age filter in days.
177
194
  */
178
- name: string;
195
+ minAge: number;
196
+ /**
197
+ * Indicates that this payload came from `--json`.
198
+ */
199
+ json: true;
179
200
  }
180
201
  /**
181
- * Effective CLI options serialized into the report.
202
+ * Serialized action reference included in each update entry.
182
203
  */
183
- interface JsonReportOptions {
204
+ interface JsonReportAction {
184
205
  /**
185
- * Regex patterns supplied through `--exclude`.
206
+ * Action reference type detected during scanning.
186
207
  */
187
- excludePatterns: string[];
208
+ type: ActionUpdate['action']['type'];
188
209
  /**
189
- * Whether branch references were checked.
210
+ * Original version or ref from the file, if available.
190
211
  */
191
- includeBranches: boolean;
212
+ version: string | null;
192
213
  /**
193
- * Resolved scan directories.
214
+ * Relative or absolute file path for the action reference.
194
215
  */
195
- directories: string[];
216
+ file: string | null;
196
217
  /**
197
- * Whether recursive scanning mode is enabled.
218
+ * Line number of the action reference.
198
219
  */
199
- recursive: boolean;
220
+ line: number | null;
200
221
  /**
201
- * Effective update mode.
222
+ * Original `uses` value, if available.
202
223
  */
203
- mode: UpdateMode;
224
+ uses: string | null;
204
225
  /**
205
- * Indicates that JSON mode never applies changes.
226
+ * Workflow job name, when applicable.
206
227
  */
207
- reportOnly: true;
228
+ job: string | null;
208
229
  /**
209
- * Minimum age filter in days.
230
+ * Full `owner/repo@ref` string, when available.
210
231
  */
211
- minAge: number;
232
+ ref: string | null;
212
233
  /**
213
- * Indicates that this payload came from `--json`.
234
+ * Normalized action name.
214
235
  */
215
- json: true;
236
+ name: string;
216
237
  }
217
238
  /**
218
239
  * Top-level machine-readable report emitted by `--json`.
@@ -18,6 +18,7 @@ function buildJsonReport(e) {
18
18
  includeBranches: e.includeBranches,
19
19
  recursive: e.recursive,
20
20
  minAge: e.minAge,
21
+ style: e.style,
21
22
  mode: e.mode,
22
23
  reportOnly: !0,
23
24
  json: !0
@@ -42,9 +43,12 @@ function serializeUpdate(e, n) {
42
43
  type: e.action.type
43
44
  },
44
45
  publishedAt: e.publishedAt?.toISOString() ?? null,
46
+ currentRefType: e.currentRefType ?? null,
47
+ targetRefStyle: e.targetRefStyle ?? null,
45
48
  currentVersion: e.currentVersion,
46
49
  skipReason: e.skipReason ?? null,
47
50
  latestVersion: e.latestVersion,
51
+ targetRef: e.targetRef ?? null,
48
52
  isBreaking: e.isBreaking,
49
53
  status: e.status ?? "ok",
50
54
  hasUpdate: e.hasUpdate,
package/dist/cli/index.js CHANGED
@@ -1,11 +1,13 @@
1
1
  import { readInlineVersionComment } from "../core/versions/read-inline-version-comment.js";
2
2
  import { isSha } from "../core/versions/is-sha.js";
3
3
  import { promptUpdateSelection } from "../core/interactive/prompt-update-selection.js";
4
+ import { resolveTargetReference } from "../core/updates/resolve-target-reference.js";
4
5
  import { getCompatibleUpdate } from "../core/api/get-compatible-update.js";
5
6
  import { createGitHubClient } from "../core/api/create-github-client.js";
6
7
  import { resolveScanDirectories } from "./resolve-scan-directories.js";
7
8
  import { getUpdateLevel } from "../core/versions/get-update-level.js";
8
9
  import { applyUpdates } from "../core/ast/update/apply-updates.js";
10
+ import { normalizeUpdateStyle } from "./normalize-update-style.js";
9
11
  import { printSkippedWarning } from "./print-skipped-warning.js";
10
12
  import { normalizeUpdateMode } from "./normalize-update-mode.js";
11
13
  import { validateCliOptions } from "./validate-cli-options.js";
@@ -24,161 +26,174 @@ import "node:worker_threads";
24
26
  import pc from "picocolors";
25
27
  import cac from "cac";
26
28
  function run() {
27
- let C = cac("actions-up");
28
- C.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("--json", "Output update information as machine-readable JSON").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 (b) => {
29
- let S = b.json ?? !1, C = null, w = resolveScanDirectories({
30
- recursive: b.recursive,
29
+ let T = cac("actions-up");
30
+ T.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("--json", "Output update information as machine-readable JSON").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("--style <style>", "Update style: sha or preserve (default: sha)", { default: "sha" }).option("--recursive, -r", "Recursively scan directories for YAML files").option("--yes, -y", "Skip all confirmations").command("", "Update GitHub Actions").action(async (S) => {
31
+ let w = S.json ?? !1, T = null, E = resolveScanDirectories({
32
+ recursive: S.recursive,
31
33
  cwd: process.cwd(),
32
- dir: b.dir
33
- }), T = w.map(({ root: e, dir: f }) => resolve(e, f)), E = b.includeBranches ?? !1, D = normalizeUpdateMode(b.mode), O = [];
34
- Array.isArray(b.exclude) ? O.push(...b.exclude) : typeof b.exclude == "string" && O.push(b.exclude);
35
- let k = O.flatMap((e) => e.split(",")).map((e) => e.trim()).filter(Boolean);
34
+ dir: S.dir
35
+ }), D = E.map(({ root: e, dir: p }) => resolve(e, p)), O = S.includeBranches ?? !1, k = normalizeUpdateMode(S.mode), A = normalizeUpdateStyle(S.style), j = [];
36
+ Array.isArray(S.exclude) ? j.push(...S.exclude) : typeof S.exclude == "string" && j.push(S.exclude);
37
+ let M = j.flatMap((e) => e.split(",")).map((e) => e.trim()).filter(Boolean);
36
38
  try {
37
39
  validateCliOptions({
38
- yes: b.yes,
39
- json: S
40
- }), S || (console.info(pc.cyan("\n🚀 Actions Up!\n")), C = createSpinner("Scanning GitHub Actions...").start());
41
- function g({ actionsToCheckCount: e, blockedByMode: f = [], outdated: p = [], skipped: m = [], scanResult: h, status: g }) {
40
+ yes: S.yes,
41
+ json: w
42
+ }), w || (console.info(pc.cyan("\n🚀 Actions Up!\n")), T = createSpinner("Scanning GitHub Actions...").start());
43
+ function v({ actionsToCheckCount: e, blockedByMode: p = [], outdated: m = [], skipped: h = [], scanResult: g, status: _ }) {
42
44
  process.stdout.write(`${JSON.stringify(buildJsonReport({
43
- recursive: b.recursive ?? !1,
44
- excludePatterns: k,
45
- directories: T,
46
- minAge: b.minAge,
45
+ recursive: S.recursive ?? !1,
46
+ excludePatterns: M,
47
+ directories: D,
48
+ minAge: S.minAge,
47
49
  actionsToCheckCount: e,
48
- includeBranches: E,
49
- blockedByMode: f,
50
- scanResult: h,
51
- outdated: p,
52
- skipped: m,
53
- status: g,
54
- mode: D
50
+ includeBranches: O,
51
+ blockedByMode: p,
52
+ scanResult: g,
53
+ outdated: m,
54
+ skipped: h,
55
+ status: _,
56
+ style: A,
57
+ mode: k
55
58
  }), null, 2)}\n`);
56
59
  }
57
- let y = mergeScanResults(b.recursive ? await Promise.all(w.map(({ root: e, dir: f }) => scanRecursive(e, f))) : await Promise.all(w.map(({ root: e, dir: f }) => scanGitHubActions(e, f)))), x = y.actions.length, O = y.workflows.size, A = y.compositeActions.size;
58
- if (C?.success(`Found ${pc.yellow(x)} actions in ${pc.yellow(O)} workflows and ${pc.yellow(A)} composite actions`), x === 0) {
59
- if (S) {
60
- g({
60
+ let b = mergeScanResults(S.recursive ? await Promise.all(E.map(({ root: e, dir: p }) => scanRecursive(e, p))) : await Promise.all(E.map(({ root: e, dir: p }) => scanGitHubActions(e, p)))), x = b.actions.length, C = b.workflows.size, j = b.compositeActions.size;
61
+ if (T?.success(`Found ${pc.yellow(x)} actions in ${pc.yellow(C)} workflows and ${pc.yellow(j)} composite actions`), x === 0) {
62
+ if (w) {
63
+ v({
61
64
  status: "no-actions-found",
62
65
  actionsToCheckCount: 0,
63
- scanResult: y
66
+ scanResult: b
64
67
  });
65
68
  return;
66
69
  }
67
70
  console.info(pc.green("\n✨ No GitHub Actions found in this repository"));
68
71
  return;
69
72
  }
70
- let j = y.actions;
71
- if (k.length > 0) {
72
- let { parseExcludePatterns: e } = await import("../core/filters/parse-exclude-patterns.js"), f = e(k);
73
- f.length > 0 && (j = j.filter((e) => {
74
- let { name: p } = e;
75
- for (let e of f) if (e.test(p)) return !1;
73
+ let N = b.actions;
74
+ if (M.length > 0) {
75
+ let { parseExcludePatterns: e } = await import("../core/filters/parse-exclude-patterns.js"), p = e(M);
76
+ p.length > 0 && (N = N.filter((e) => {
77
+ let { name: m } = e;
78
+ for (let e of p) if (e.test(m)) return !1;
76
79
  return !0;
77
80
  }));
78
81
  }
79
- if (S || (C = createSpinner("Checking for updates...").start()), j.length === 0) {
80
- if (C?.success("No actions to check after excludes"), S) {
81
- g({
82
+ if (w || (T = createSpinner("Checking for updates...").start()), N.length === 0) {
83
+ if (T?.success("No actions to check after excludes"), w) {
84
+ v({
82
85
  status: "nothing-to-check",
83
86
  actionsToCheckCount: 0,
84
- scanResult: y
87
+ scanResult: b
85
88
  });
86
89
  return;
87
90
  }
88
91
  console.info(pc.green("\n✨ Nothing to check after excludes\n"));
89
92
  return;
90
93
  }
91
- let M = process.env.GITHUB_TOKEN, N = createGitHubClient(M), P = await checkUpdates(j, M, {
92
- client: N,
93
- includeBranches: E
94
- }), F = [];
95
- await Promise.all(P.map(async (e) => {
96
- await shouldIgnore(e.action.file, e.action.line) || F.push(e);
94
+ let P = process.env.GITHUB_TOKEN, F = createGitHubClient(P), I = await checkUpdates(N, P, {
95
+ client: F,
96
+ includeBranches: O,
97
+ style: A
98
+ }), L = [];
99
+ await Promise.all(I.map(async (e) => {
100
+ await shouldIgnore(e.action.file, e.action.line) || L.push(e);
97
101
  }));
98
- let I = F.filter((e) => e.status === "skipped"), L = F.filter((e) => e.hasUpdate), R = b.minAge * 24 * 60 * 60 * 1e3, z = Date.now();
99
- L = L.filter((e) => e.publishedAt ? z - e.publishedAt.getTime() >= R : !0);
100
- let B = [];
101
- if (D !== "major") {
102
- let p = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), g = /* @__PURE__ */ new Map(), _ = await Promise.all(L.map(async (p) => {
103
- let m = p.currentVersion;
104
- if (isSha(p.currentVersion)) {
105
- let f = await readInlineVersionComment(p.action.file, p.action.line, g);
106
- f && (m = f);
102
+ let R = L.filter((e) => e.status === "skipped"), z = L.filter((e) => e.hasUpdate), B = S.minAge * 24 * 60 * 60 * 1e3, V = Date.now();
103
+ z = z.filter((e) => e.publishedAt ? V - e.publishedAt.getTime() >= B : !0);
104
+ let H = [];
105
+ if (k !== "major") {
106
+ let m = /* @__PURE__ */ new Map(), h = /* @__PURE__ */ new Map(), _ = /* @__PURE__ */ new Map(), v = await Promise.all(z.map(async (m) => {
107
+ let h = m.currentVersion;
108
+ if (isSha(m.currentVersion)) {
109
+ let p = await readInlineVersionComment(m.action.file, m.action.line, _);
110
+ p && (h = p);
107
111
  }
108
- let h = getUpdateLevel(m, p.latestVersion);
112
+ let g = getUpdateLevel(h, m.latestVersion);
109
113
  return {
110
- effectiveCurrentVersion: m,
111
- allowed: D === "minor" ? h === "minor" || h === "patch" || h === "none" : h === "patch" || h === "none",
112
- update: p
114
+ effectiveCurrentVersion: h,
115
+ allowed: k === "minor" ? g === "minor" || g === "patch" || g === "none" : g === "patch" || g === "none",
116
+ update: m
113
117
  };
114
- })), v = [], y = await Promise.all(_.map(async (e) => {
118
+ })), y = [], b = await Promise.all(v.map(async (e) => {
115
119
  if (e.allowed) return { update: e.update };
116
- let f = await getCompatibleUpdate(N, {
120
+ let p = await getCompatibleUpdate(F, {
117
121
  currentVersion: e.effectiveCurrentVersion,
118
122
  actionName: e.update.action.name,
119
- tagsCache: p,
123
+ tagsCache: m,
120
124
  shaCache: h,
121
- mode: D
125
+ mode: k
122
126
  });
123
- return f ? { update: {
127
+ return p ? { update: {
124
128
  ...e.update,
125
- latestVersion: f.version,
126
- latestSha: f.sha,
129
+ latestVersion: p.version,
130
+ latestSha: p.sha,
127
131
  isBreaking: !1,
128
132
  hasUpdate: !0
129
133
  } } : { blocked: e.update };
130
134
  }));
131
- for (let e of y) {
135
+ for (let e of b) {
132
136
  if (e.update) {
133
- v.push(e.update);
137
+ y.push(e.update);
134
138
  continue;
135
139
  }
136
- B.push(e.blocked);
140
+ H.push(e.blocked);
137
141
  }
138
- L = v;
142
+ z = y;
139
143
  }
140
- let V = L.filter((e) => e.isBreaking);
141
- if (L.length === 0) {
142
- if (C?.success("All actions are up to date!"), S) {
143
- g({
144
- actionsToCheckCount: j.length,
144
+ z = z.map((e) => resolveTargetReference(e, A));
145
+ let U = z.filter((e) => !e.targetRef).map((e) => ({
146
+ ...e,
147
+ skipReason: "unsupported-style",
148
+ status: "skipped",
149
+ hasUpdate: !1
150
+ }));
151
+ R.push(...U), z = z.filter((e) => e.targetRef);
152
+ let W = z.filter((e) => e.isBreaking);
153
+ if (z.length === 0) {
154
+ if (T?.success("All actions are up to date!"), w) {
155
+ v({
156
+ actionsToCheckCount: N.length,
145
157
  status: "up-to-date",
146
- blockedByMode: B,
147
- scanResult: y,
148
- skipped: I
158
+ blockedByMode: H,
159
+ scanResult: b,
160
+ skipped: R
149
161
  });
150
162
  return;
151
163
  }
152
- I.length > 0 && printSkippedWarning(I, E), B.length > 0 && printModeWarning(B, D), console.info(pc.green("\n✨ Everything is already at the latest version!\n"));
164
+ R.length > 0 && printSkippedWarning(R, O, A), H.length > 0 && printModeWarning(H, k), console.info(pc.green("\n✨ Everything is already at the latest version!\n"));
153
165
  return;
154
166
  }
155
- if (C?.success(`Found ${pc.yellow(L.length)} updates available${V.length > 0 ? ` (${pc.redBright(V.length)} breaking)` : ""}`), S) {
156
- g({
157
- actionsToCheckCount: j.length,
167
+ if (T?.success(`Found ${pc.yellow(z.length)} updates available${W.length > 0 ? ` (${pc.redBright(W.length)} breaking)` : ""}`), w) {
168
+ v({
169
+ actionsToCheckCount: N.length,
158
170
  status: "updates-available",
159
- blockedByMode: B,
160
- scanResult: y,
161
- outdated: L,
162
- skipped: I
171
+ blockedByMode: H,
172
+ scanResult: b,
173
+ outdated: z,
174
+ skipped: R
163
175
  });
164
176
  return;
165
177
  }
166
- if (I.length > 0 && printSkippedWarning(I, E), B.length > 0 && printModeWarning(B, D), b.dryRun) {
178
+ if (R.length > 0 && printSkippedWarning(R, O, A), H.length > 0 && printModeWarning(H, k), S.dryRun) {
167
179
  console.info(pc.yellow("\n📋 Dry Run - No changes will be made\n"));
168
- for (let e of L) 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`);
169
- console.info(pc.gray(`\n${L.length} actions would be updated\n`));
180
+ for (let e of z) {
181
+ let p = e.targetRefStyle === "sha" && e.targetRef ? `${e.latestVersion} ${pc.gray(`(${e.targetRef.slice(0, 7)})`)}` : e.targetRef ?? e.latestVersion;
182
+ console.info(`${pc.cyan(e.action.file ?? "unknown")}:\n${e.action.name}: ${pc.redBright(e.currentVersion)} → ${pc.green(p)}\n`);
183
+ }
184
+ console.info(pc.gray(`\n${z.length} actions would be updated\n`));
170
185
  return;
171
186
  }
172
- if (b.yes) {
173
- let e = L.filter((e) => e.latestSha);
187
+ if (S.yes) {
188
+ let e = z.filter((e) => e.targetRef);
174
189
  if (e.length === 0) {
175
- console.info(pc.yellow("\n⚠️ No actions with SHA available for update\n"));
190
+ console.info(pc.yellow("\n⚠️ No actionable updates available\n"));
176
191
  return;
177
192
  }
178
193
  console.info(pc.yellow(`\n🔄 Updating ${e.length} actions...\n`)), await applyUpdates(e), console.info(pc.green("\n✓ Updates applied successfully!"));
179
194
  } else {
180
- (I.length > 0 || B.length > 0) && console.info("");
181
- let e = await promptUpdateSelection(L, { showAge: b.minAge > 0 });
195
+ (R.length > 0 || H.length > 0) && console.info("");
196
+ let e = await promptUpdateSelection(z, { showAge: S.minAge > 0 });
182
197
  if (!e || e.length === 0) {
183
198
  console.info(pc.gray("\nNo updates applied"));
184
199
  return;
@@ -186,8 +201,8 @@ function run() {
186
201
  console.info(pc.yellow(`\n🔄 Updating ${e.length} selected actions...\n`)), await applyUpdates(e), console.info(pc.green("\n✓ Updates applied successfully!"));
187
202
  }
188
203
  } catch (e) {
189
- 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);
204
+ T?.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);
190
205
  }
191
- }), C.parse();
206
+ }), T.parse();
192
207
  }
193
208
  export { run };
@@ -0,0 +1,8 @@
1
+ import { UpdateStyle } from '../types/update-style';
2
+ /**
3
+ * Normalizes the update style option.
4
+ *
5
+ * @param style - Raw style option.
6
+ * @returns Normalized update style.
7
+ */
8
+ export declare function normalizeUpdateStyle(style: undefined | string): UpdateStyle;
@@ -0,0 +1,6 @@
1
+ function normalizeUpdateStyle(e) {
2
+ let t = (e ?? "sha").toLowerCase();
3
+ if (t === "preserve" || t === "sha") return t;
4
+ throw Error(`Invalid style "${e}". Expected "sha" or "preserve".`);
5
+ }
6
+ export { normalizeUpdateStyle };
@@ -1,8 +1,10 @@
1
+ import { UpdateStyle } from '../types/update-style';
1
2
  /**
2
3
  * Prints a warning message for actions that were skipped during scanning.
3
4
  *
4
5
  * @param skipped - Array of skipped actions with their current versions.
5
6
  * @param includeBranches - Whether branch-pinned actions are being checked.
7
+ * @param style - Effective update style for the current run.
6
8
  */
7
9
  export declare function printSkippedWarning(skipped: {
8
10
  action: {
@@ -10,5 +12,6 @@ export declare function printSkippedWarning(skipped: {
10
12
  uses?: string;
11
13
  name: string;
12
14
  };
15
+ skipReason?: 'unsupported-style' | 'unknown' | 'branch';
13
16
  currentVersion: string | null;
14
- }[], includeBranches: boolean): void;
17
+ }[], includeBranches: boolean, style: UpdateStyle): void;
@@ -1,7 +1,11 @@
1
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}`));
2
+ function printSkippedWarning(e, t, r) {
3
+ let i = e.filter((e) => e.skipReason === "branch" || e.skipReason === void 0), a = e.filter((e) => e.skipReason === "unsupported-style");
4
+ i.length > 0 && printSkippedGroup(i, t ? "pinned to branches" : "pinned to branches (use --include-branches to check them)"), a.length > 0 && printSkippedGroup(a, r === "preserve" ? "whose current ref style could not be preserved" : "that could not be updated with the current style");
5
+ }
6
+ function printSkippedGroup(t, n) {
7
+ let r = new Intl.PluralRules("en-US", { type: "cardinal" }).select(t.length) === "one" ? "action" : "actions";
8
+ console.info(pc.yellow(`\n⚠️ Skipped ${t.length} ${r} ${n}`));
5
9
  for (let n of t) {
6
10
  let t = n.action.uses ?? `${n.action.name}@${n.currentVersion ?? "unknown"}`;
7
11
  console.info(pc.gray(` • ${t}`));
@@ -1,6 +1,7 @@
1
1
  import { GitHubClient } from '../../types/github-client';
2
2
  import { GitHubAction } from '../../types/github-action';
3
3
  import { ActionUpdate } from '../../types/action-update';
4
+ import { UpdateStyle } from '../../types/update-style';
4
5
  /**
5
6
  * Check for updates for GitHub Actions.
6
7
  *
@@ -13,4 +14,5 @@ import { ActionUpdate } from '../../types/action-update';
13
14
  export declare function checkUpdates(actions: GitHubAction[], token?: string, options?: {
14
15
  includeBranches?: boolean;
15
16
  client?: GitHubClient;
17
+ style?: UpdateStyle;
16
18
  }): Promise<ActionUpdate[]>;