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