@savvy-web/github-action-builder 0.7.4 → 0.7.6
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/github-action-builder.d.ts +1 -0
- package/bin/github-action-builder.js +39 -307
- package/cli/commands/build.js +91 -0
- package/cli/commands/index.js +5 -0
- package/cli/commands/init.js +247 -0
- package/cli/commands/validate.js +42 -0
- package/errors.js +284 -0
- package/github-action.js +302 -0
- package/index.d.ts +1567 -1820
- package/index.js +10 -134
- package/layers/app.js +83 -0
- package/package.json +74 -90
- package/schemas/action-yml.js +110 -0
- package/schemas/config.js +190 -0
- package/schemas/path.js +43 -0
- package/services/build-live.js +223 -0
- package/services/build.js +63 -0
- package/services/config-live.js +111 -0
- package/services/config.js +63 -0
- package/services/persist-local-live.js +210 -0
- package/services/persist-local.js +37 -0
- package/services/validation-live.js +216 -0
- package/services/validation.js +77 -0
- package/tsdoc-metadata.json +11 -11
- package/231.js +0 -5
- package/612.js +0 -5
- package/948.js +0 -931
- /package/{tsconfig → public/tsconfig}/action.json +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -1,317 +1,49 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { AppLayer } from "../layers/app.js";
|
|
3
|
+
import { buildCommand } from "../cli/commands/build.js";
|
|
4
|
+
import { initCommand } from "../cli/commands/init.js";
|
|
5
|
+
import { validateCommand } from "../cli/commands/validate.js";
|
|
6
|
+
import "../cli/commands/index.js";
|
|
7
|
+
import { Cause, Console, Effect, Layer } from "effect";
|
|
8
|
+
import { Command } from "@effect/cli";
|
|
3
9
|
import { NodeContext, NodeRuntime } from "@effect/platform-node";
|
|
4
|
-
import { Cause, Console, Effect, Layer, Option } from "effect";
|
|
5
|
-
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
6
|
-
import { resolve } from "node:path";
|
|
7
|
-
import { PersistLocalService, ValidationService, AppLayer, BuildService, ConfigService, ValidationFailed, BuildFailed } from "../948.js";
|
|
8
|
-
const configOption = Options.file("config").pipe(Options.withAlias("c"), Options.withDescription("Path to configuration file"), Options.optional);
|
|
9
|
-
const quietOption = Options.boolean("quiet").pipe(Options.withAlias("q"), Options.withDescription("Suppress non-error output"), Options.withDefault(false));
|
|
10
|
-
const noValidateOption = Options.boolean("no-validate").pipe(Options.withDescription("Skip validation step"), Options.withDefault(false));
|
|
11
|
-
const noPersistOption = Options.boolean("no-persist").pipe(Options.withDescription("Skip persisting build output to local action directory"), Options.withDefault(false));
|
|
12
|
-
const buildHandler = ({ config, quiet, noValidate, noPersist })=>Effect.gen(function*() {
|
|
13
|
-
const configService = yield* ConfigService;
|
|
14
|
-
const validationService = yield* ValidationService;
|
|
15
|
-
const buildService = yield* BuildService;
|
|
16
|
-
const persistLocalService = yield* PersistLocalService;
|
|
17
|
-
const cwd = process.cwd();
|
|
18
|
-
if (!quiet) yield* Console.log("Loading configuration...");
|
|
19
|
-
const loadOptions = Option.isSome(config) ? {
|
|
20
|
-
cwd,
|
|
21
|
-
configPath: config.value
|
|
22
|
-
} : {
|
|
23
|
-
cwd
|
|
24
|
-
};
|
|
25
|
-
const configResult = yield* configService.load(loadOptions);
|
|
26
|
-
if (!quiet) if (configResult.usingDefaults) yield* Console.log(" Using default configuration");
|
|
27
|
-
else yield* Console.log(` Found ${configResult.configPath}`);
|
|
28
|
-
if (!noValidate) {
|
|
29
|
-
if (!quiet) yield* Console.log("\nValidating...");
|
|
30
|
-
const validationResult = yield* validationService.validate(configResult.config, {
|
|
31
|
-
cwd
|
|
32
|
-
});
|
|
33
|
-
if (!validationResult.valid) {
|
|
34
|
-
yield* Console.error(`\n${validationService.formatResult(validationResult)}`);
|
|
35
|
-
return yield* new ValidationFailed({
|
|
36
|
-
errorCount: validationResult.errors.length,
|
|
37
|
-
warningCount: validationResult.warnings.length,
|
|
38
|
-
message: "Validation failed"
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
if (!quiet && validationResult.warnings.length > 0) yield* Console.log(validationService.formatResult(validationResult));
|
|
42
|
-
else if (!quiet) yield* Console.log(" All checks passed");
|
|
43
|
-
}
|
|
44
|
-
if (!quiet) yield* Console.log("\nBuilding...");
|
|
45
|
-
const buildResult = yield* buildService.build(configResult.config, {
|
|
46
|
-
cwd
|
|
47
|
-
});
|
|
48
|
-
if (!buildResult.success) {
|
|
49
|
-
yield* Console.error(`\nBuild failed: ${buildResult.error}`);
|
|
50
|
-
return yield* new BuildFailed({
|
|
51
|
-
message: buildResult.error ?? "One or more entries failed to build",
|
|
52
|
-
failedEntries: buildResult.entries.filter((e)=>!e.success).length
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
if (!quiet) {
|
|
56
|
-
yield* Console.log(`\n${buildService.formatResult(buildResult)}`);
|
|
57
|
-
yield* Console.log("\nBuild completed successfully!");
|
|
58
|
-
}
|
|
59
|
-
if (!noPersist && configResult.config.persistLocal.enabled) {
|
|
60
|
-
if (!quiet) yield* Console.log("\nPersisting to local action directory...");
|
|
61
|
-
const persistResult = yield* persistLocalService.persist(configResult.config, {
|
|
62
|
-
cwd
|
|
63
|
-
});
|
|
64
|
-
if (!quiet && persistResult.success) yield* Console.log(persistLocalService.formatResult(persistResult));
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
const buildCommand = Command.make("build", {
|
|
68
|
-
config: configOption,
|
|
69
|
-
quiet: quietOption,
|
|
70
|
-
noValidate: noValidateOption,
|
|
71
|
-
noPersist: noPersistOption
|
|
72
|
-
}, buildHandler);
|
|
73
|
-
const actionNameArg = Args.text({
|
|
74
|
-
name: "action-name"
|
|
75
|
-
}).pipe(Args.withDescription("Name of the GitHub Action (also the output directory)"));
|
|
76
|
-
const forceOption = Options.boolean("force").pipe(Options.withAlias("f"), Options.withDescription("Overwrite existing files"), Options.withDefault(false));
|
|
77
|
-
const getPackageVersion = ()=>"0.7.4";
|
|
78
|
-
const generatePackageJson = (name)=>{
|
|
79
|
-
const version = getPackageVersion();
|
|
80
|
-
const pkg = {
|
|
81
|
-
name,
|
|
82
|
-
version: "0.0.0",
|
|
83
|
-
private: true,
|
|
84
|
-
type: "module",
|
|
85
|
-
scripts: {
|
|
86
|
-
build: "github-action-builder build",
|
|
87
|
-
validate: "github-action-builder validate",
|
|
88
|
-
typecheck: "tsc --noEmit"
|
|
89
|
-
},
|
|
90
|
-
devDependencies: {
|
|
91
|
-
"@savvy-web/github-action-builder": `^${version}`,
|
|
92
|
-
typescript: "^5.9.3"
|
|
93
|
-
},
|
|
94
|
-
dependencies: {
|
|
95
|
-
"@actions/core": "^1.11.1",
|
|
96
|
-
"@actions/github": "^6.0.0"
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
return `${JSON.stringify(pkg, null, 2)}\n`;
|
|
100
|
-
};
|
|
101
|
-
const generateTsConfig = ()=>{
|
|
102
|
-
const config = {
|
|
103
|
-
compilerOptions: {
|
|
104
|
-
target: "ES2022",
|
|
105
|
-
module: "NodeNext",
|
|
106
|
-
moduleResolution: "NodeNext",
|
|
107
|
-
strict: true,
|
|
108
|
-
esModuleInterop: true,
|
|
109
|
-
skipLibCheck: true,
|
|
110
|
-
forceConsistentCasingInFileNames: true,
|
|
111
|
-
declaration: false,
|
|
112
|
-
outDir: "dist",
|
|
113
|
-
rootDir: "src"
|
|
114
|
-
},
|
|
115
|
-
include: [
|
|
116
|
-
"src/**/*.ts",
|
|
117
|
-
"action.config.ts"
|
|
118
|
-
],
|
|
119
|
-
exclude: [
|
|
120
|
-
"node_modules",
|
|
121
|
-
"dist"
|
|
122
|
-
]
|
|
123
|
-
};
|
|
124
|
-
return `${JSON.stringify(config, null, 2)}\n`;
|
|
125
|
-
};
|
|
126
|
-
const generateActionYml = (name)=>`name: "${name}"
|
|
127
|
-
description: "A GitHub Action built with @savvy-web/github-action-builder"
|
|
128
|
-
author: ""
|
|
129
10
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
description: "An example output"
|
|
139
|
-
|
|
140
|
-
runs:
|
|
141
|
-
using: "node24"
|
|
142
|
-
main: "dist/main.js"
|
|
143
|
-
pre: "dist/pre.js"
|
|
144
|
-
post: "dist/post.js"
|
|
145
|
-
|
|
146
|
-
branding:
|
|
147
|
-
icon: "zap"
|
|
148
|
-
color: "blue"
|
|
149
|
-
`;
|
|
150
|
-
const defaultConfig = `import { GitHubAction } from "@savvy-web/github-action-builder";
|
|
151
|
-
|
|
152
|
-
export default GitHubAction.create({
|
|
153
|
-
// Entry points are auto-detected from src/main.ts, src/pre.ts, src/post.ts
|
|
154
|
-
// Uncomment to customize:
|
|
155
|
-
// entries: {
|
|
156
|
-
// main: "src/main.ts",
|
|
157
|
-
// pre: "src/pre.ts",
|
|
158
|
-
// post: "src/post.ts",
|
|
159
|
-
// },
|
|
160
|
-
|
|
161
|
-
// Build options
|
|
162
|
-
// build: {
|
|
163
|
-
// minify: true,
|
|
164
|
-
// sourceMap: false,
|
|
165
|
-
// },
|
|
166
|
-
|
|
167
|
-
// Validation options
|
|
168
|
-
// validation: {
|
|
169
|
-
// strict: undefined, // Auto-detects CI environment
|
|
170
|
-
// },
|
|
171
|
-
});
|
|
172
|
-
`;
|
|
173
|
-
const mainTemplate = `import * as core from "@actions/core";
|
|
174
|
-
|
|
175
|
-
async function run(): Promise<void> {
|
|
176
|
-
try {
|
|
177
|
-
const input = core.getInput("example-input");
|
|
178
|
-
core.info(\`Running main action with input: \${input}\`);
|
|
179
|
-
|
|
180
|
-
// Your main action logic goes here
|
|
181
|
-
|
|
182
|
-
core.setOutput("example-output", "success");
|
|
183
|
-
} catch (error) {
|
|
184
|
-
if (error instanceof Error) {
|
|
185
|
-
core.setFailed(error.message);
|
|
186
|
-
} else {
|
|
187
|
-
core.setFailed("An unexpected error occurred");
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
run();
|
|
193
|
-
`;
|
|
194
|
-
const preTemplate = `import * as core from "@actions/core";
|
|
195
|
-
|
|
196
|
-
async function run(): Promise<void> {
|
|
197
|
-
try {
|
|
198
|
-
core.info("Running pre action...");
|
|
199
|
-
|
|
200
|
-
// Your pre-action setup logic goes here
|
|
201
|
-
// This runs before the main action
|
|
202
|
-
} catch (error) {
|
|
203
|
-
if (error instanceof Error) {
|
|
204
|
-
core.setFailed(error.message);
|
|
205
|
-
} else {
|
|
206
|
-
core.setFailed("An unexpected error occurred");
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
run();
|
|
212
|
-
`;
|
|
213
|
-
const postTemplate = `import * as core from "@actions/core";
|
|
214
|
-
|
|
215
|
-
async function run(): Promise<void> {
|
|
216
|
-
try {
|
|
217
|
-
core.info("Running post action...");
|
|
218
|
-
|
|
219
|
-
// Your post-action cleanup logic goes here
|
|
220
|
-
// This runs after the main action, even if it fails
|
|
221
|
-
} catch (error) {
|
|
222
|
-
if (error instanceof Error) {
|
|
223
|
-
core.warning(error.message);
|
|
224
|
-
} else {
|
|
225
|
-
core.warning("An unexpected error occurred during cleanup");
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
run();
|
|
231
|
-
`;
|
|
232
|
-
const writeFile = (path, content, force, createdFiles, skippedFiles)=>{
|
|
233
|
-
if (existsSync(path) && !force) return void skippedFiles.push(path);
|
|
234
|
-
writeFileSync(path, content, "utf-8");
|
|
235
|
-
createdFiles.push(path);
|
|
236
|
-
};
|
|
237
|
-
const initHandler = ({ actionName, force })=>Effect.gen(function*() {
|
|
238
|
-
const cwd = process.cwd();
|
|
239
|
-
const projectDir = resolve(cwd, actionName);
|
|
240
|
-
const createdFiles = [];
|
|
241
|
-
const skippedFiles = [];
|
|
242
|
-
if (existsSync(projectDir) && !force) {
|
|
243
|
-
yield* Console.error(`Directory already exists: ${actionName}`);
|
|
244
|
-
yield* Console.error("Use --force to overwrite existing files.");
|
|
245
|
-
return yield* Effect.fail(new Error("Directory exists"));
|
|
246
|
-
}
|
|
247
|
-
if (!existsSync(projectDir)) mkdirSync(projectDir, {
|
|
248
|
-
recursive: true
|
|
249
|
-
});
|
|
250
|
-
const srcDir = resolve(projectDir, "src");
|
|
251
|
-
if (!existsSync(srcDir)) mkdirSync(srcDir, {
|
|
252
|
-
recursive: true
|
|
253
|
-
});
|
|
254
|
-
writeFile(resolve(projectDir, "package.json"), generatePackageJson(actionName), force, createdFiles, skippedFiles);
|
|
255
|
-
writeFile(resolve(projectDir, "tsconfig.json"), generateTsConfig(), force, createdFiles, skippedFiles);
|
|
256
|
-
writeFile(resolve(projectDir, "action.yml"), generateActionYml(actionName), force, createdFiles, skippedFiles);
|
|
257
|
-
writeFile(resolve(projectDir, "action.config.ts"), defaultConfig, force, createdFiles, skippedFiles);
|
|
258
|
-
writeFile(resolve(srcDir, "main.ts"), mainTemplate, force, createdFiles, skippedFiles);
|
|
259
|
-
writeFile(resolve(srcDir, "pre.ts"), preTemplate, force, createdFiles, skippedFiles);
|
|
260
|
-
writeFile(resolve(srcDir, "post.ts"), postTemplate, force, createdFiles, skippedFiles);
|
|
261
|
-
yield* Console.log(`Created ${actionName}/`);
|
|
262
|
-
if (createdFiles.length > 0) for (const file of createdFiles)yield* Console.log(` ${file.replace(`${projectDir}/`, "")}`);
|
|
263
|
-
if (skippedFiles.length > 0) {
|
|
264
|
-
yield* Console.log("\nSkipped existing files (use --force to overwrite):");
|
|
265
|
-
for (const file of skippedFiles)yield* Console.log(` ${file.replace(`${projectDir}/`, "")}`);
|
|
266
|
-
}
|
|
267
|
-
yield* Console.log("\nNext steps:");
|
|
268
|
-
yield* Console.log(` cd ${actionName}`);
|
|
269
|
-
yield* Console.log(" npm install");
|
|
270
|
-
yield* Console.log(" npm run build");
|
|
271
|
-
});
|
|
272
|
-
const initCommand = Command.make("init", {
|
|
273
|
-
actionName: actionNameArg,
|
|
274
|
-
force: forceOption
|
|
275
|
-
}, initHandler);
|
|
276
|
-
const validateHandler = ({ config, quiet })=>Effect.gen(function*() {
|
|
277
|
-
const configService = yield* ConfigService;
|
|
278
|
-
const validationService = yield* ValidationService;
|
|
279
|
-
const cwd = process.cwd();
|
|
280
|
-
if (!quiet) yield* Console.log("Loading configuration...");
|
|
281
|
-
const loadOptions = Option.isSome(config) ? {
|
|
282
|
-
cwd,
|
|
283
|
-
configPath: config.value
|
|
284
|
-
} : {
|
|
285
|
-
cwd
|
|
286
|
-
};
|
|
287
|
-
const configResult = yield* configService.load(loadOptions);
|
|
288
|
-
if (!quiet) if (configResult.usingDefaults) yield* Console.log(" Using default configuration");
|
|
289
|
-
else yield* Console.log(` Found ${configResult.configPath}`);
|
|
290
|
-
if (!quiet) yield* Console.log("\nValidating...");
|
|
291
|
-
const validationResult = yield* validationService.validate(configResult.config, {
|
|
292
|
-
cwd
|
|
293
|
-
});
|
|
294
|
-
yield* Console.log(`\n${validationService.formatResult(validationResult)}`);
|
|
295
|
-
if (!validationResult.valid) return yield* Effect.fail(new Error("Validation failed"));
|
|
296
|
-
if (!quiet) yield* Console.log("\nValidation completed successfully!");
|
|
297
|
-
});
|
|
298
|
-
const validateCommand = Command.make("validate", {
|
|
299
|
-
config: configOption,
|
|
300
|
-
quiet: quietOption
|
|
301
|
-
}, validateHandler);
|
|
11
|
+
//#region src/cli/index.ts
|
|
12
|
+
/* v8 ignore start - CLI entry point requires integration testing */
|
|
13
|
+
/**
|
|
14
|
+
* GitHub Action Builder CLI entry point.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Root command for the CLI.
|
|
18
|
+
*/
|
|
302
19
|
const rootCommand = Command.make("github-action-builder").pipe(Command.withSubcommands([
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
20
|
+
buildCommand,
|
|
21
|
+
validateCommand,
|
|
22
|
+
initCommand
|
|
306
23
|
]));
|
|
24
|
+
/**
|
|
25
|
+
* CLI application configuration.
|
|
26
|
+
*/
|
|
307
27
|
const cli = Command.run(rootCommand, {
|
|
308
|
-
|
|
309
|
-
|
|
28
|
+
name: "github-action-builder",
|
|
29
|
+
version: process.env.__PACKAGE_VERSION__ ?? "0.0.0"
|
|
310
30
|
});
|
|
31
|
+
/**
|
|
32
|
+
* Combined layer: AppLayer + NodeContext for CLI.
|
|
33
|
+
*/
|
|
311
34
|
const CliLayer = Layer.merge(AppLayer, NodeContext.layer);
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Run the CLI with full error cause rendering.
|
|
37
|
+
*
|
|
38
|
+
* Expected typed errors (ValidationFailed, BuildFailed, etc.) are already
|
|
39
|
+
* printed by command handlers — they just need to exit with failure.
|
|
40
|
+
* Unexpected defects get full Cause.pretty rendering with stack traces.
|
|
41
|
+
*/
|
|
42
|
+
const main = Effect.suspend(() => cli(process.argv)).pipe(Effect.provide(CliLayer), Effect.catchAllCause((cause) => {
|
|
43
|
+
if (Cause.defects(cause).length > 0) return Console.error(Cause.pretty(cause)).pipe(Effect.andThen(Effect.failCause(cause)));
|
|
44
|
+
return Effect.failCause(cause);
|
|
316
45
|
}));
|
|
317
46
|
NodeRuntime.runMain(main);
|
|
47
|
+
|
|
48
|
+
//#endregion
|
|
49
|
+
export { };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { BuildFailed, ValidationFailed } from "../../errors.js";
|
|
2
|
+
import { BuildService } from "../../services/build.js";
|
|
3
|
+
import { ConfigService } from "../../services/config.js";
|
|
4
|
+
import { PersistLocalService } from "../../services/persist-local.js";
|
|
5
|
+
import { ValidationService } from "../../services/validation.js";
|
|
6
|
+
import { Console, Effect, Option } from "effect";
|
|
7
|
+
import { Command, Options } from "@effect/cli";
|
|
8
|
+
|
|
9
|
+
//#region src/cli/commands/build.ts
|
|
10
|
+
/* v8 ignore start - CLI commands require integration testing */
|
|
11
|
+
/**
|
|
12
|
+
* Build command for GitHub Action Builder CLI.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Config file option - shared across commands.
|
|
16
|
+
*/
|
|
17
|
+
const configOption = Options.file("config").pipe(Options.withAlias("c"), Options.withDescription("Path to configuration file"), Options.optional);
|
|
18
|
+
/**
|
|
19
|
+
* Quiet mode option - suppress non-error output.
|
|
20
|
+
*/
|
|
21
|
+
const quietOption = Options.boolean("quiet").pipe(Options.withAlias("q"), Options.withDescription("Suppress non-error output"), Options.withDefault(false));
|
|
22
|
+
/**
|
|
23
|
+
* Skip validation option.
|
|
24
|
+
*/
|
|
25
|
+
const noValidateOption = Options.boolean("no-validate").pipe(Options.withDescription("Skip validation step"), Options.withDefault(false));
|
|
26
|
+
/**
|
|
27
|
+
* Skip persist-local option.
|
|
28
|
+
*/
|
|
29
|
+
const noPersistOption = Options.boolean("no-persist").pipe(Options.withDescription("Skip persisting build output to local action directory"), Options.withDefault(false));
|
|
30
|
+
/**
|
|
31
|
+
* Build command handler using Effect services.
|
|
32
|
+
*/
|
|
33
|
+
const buildHandler = ({ config, quiet, noValidate, noPersist }) => Effect.gen(function* () {
|
|
34
|
+
const configService = yield* ConfigService;
|
|
35
|
+
const validationService = yield* ValidationService;
|
|
36
|
+
const buildService = yield* BuildService;
|
|
37
|
+
const persistLocalService = yield* PersistLocalService;
|
|
38
|
+
const cwd = process.cwd();
|
|
39
|
+
if (!quiet) yield* Console.log("Loading configuration...");
|
|
40
|
+
const loadOptions = Option.isSome(config) ? {
|
|
41
|
+
cwd,
|
|
42
|
+
configPath: config.value
|
|
43
|
+
} : { cwd };
|
|
44
|
+
const configResult = yield* configService.load(loadOptions);
|
|
45
|
+
if (!quiet) if (configResult.usingDefaults) yield* Console.log(" Using default configuration");
|
|
46
|
+
else yield* Console.log(` Found ${configResult.configPath}`);
|
|
47
|
+
if (!noValidate) {
|
|
48
|
+
if (!quiet) yield* Console.log("\nValidating...");
|
|
49
|
+
const validationResult = yield* validationService.validate(configResult.config, { cwd });
|
|
50
|
+
if (!validationResult.valid) {
|
|
51
|
+
yield* Console.error(`\n${validationService.formatResult(validationResult)}`);
|
|
52
|
+
return yield* new ValidationFailed({
|
|
53
|
+
errorCount: validationResult.errors.length,
|
|
54
|
+
warningCount: validationResult.warnings.length,
|
|
55
|
+
message: "Validation failed"
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (!quiet && validationResult.warnings.length > 0) yield* Console.log(validationService.formatResult(validationResult));
|
|
59
|
+
else if (!quiet) yield* Console.log(" All checks passed");
|
|
60
|
+
}
|
|
61
|
+
if (!quiet) yield* Console.log("\nBuilding...");
|
|
62
|
+
const buildResult = yield* buildService.build(configResult.config, { cwd });
|
|
63
|
+
if (!buildResult.success) {
|
|
64
|
+
yield* Console.error(`\nBuild failed: ${buildResult.error}`);
|
|
65
|
+
return yield* new BuildFailed({
|
|
66
|
+
message: buildResult.error ?? "One or more entries failed to build",
|
|
67
|
+
failedEntries: buildResult.entries.filter((e) => !e.success).length
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (!quiet) {
|
|
71
|
+
yield* Console.log(`\n${buildService.formatResult(buildResult)}`);
|
|
72
|
+
yield* Console.log("\nBuild completed successfully!");
|
|
73
|
+
}
|
|
74
|
+
if (!noPersist && configResult.config.persistLocal.enabled) {
|
|
75
|
+
if (!quiet) yield* Console.log("\nPersisting to local action directory...");
|
|
76
|
+
const persistResult = yield* persistLocalService.persist(configResult.config, { cwd });
|
|
77
|
+
if (!quiet && persistResult.success) yield* Console.log(persistLocalService.formatResult(persistResult));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
/**
|
|
81
|
+
* Build command - bundles GitHub Action entry points.
|
|
82
|
+
*/
|
|
83
|
+
const buildCommand = Command.make("build", {
|
|
84
|
+
config: configOption,
|
|
85
|
+
quiet: quietOption,
|
|
86
|
+
noValidate: noValidateOption,
|
|
87
|
+
noPersist: noPersistOption
|
|
88
|
+
}, buildHandler);
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
export { buildCommand, configOption, noValidateOption, quietOption };
|