@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
package/github-action.js
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { BuildResultSchema, BuildService } from "./services/build.js";
|
|
2
|
+
import { defineConfig } from "./schemas/config.js";
|
|
3
|
+
import { ConfigService } from "./services/config.js";
|
|
4
|
+
import { PersistLocalResultSchema, PersistLocalService } from "./services/persist-local.js";
|
|
5
|
+
import { ValidationResultSchema, ValidationService } from "./services/validation.js";
|
|
6
|
+
import { AppLayer } from "./layers/app.js";
|
|
7
|
+
import { Effect, ManagedRuntime, Schema } from "effect";
|
|
8
|
+
|
|
9
|
+
//#region src/github-action.ts
|
|
10
|
+
/**
|
|
11
|
+
* Result of a GitHubAction build operation.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* The result contains detailed information about both validation and build steps.
|
|
15
|
+
* Check the `success` property first, then examine `error`, `validation`, or `build`
|
|
16
|
+
* for details.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
const GitHubActionBuildResultSchema = Schema.Struct({
|
|
21
|
+
/** Whether the build completed successfully. */
|
|
22
|
+
success: Schema.Boolean,
|
|
23
|
+
/** Build result details if the build step ran. */
|
|
24
|
+
build: Schema.optional(BuildResultSchema),
|
|
25
|
+
/** Validation result if validation was performed. */
|
|
26
|
+
validation: Schema.optional(ValidationResultSchema),
|
|
27
|
+
/** Persist-local result if persist was performed. */
|
|
28
|
+
persistLocal: Schema.optional(PersistLocalResultSchema),
|
|
29
|
+
/** Error message if the build or validation failed. */
|
|
30
|
+
error: Schema.optional(Schema.String),
|
|
31
|
+
/** Raw error object for programmatic inspection. */
|
|
32
|
+
cause: Schema.optional(Schema.Unknown)
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Main API class for building GitHub Actions.
|
|
36
|
+
*
|
|
37
|
+
* @remarks
|
|
38
|
+
* This class provides a Promise-based interface wrapping Effect services.
|
|
39
|
+
* It handles configuration loading, validation, and bundling in a single workflow.
|
|
40
|
+
*
|
|
41
|
+
* For Effect consumers, use the services directly:
|
|
42
|
+
* - {@link ConfigService} for configuration
|
|
43
|
+
* - {@link ValidationService} for validation
|
|
44
|
+
* - {@link BuildService} for building
|
|
45
|
+
*
|
|
46
|
+
* @example Complete build workflow
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { GitHubAction } from "@savvy-web/github-action-builder";
|
|
49
|
+
*
|
|
50
|
+
* async function buildAction(): Promise<void> {
|
|
51
|
+
* const action = GitHubAction.create();
|
|
52
|
+
* const result = await action.build();
|
|
53
|
+
*
|
|
54
|
+
* if (result.success) {
|
|
55
|
+
* console.log(`Built ${result.build?.entries.length} entry points`);
|
|
56
|
+
* } else {
|
|
57
|
+
* console.error(`Build failed: ${result.error}`);
|
|
58
|
+
* process.exit(1);
|
|
59
|
+
* }
|
|
60
|
+
* }
|
|
61
|
+
*
|
|
62
|
+
* buildAction();
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example With custom configuration
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { GitHubAction } from "@savvy-web/github-action-builder";
|
|
68
|
+
*
|
|
69
|
+
* async function main(): Promise<void> {
|
|
70
|
+
* const action = GitHubAction.create({
|
|
71
|
+
* config: {
|
|
72
|
+
* entries: { main: "src/action.ts" },
|
|
73
|
+
* build: { minify: true },
|
|
74
|
+
* },
|
|
75
|
+
* cwd: "/path/to/project",
|
|
76
|
+
* });
|
|
77
|
+
*
|
|
78
|
+
* const result = await action.build();
|
|
79
|
+
* console.log(result.success ? "Success" : result.error);
|
|
80
|
+
* }
|
|
81
|
+
*
|
|
82
|
+
* main();
|
|
83
|
+
* ```
|
|
84
|
+
*
|
|
85
|
+
* @public
|
|
86
|
+
*/
|
|
87
|
+
var GitHubAction = class GitHubAction {
|
|
88
|
+
/**
|
|
89
|
+
* Managed runtime for running Effects.
|
|
90
|
+
* @internal
|
|
91
|
+
*/
|
|
92
|
+
runtime;
|
|
93
|
+
/**
|
|
94
|
+
* Cached configuration after first load.
|
|
95
|
+
* @internal
|
|
96
|
+
*/
|
|
97
|
+
config = null;
|
|
98
|
+
/**
|
|
99
|
+
* Resolved options.
|
|
100
|
+
* @internal
|
|
101
|
+
*/
|
|
102
|
+
cwd;
|
|
103
|
+
configSource;
|
|
104
|
+
skipValidation;
|
|
105
|
+
clean;
|
|
106
|
+
constructor(options = {}) {
|
|
107
|
+
const layer = options.layer ?? AppLayer;
|
|
108
|
+
this.runtime = ManagedRuntime.make(layer);
|
|
109
|
+
this.configSource = options.config;
|
|
110
|
+
this.cwd = options.cwd ?? process.cwd();
|
|
111
|
+
this.skipValidation = options.skipValidation ?? false;
|
|
112
|
+
this.clean = options.clean ?? true;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Create a new GitHubAction builder instance.
|
|
116
|
+
*
|
|
117
|
+
* @param options - Builder options
|
|
118
|
+
* @returns A new GitHubAction instance
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* import { GitHubAction } from "@savvy-web/github-action-builder";
|
|
123
|
+
*
|
|
124
|
+
* // Auto-detect configuration
|
|
125
|
+
* const action = GitHubAction.create();
|
|
126
|
+
*
|
|
127
|
+
* // With inline config
|
|
128
|
+
* const action2 = GitHubAction.create({
|
|
129
|
+
* config: { build: { minify: false } },
|
|
130
|
+
* });
|
|
131
|
+
*
|
|
132
|
+
* // With config file path
|
|
133
|
+
* const action3 = GitHubAction.create({
|
|
134
|
+
* config: "./custom.config.ts",
|
|
135
|
+
* });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
static create(options = {}) {
|
|
139
|
+
return new GitHubAction(options);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Load and resolve configuration.
|
|
143
|
+
*
|
|
144
|
+
* @remarks
|
|
145
|
+
* Configuration is cached after the first load. Subsequent calls
|
|
146
|
+
* return the cached configuration.
|
|
147
|
+
*
|
|
148
|
+
* @returns Resolved configuration with all defaults applied
|
|
149
|
+
* @throws Error if configuration file cannot be loaded or is invalid
|
|
150
|
+
*/
|
|
151
|
+
async loadConfig() {
|
|
152
|
+
if (this.config) return this.config;
|
|
153
|
+
const configSource = this.configSource;
|
|
154
|
+
const cwd = this.cwd;
|
|
155
|
+
const program = Effect.gen(function* () {
|
|
156
|
+
const configService = yield* ConfigService;
|
|
157
|
+
/* v8 ignore next 6 - requires config file path string */
|
|
158
|
+
if (typeof configSource === "string") return (yield* configService.load({
|
|
159
|
+
cwd,
|
|
160
|
+
configPath: configSource
|
|
161
|
+
})).config;
|
|
162
|
+
if (configSource) return defineConfig(configSource);
|
|
163
|
+
return (yield* configService.load({ cwd })).config;
|
|
164
|
+
});
|
|
165
|
+
const config = await this.runtime.runPromise(program);
|
|
166
|
+
this.config = config;
|
|
167
|
+
return config;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Validate the action configuration and action.yml.
|
|
171
|
+
*
|
|
172
|
+
* @remarks
|
|
173
|
+
* Validation checks:
|
|
174
|
+
* - Entry point files exist
|
|
175
|
+
* - Output directory is writable
|
|
176
|
+
* - action.yml exists and is valid (if required)
|
|
177
|
+
*
|
|
178
|
+
* In CI environments, warnings are treated as errors by default.
|
|
179
|
+
*
|
|
180
|
+
* @param options - Validation options
|
|
181
|
+
* @returns Validation result with errors and warnings
|
|
182
|
+
*/
|
|
183
|
+
async validate(options = {}) {
|
|
184
|
+
const config = await this.loadConfig();
|
|
185
|
+
const cwd = this.cwd;
|
|
186
|
+
const program = Effect.gen(function* () {
|
|
187
|
+
return yield* (yield* ValidationService).validate(config, {
|
|
188
|
+
cwd,
|
|
189
|
+
...options
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
return this.runtime.runPromise(program);
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Build the GitHub Action.
|
|
196
|
+
*
|
|
197
|
+
* @remarks
|
|
198
|
+
* The build process:
|
|
199
|
+
* 1. Loads configuration (if not already loaded)
|
|
200
|
+
* 2. Validates the project (unless `skipValidation` is set)
|
|
201
|
+
* 3. Bundles each entry point with rsbuild
|
|
202
|
+
* 4. Writes output to the `dist/` directory
|
|
203
|
+
*
|
|
204
|
+
* @returns Build result with success status and details
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* import { GitHubAction } from "@savvy-web/github-action-builder";
|
|
209
|
+
*
|
|
210
|
+
* async function main(): Promise<void> {
|
|
211
|
+
* const action = GitHubAction.create();
|
|
212
|
+
* const result = await action.build();
|
|
213
|
+
*
|
|
214
|
+
* if (result.success && result.build) {
|
|
215
|
+
* console.log(`Built ${result.build.entries.length} entries`);
|
|
216
|
+
* } else {
|
|
217
|
+
* console.error(result.error);
|
|
218
|
+
* }
|
|
219
|
+
* }
|
|
220
|
+
*
|
|
221
|
+
* main();
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
/* v8 ignore start - build execution requires actual rsbuild bundling */
|
|
225
|
+
async build() {
|
|
226
|
+
try {
|
|
227
|
+
const config = await this.loadConfig();
|
|
228
|
+
let validationResult;
|
|
229
|
+
if (!this.skipValidation) {
|
|
230
|
+
validationResult = await this.validate();
|
|
231
|
+
if (!validationResult.valid) return {
|
|
232
|
+
success: false,
|
|
233
|
+
validation: validationResult,
|
|
234
|
+
error: "Validation failed"
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const cwd = this.cwd;
|
|
238
|
+
const clean = this.clean;
|
|
239
|
+
const program = Effect.gen(function* () {
|
|
240
|
+
const buildService = yield* BuildService;
|
|
241
|
+
const buildOptions = {
|
|
242
|
+
cwd,
|
|
243
|
+
clean
|
|
244
|
+
};
|
|
245
|
+
return yield* buildService.build(config, buildOptions);
|
|
246
|
+
});
|
|
247
|
+
const buildResult = await this.runtime.runPromise(program);
|
|
248
|
+
if (!buildResult.success) {
|
|
249
|
+
if (validationResult) return {
|
|
250
|
+
success: false,
|
|
251
|
+
build: buildResult,
|
|
252
|
+
validation: validationResult,
|
|
253
|
+
error: buildResult.error ?? "Build failed"
|
|
254
|
+
};
|
|
255
|
+
return {
|
|
256
|
+
success: false,
|
|
257
|
+
build: buildResult,
|
|
258
|
+
error: buildResult.error ?? "Build failed"
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
let persistLocalResult;
|
|
262
|
+
if (config.persistLocal.enabled) {
|
|
263
|
+
const persistProgram = Effect.gen(function* () {
|
|
264
|
+
return yield* (yield* PersistLocalService).persist(config, { cwd });
|
|
265
|
+
});
|
|
266
|
+
persistLocalResult = await this.runtime.runPromise(persistProgram);
|
|
267
|
+
}
|
|
268
|
+
if (validationResult) return {
|
|
269
|
+
success: true,
|
|
270
|
+
build: buildResult,
|
|
271
|
+
validation: validationResult,
|
|
272
|
+
persistLocal: persistLocalResult
|
|
273
|
+
};
|
|
274
|
+
return {
|
|
275
|
+
success: true,
|
|
276
|
+
build: buildResult,
|
|
277
|
+
persistLocal: persistLocalResult
|
|
278
|
+
};
|
|
279
|
+
} catch (error) {
|
|
280
|
+
return {
|
|
281
|
+
success: false,
|
|
282
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
283
|
+
cause: error
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/* v8 ignore stop */
|
|
288
|
+
/**
|
|
289
|
+
* Dispose the runtime and release resources.
|
|
290
|
+
*
|
|
291
|
+
* @remarks
|
|
292
|
+
* Call this when you're done using the GitHubAction instance
|
|
293
|
+
* to clean up any resources held by the Effect runtime.
|
|
294
|
+
*/
|
|
295
|
+
/* v8 ignore next 3 - cleanup method */
|
|
296
|
+
async dispose() {
|
|
297
|
+
await this.runtime.dispose();
|
|
298
|
+
}
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
//#endregion
|
|
302
|
+
export { GitHubAction, GitHubActionBuildResultSchema };
|