diff --git a/lib/cli/build/index.tsx b/lib/cli/build/index.tsx
index 86f4232..958e17c 100644
--- a/lib/cli/build/index.tsx
+++ b/lib/cli/build/index.tsx
@@ -33,12 +33,17 @@ export async function build(args: string[]) {
);
}
- const { inProgress, done, unmount } = progress();
+ const { inProgress, done, fail, unmount } = progress();
try {
for (const workflowPath of workflowPaths) {
- await inProgress(`Building ${workflowPath}`);
- await _buildWorkflow(workflowPath);
- await done(getBuildTargetPath(workflowPath));
+ try {
+ await inProgress(`Building ${workflowPath}`);
+ await _buildWorkflow(workflowPath);
+ await done(getBuildTargetPath(workflowPath));
+ } catch (error) {
+ await fail(workflowPath);
+ throw error;
+ }
}
} finally {
unmount();
diff --git a/lib/cli/install/action-yaml.ts b/lib/cli/install/action-yaml.ts
index 044f4cd..4b6652e 100644
--- a/lib/cli/install/action-yaml.ts
+++ b/lib/cli/install/action-yaml.ts
@@ -1,7 +1,7 @@
import fs from "node:fs";
import path from "node:path";
import { parse as parseYaml } from "yaml";
-import { getFileContent } from "../../internal/git";
+import { getFileContent } from "../lib/github";
export type ActionYaml = {
inputs?: Record<
diff --git a/lib/cli/install/commit.ts b/lib/cli/install/commit.ts
index ac9dbf8..8f66f39 100644
--- a/lib/cli/install/commit.ts
+++ b/lib/cli/install/commit.ts
@@ -1,6 +1,6 @@
import * as fs from "node:fs";
import path from "node:path";
-import { getCommit as getCommitFromGithub } from "../../internal/git";
+import { getCommit as getCommitFromGithub } from "../lib/github";
type Cache = {
commit: string;
diff --git a/lib/cli/install/index.tsx b/lib/cli/install/index.tsx
index 0732331..81848bc 100644
--- a/lib/cli/install/index.tsx
+++ b/lib/cli/install/index.tsx
@@ -6,7 +6,7 @@ import {
saveActionsJson,
saveActionsLockJson,
} from "../../internal/actions";
-import { getLatestRelease } from "../../internal/git";
+import { getLatestRelease } from "../lib/github";
import { success } from "../ui/Message";
import { progress } from "../ui/Progress";
import { type ActionYaml, downloadActionYaml } from "./action-yaml";
@@ -50,47 +50,59 @@ export async function install(args: string[]) {
}
}
- const { inProgress, done, clear, unmount } = progress();
+ const { inProgress, fail, done, clear, unmount } = progress();
try {
for (const parsedAction of Object.values(targetActions)) {
await inProgress(
`Installing ${parsedAction.fullName}@${parsedAction.version}`,
);
- // get tag name
- const tagName = await (async () => {
- if (parsedAction.version == null || parsedAction.version === "latest") {
- const latestRelease = await getLatestRelease(
+ try {
+ // get tag name
+ const tagName = await (async () => {
+ if (
+ parsedAction.version == null ||
+ parsedAction.version === "latest"
+ ) {
+ const latestRelease = await getLatestRelease(
+ parsedAction.owner,
+ parsedAction.repo,
+ );
+ return latestRelease.tag_name;
+ }
+ return parsedAction.version;
+ })();
+
+ // get commit by tag name
+ const sha = await (async () => {
+ const lockedSha =
+ actionsLockJson.actions[`${parsedAction.fullName}@${tagName}`];
+ if (lockedSha != null) return lockedSha;
+ return await getCommit(
parsedAction.owner,
parsedAction.repo,
+ tagName,
);
- return latestRelease.tag_name;
- }
- return parsedAction.version;
- })();
-
- // get commit by tag name
- const sha = await (async () => {
- const lockedSha =
- actionsLockJson.actions[`${parsedAction.fullName}@${tagName}`];
- if (lockedSha != null) return lockedSha;
- return await getCommit(parsedAction.owner, parsedAction.repo, tagName);
- })();
-
- // update actions.json and actions-lock.json
- actionsJson[parsedAction.fullName] = tagName;
- actionsLockJson.actions[`${parsedAction.fullName}@${tagName}`] = sha;
-
- // download action.yml
- const actionYaml = await downloadActionYaml(
- parsedAction.owner,
- parsedAction.repo,
- parsedAction.action,
- sha,
- );
- actionYamls[parsedAction.fullName] = actionYaml;
-
- await done(`${parsedAction.fullName}@${tagName}`);
+ })();
+
+ // update actions.json and actions-lock.json
+ actionsJson[parsedAction.fullName] = tagName;
+ actionsLockJson.actions[`${parsedAction.fullName}@${tagName}`] = sha;
+
+ // download action.yml
+ const actionYaml = await downloadActionYaml(
+ parsedAction.owner,
+ parsedAction.repo,
+ parsedAction.action,
+ sha,
+ );
+ actionYamls[parsedAction.fullName] = actionYaml;
+
+ await done(`${parsedAction.fullName}@${tagName}`);
+ } catch (error) {
+ await fail(`${parsedAction.fullName}@${parsedAction.version}`);
+ throw error;
+ }
}
await inProgress("Building type definitions...");
diff --git a/lib/cli/install/type-def.ts b/lib/cli/install/type-def.ts
index a6d19be..c0e8fdf 100644
--- a/lib/cli/install/type-def.ts
+++ b/lib/cli/install/type-def.ts
@@ -1,4 +1,4 @@
-import { toUpperCamelCase } from "../../internal/util";
+import { toUpperCamelCase } from "../lib/util";
import type { ActionYaml } from "./action-yaml";
const actionJs = `import * as fs from "node:fs";
diff --git a/lib/internal/git.ts b/lib/cli/lib/github.ts
similarity index 100%
rename from lib/internal/git.ts
rename to lib/cli/lib/github.ts
diff --git a/lib/internal/util.spec.ts b/lib/cli/lib/util.spec.ts
similarity index 100%
rename from lib/internal/util.spec.ts
rename to lib/cli/lib/util.spec.ts
diff --git a/lib/internal/util.ts b/lib/cli/lib/util.ts
similarity index 100%
rename from lib/internal/util.ts
rename to lib/cli/lib/util.ts
diff --git a/lib/cli/ui/Progress.tsx b/lib/cli/ui/Progress.tsx
index 39521ba..a5a1c20 100644
--- a/lib/cli/ui/Progress.tsx
+++ b/lib/cli/ui/Progress.tsx
@@ -1,7 +1,7 @@
import { render, Static, Text } from "ink";
import Spinner from "./Spinner";
-export type ProgressStatus = "in-progress" | "done";
+export type ProgressStatus = "in-progress" | "done" | "fail";
export type ProgressProps = {
status: ProgressStatus;
@@ -32,6 +32,24 @@ export default function Progress({ status, title }: ProgressProps) {
);
}
+
+ if (status === "fail") {
+ return (
+
+ {(title) => (
+
+
+ ✗
+
+
+ {" "}
+ {title}
+
+
+ )}
+
+ );
+ }
}
export function progress() {
@@ -45,6 +63,9 @@ export function progress() {
done: async (title: string) => {
rerender();
},
+ fail: async (title: string) => {
+ rerender();
+ },
clear: async () => {
rerender(null);
await new Promise((resolve) => setTimeout(resolve)); // wait for the message to be cleared