@savvy-web/github-action-builder 0.6.4 → 0.7.1
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/677.js +52 -6
- package/README.md +26 -33
- package/bin/github-action-builder.js +2 -2
- package/index.d.ts +10 -0
- package/package.json +1 -1
package/677.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Context, Data, Effect, Layer, ParseResult, Schema } from "effect";
|
|
2
|
-
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
3
4
|
import { dirname, join, relative, resolve } from "node:path";
|
|
4
5
|
import { createRsbuild } from "@rsbuild/core";
|
|
5
6
|
import { fileURLToPath } from "node:url";
|
|
@@ -102,6 +103,9 @@ const BuildOptionsSchema = Schema.Struct({
|
|
|
102
103
|
}),
|
|
103
104
|
externals: Schema.optionalWith(Schema.Array(Schema.String), {
|
|
104
105
|
default: ()=>[]
|
|
106
|
+
}),
|
|
107
|
+
ignore: Schema.optionalWith(Schema.Array(Schema.String), {
|
|
108
|
+
default: ()=>[]
|
|
105
109
|
})
|
|
106
110
|
});
|
|
107
111
|
const ValidationOptionsSchema = Schema.Struct({
|
|
@@ -131,7 +135,8 @@ const ConfigInputSchema = Schema.Struct({
|
|
|
131
135
|
build: Schema.optional(Schema.Struct({
|
|
132
136
|
minify: Schema.optional(Schema.Boolean),
|
|
133
137
|
sourceMap: Schema.optional(Schema.Boolean),
|
|
134
|
-
externals: Schema.optional(Schema.Array(Schema.String))
|
|
138
|
+
externals: Schema.optional(Schema.Array(Schema.String)),
|
|
139
|
+
ignore: Schema.optional(Schema.Array(Schema.String))
|
|
135
140
|
})),
|
|
136
141
|
validation: Schema.optional(Schema.Struct({
|
|
137
142
|
requireActionYml: Schema.optional(Schema.Boolean),
|
|
@@ -178,6 +183,7 @@ Schema.Struct({
|
|
|
178
183
|
usingDefaults: Schema.Boolean
|
|
179
184
|
});
|
|
180
185
|
const ConfigService = Context.GenericTag("ConfigService");
|
|
186
|
+
const IGNORE_STUB_SOURCE = `throw new Error("A module excluded via the build 'ignore' option was loaded at runtime.");\n`;
|
|
181
187
|
function formatBytes(bytes) {
|
|
182
188
|
if (bytes < 1024) return `${bytes} B`;
|
|
183
189
|
if (bytes < 1048576) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
@@ -231,6 +237,22 @@ function bundleEntry(entry, config, cwd) {
|
|
|
231
237
|
return Effect.gen(function*() {
|
|
232
238
|
const startTime = Date.now();
|
|
233
239
|
const outputDir = resolve(cwd, "dist");
|
|
240
|
+
const externalsSet = new Set(config.build.externals);
|
|
241
|
+
const ignoreSet = new Set(config.build.ignore);
|
|
242
|
+
const ignoreAlias = {};
|
|
243
|
+
let stubDir;
|
|
244
|
+
if (config.build.ignore.length > 0) {
|
|
245
|
+
stubDir = yield* Effect["try"]({
|
|
246
|
+
try: ()=>mkdtempSync(join(tmpdir(), "github-action-builder-")),
|
|
247
|
+
catch: (error)=>new WriteError({
|
|
248
|
+
path: tmpdir(),
|
|
249
|
+
cause: error
|
|
250
|
+
})
|
|
251
|
+
});
|
|
252
|
+
const stubPath = resolve(stubDir, "ignore-stub.mjs");
|
|
253
|
+
yield* writeFile(stubPath, IGNORE_STUB_SOURCE);
|
|
254
|
+
for (const moduleName of config.build.ignore)ignoreAlias[`${moduleName}$`] = stubPath;
|
|
255
|
+
}
|
|
234
256
|
const rsbuild = yield* Effect.tryPromise({
|
|
235
257
|
try: ()=>createRsbuild({
|
|
236
258
|
rsbuildConfig: {
|
|
@@ -239,6 +261,9 @@ function bundleEntry(entry, config, cwd) {
|
|
|
239
261
|
[entry.type]: entry.path
|
|
240
262
|
}
|
|
241
263
|
},
|
|
264
|
+
resolve: {
|
|
265
|
+
alias: ignoreAlias
|
|
266
|
+
},
|
|
242
267
|
output: {
|
|
243
268
|
target: "node",
|
|
244
269
|
module: true,
|
|
@@ -248,10 +273,13 @@ function bundleEntry(entry, config, cwd) {
|
|
|
248
273
|
filename: {
|
|
249
274
|
js: "[name].js"
|
|
250
275
|
},
|
|
251
|
-
externals:
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
276
|
+
externals: (data)=>{
|
|
277
|
+
const request = data.request;
|
|
278
|
+
if (!request) return false;
|
|
279
|
+
if (request.startsWith("node:")) return `node-commonjs ${request}`;
|
|
280
|
+
if (externalsSet.has(request) && !ignoreSet.has(request)) return request;
|
|
281
|
+
return false;
|
|
282
|
+
},
|
|
255
283
|
cleanDistPath: false,
|
|
256
284
|
minify: config.build.minify,
|
|
257
285
|
sourceMap: config.build.sourceMap ? {
|
|
@@ -262,6 +290,17 @@ function bundleEntry(entry, config, cwd) {
|
|
|
262
290
|
chunkSplit: {
|
|
263
291
|
strategy: "all-in-one"
|
|
264
292
|
}
|
|
293
|
+
},
|
|
294
|
+
tools: {
|
|
295
|
+
rspack: {
|
|
296
|
+
node: {
|
|
297
|
+
__dirname: "node-module",
|
|
298
|
+
__filename: "node-module"
|
|
299
|
+
},
|
|
300
|
+
output: {
|
|
301
|
+
asyncChunks: false
|
|
302
|
+
}
|
|
303
|
+
}
|
|
265
304
|
}
|
|
266
305
|
}
|
|
267
306
|
}),
|
|
@@ -284,6 +323,13 @@ function bundleEntry(entry, config, cwd) {
|
|
|
284
323
|
cause: new Error(`rsbuild close() failed: ${error}`)
|
|
285
324
|
})
|
|
286
325
|
});
|
|
326
|
+
if (void 0 !== stubDir) {
|
|
327
|
+
const dir = stubDir;
|
|
328
|
+
yield* Effect.ignore(Effect["try"](()=>rmSync(dir, {
|
|
329
|
+
recursive: true,
|
|
330
|
+
force: true
|
|
331
|
+
})));
|
|
332
|
+
}
|
|
287
333
|
const outputPath = resolve(outputDir, `${entry.type}.js`);
|
|
288
334
|
const size = yield* Effect["try"]({
|
|
289
335
|
try: ()=>statSync(outputPath).size,
|
package/README.md
CHANGED
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
# @savvy-web/github-action-builder
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
(
|
|
6
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@savvy-web/github-action-builder)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://nodejs.org/)
|
|
6
|
+
|
|
7
|
+
Build a GitHub Action from TypeScript source without writing build config. The builder bundles your code with [@rsbuild/core](https://github.com/web-infra-dev/rsbuild) (rspack under the hood) and checks `action.yml` against GitHub's published metadata schema. The output is a single Node.js 24 file you commit to your repo.
|
|
7
8
|
|
|
8
9
|
## Features
|
|
9
10
|
|
|
10
|
-
- **
|
|
11
|
-
|
|
12
|
-
- **
|
|
13
|
-
|
|
14
|
-
- **
|
|
15
|
-
metadata specification
|
|
16
|
-
- **Single-file bundles** - All npm dependencies inlined via rsbuild, `node:`
|
|
17
|
-
builtins externalized, with tree-shaking support
|
|
18
|
-
- **Local testing** - Auto-persists build output for testing with
|
|
19
|
-
[nektos/act](https://github.com/nektos/act)
|
|
11
|
+
- **No build config required** - Picks up entry points from `src/main.ts`, `src/pre.ts`, `src/post.ts` on its own
|
|
12
|
+
- **Node.js 24** - Emits ESM actions that run on the `node24` GitHub Actions runtime
|
|
13
|
+
- **Schema validation** - Validates `action.yml` against GitHub's official metadata specification
|
|
14
|
+
- **Single-file bundles** - All npm dependencies inlined via rsbuild; `node:` builtins externalized; user-configured `externals` and `ignore` options for optional or native modules
|
|
15
|
+
- **Local testing** - Auto-persists build output for testing with [nektos/act](https://github.com/nektos/act)
|
|
20
16
|
- **CI-aware** - Strict validation in CI, warnings-only locally
|
|
21
17
|
|
|
22
|
-
## Quick
|
|
18
|
+
## Quick start
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
Scaffold a new GitHub Action project, then build it:
|
|
25
21
|
|
|
26
22
|
```bash
|
|
27
23
|
npx @savvy-web/github-action-builder init my-action
|
|
@@ -30,8 +26,7 @@ npm install
|
|
|
30
26
|
npm run build
|
|
31
27
|
```
|
|
32
28
|
|
|
33
|
-
|
|
34
|
-
complete project:
|
|
29
|
+
The `init` command lays down the project:
|
|
35
30
|
|
|
36
31
|
```text
|
|
37
32
|
my-action/
|
|
@@ -45,10 +40,9 @@ my-action/
|
|
|
45
40
|
└── tsconfig.json # TypeScript configuration
|
|
46
41
|
```
|
|
47
42
|
|
|
48
|
-
|
|
49
|
-
Your bundled action is in `dist/main.js`, ready to commit and use.
|
|
43
|
+
Put your action logic in `src/main.ts` and run `npm run build` again. The bundled action lands at `dist/main.js` — commit that file to your repo.
|
|
50
44
|
|
|
51
|
-
## Basic
|
|
45
|
+
## Basic usage
|
|
52
46
|
|
|
53
47
|
### Initialize
|
|
54
48
|
|
|
@@ -78,7 +72,7 @@ npm run validate
|
|
|
78
72
|
npx @savvy-web/github-action-builder validate
|
|
79
73
|
```
|
|
80
74
|
|
|
81
|
-
## Project
|
|
75
|
+
## Project structure
|
|
82
76
|
|
|
83
77
|
The builder expects this structure:
|
|
84
78
|
|
|
@@ -112,7 +106,7 @@ export default GitHubAction.create({
|
|
|
112
106
|
});
|
|
113
107
|
```
|
|
114
108
|
|
|
115
|
-
## action.yml
|
|
109
|
+
## action.yml requirements
|
|
116
110
|
|
|
117
111
|
Your `action.yml` must use Node.js 24:
|
|
118
112
|
|
|
@@ -127,12 +121,12 @@ runs:
|
|
|
127
121
|
|
|
128
122
|
## Documentation
|
|
129
123
|
|
|
130
|
-
- [Getting
|
|
131
|
-
- [Configuration](./docs/configuration.md) - All configuration options
|
|
132
|
-
- [Local
|
|
133
|
-
- [CLI
|
|
134
|
-
- [Architecture](./docs/architecture.md) - How it works internally
|
|
135
|
-
- [Troubleshooting](./docs/troubleshooting.md) - Common issues and solutions
|
|
124
|
+
- [Getting started](./docs/01-getting-started.md) - Installation and first build
|
|
125
|
+
- [Configuration](./docs/02-configuration.md) - All configuration options
|
|
126
|
+
- [Local testing](./docs/03-local-testing.md) - Testing with nektos/act
|
|
127
|
+
- [CLI reference](./docs/04-cli-reference.md) - Complete command reference
|
|
128
|
+
- [Architecture](./docs/05-architecture.md) - How it works internally
|
|
129
|
+
- [Troubleshooting](./docs/06-troubleshooting.md) - Common issues and solutions
|
|
136
130
|
|
|
137
131
|
## Programmatic API
|
|
138
132
|
|
|
@@ -146,10 +140,11 @@ const result = await action.build();
|
|
|
146
140
|
|
|
147
141
|
if (result.success) {
|
|
148
142
|
console.log(`Built ${result.build?.entries.length} entry points`);
|
|
143
|
+
// e.g. "Built 3 entry points"
|
|
149
144
|
}
|
|
150
145
|
```
|
|
151
146
|
|
|
152
|
-
## Shared TypeScript
|
|
147
|
+
## Shared TypeScript configuration
|
|
153
148
|
|
|
154
149
|
The package exports a base `tsconfig.json` for GitHub Action projects:
|
|
155
150
|
|
|
@@ -159,9 +154,7 @@ The package exports a base `tsconfig.json` for GitHub Action projects:
|
|
|
159
154
|
}
|
|
160
155
|
```
|
|
161
156
|
|
|
162
|
-
|
|
163
|
-
mode, ES2022 target, and bundler module resolution. Override or extend as
|
|
164
|
-
needed in your project's `tsconfig.json`.
|
|
157
|
+
It sets up Node.js 24 ESM actions with strict mode, an ES2022 target and bundler module resolution. Override any of it in your own `tsconfig.json`.
|
|
165
158
|
|
|
166
159
|
## Requirements
|
|
167
160
|
|
|
@@ -74,7 +74,7 @@ const actionNameArg = Args.text({
|
|
|
74
74
|
name: "action-name"
|
|
75
75
|
}).pipe(Args.withDescription("Name of the GitHub Action (also the output directory)"));
|
|
76
76
|
const forceOption = Options.boolean("force").pipe(Options.withAlias("f"), Options.withDescription("Overwrite existing files"), Options.withDefault(false));
|
|
77
|
-
const getPackageVersion = ()=>"0.
|
|
77
|
+
const getPackageVersion = ()=>"0.7.1";
|
|
78
78
|
const generatePackageJson = (name)=>{
|
|
79
79
|
const version = getPackageVersion();
|
|
80
80
|
const pkg = {
|
|
@@ -306,7 +306,7 @@ const rootCommand = Command.make("github-action-builder").pipe(Command.withSubco
|
|
|
306
306
|
]));
|
|
307
307
|
const cli = Command.run(rootCommand, {
|
|
308
308
|
name: "github-action-builder",
|
|
309
|
-
version: "0.
|
|
309
|
+
version: "0.7.1"
|
|
310
310
|
});
|
|
311
311
|
const CliLayer = Layer.merge(AppLayer, NodeContext.layer);
|
|
312
312
|
const main = Effect.suspend(()=>cli(process.argv)).pipe(Effect.provide(CliLayer), Effect.catchAllCause((cause)=>{
|
package/index.d.ts
CHANGED
|
@@ -343,6 +343,10 @@ export declare const BuildOptionsSchema: Schema.Struct<{
|
|
|
343
343
|
externals: Schema.optionalWith<Schema.Array$<typeof Schema.String>, {
|
|
344
344
|
default: () => never[];
|
|
345
345
|
}>;
|
|
346
|
+
/** Packages to exclude from the bundle and replace with a stub that throws if loaded at runtime. Use for optional transitive dependencies the action never exercises (e.g. native modules). Defaults to []. */
|
|
347
|
+
ignore: Schema.optionalWith<Schema.Array$<typeof Schema.String>, {
|
|
348
|
+
default: () => never[];
|
|
349
|
+
}>;
|
|
346
350
|
}>;
|
|
347
351
|
|
|
348
352
|
/**
|
|
@@ -637,6 +641,7 @@ export declare const ConfigInputSchema: Schema.Struct<{
|
|
|
637
641
|
minify: Schema.optional<typeof Schema.Boolean>;
|
|
638
642
|
sourceMap: Schema.optional<typeof Schema.Boolean>;
|
|
639
643
|
externals: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
644
|
+
ignore: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
640
645
|
}>>;
|
|
641
646
|
validation: Schema.optional<Schema.Struct<{
|
|
642
647
|
requireActionYml: Schema.optional<typeof Schema.Boolean>;
|
|
@@ -782,6 +787,10 @@ export declare const ConfigSchema: Schema.Struct<{
|
|
|
782
787
|
externals: Schema.optionalWith<Schema.Array$<typeof Schema.String>, {
|
|
783
788
|
default: () => never[];
|
|
784
789
|
}>;
|
|
790
|
+
/** Packages to exclude from the bundle and replace with a stub that throws if loaded at runtime. Use for optional transitive dependencies the action never exercises (e.g. native modules). Defaults to []. */
|
|
791
|
+
ignore: Schema.optionalWith<Schema.Array$<typeof Schema.String>, {
|
|
792
|
+
default: () => never[];
|
|
793
|
+
}>;
|
|
785
794
|
}>;
|
|
786
795
|
validation: Schema.Struct<{
|
|
787
796
|
/** Require action.yml to exist and be valid. Defaults to true. */
|
|
@@ -910,6 +919,7 @@ export declare const ConfigService: Context.Tag<ConfigService, ConfigService>;
|
|
|
910
919
|
* minify: true,
|
|
911
920
|
* sourceMap: true,
|
|
912
921
|
* externals: ["@aws-sdk/client-s3"],
|
|
922
|
+
* ignore: ["libxmljs2"],
|
|
913
923
|
* },
|
|
914
924
|
* validation: {
|
|
915
925
|
* requireActionYml: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/github-action-builder",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A zero-config build tool for creating GitHub Actions from TypeScript. Bundles with rsbuild, validates action.yml against GitHub's schema, and outputs production-ready Node.js 24 actions.",
|
|
6
6
|
"keywords": [
|