@savvy-web/github-action-builder 2.0.6 → 2.1.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/README.md +2 -0
- package/bin/github-action-builder.js +1 -1
- package/cli/commands/init.js +1 -1
- package/index.d.ts +4 -4
- package/package.json +2 -2
- package/services/build-live.js +35 -3
- package/tsconfig/action.json +1 -0
package/README.md
CHANGED
|
@@ -106,6 +106,8 @@ export default GitHubAction.create({
|
|
|
106
106
|
});
|
|
107
107
|
```
|
|
108
108
|
|
|
109
|
+
Every build runs in production mode, so `minify` alone decides whether the output is minified and a local build produces the same bytes CI does. License notices from bundled dependencies are folded into the bundle, keeping the output a single committed file with its attribution intact.
|
|
110
|
+
|
|
109
111
|
## action.yml requirements
|
|
110
112
|
|
|
111
113
|
Your `action.yml` must use Node.js 24:
|
|
@@ -24,7 +24,7 @@ const rootCommand = Command.make("github-action-builder").pipe(Command.withSubco
|
|
|
24
24
|
/**
|
|
25
25
|
* CLI application: reads argv from the Stdio service provided by NodeServices.
|
|
26
26
|
*/
|
|
27
|
-
const cli = Command.run(rootCommand, { version: "2.
|
|
27
|
+
const cli = Command.run(rootCommand, { version: "2.1.1" });
|
|
28
28
|
/**
|
|
29
29
|
* Combined layer: AppLayer + the Node implementations of the CLI
|
|
30
30
|
* environment (FileSystem, Path, Terminal, Stdio, ChildProcessSpawner).
|
package/cli/commands/init.js
CHANGED
|
@@ -20,7 +20,7 @@ const forceOption = Flag.boolean("force").pipe(Flag.withAlias("f"), Flag.withDes
|
|
|
20
20
|
* Get current package version (replaced at build time).
|
|
21
21
|
*/
|
|
22
22
|
const getPackageVersion = () => {
|
|
23
|
-
return "2.
|
|
23
|
+
return "2.1.1";
|
|
24
24
|
};
|
|
25
25
|
/**
|
|
26
26
|
* Generate package.json content.
|
package/index.d.ts
CHANGED
|
@@ -802,9 +802,9 @@ type AppError = ConfigError | ValidationError | BuildError | PersistError;
|
|
|
802
802
|
*/
|
|
803
803
|
declare const LoadConfigOptionsSchema: Schema.Struct<{
|
|
804
804
|
/** Working directory to search for config. Accepts string, Buffer, or URL. */
|
|
805
|
-
readonly cwd: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<URL, unknown>]>, never, never>>;
|
|
805
|
+
readonly cwd: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<import("node:url").URL, unknown>]>, never, never>>;
|
|
806
806
|
/** Explicit path to config file. Accepts string, Buffer, or URL. */
|
|
807
|
-
readonly configPath: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<URL, unknown>]>, never, never>>;
|
|
807
|
+
readonly configPath: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<import("node:url").URL, unknown>]>, never, never>>;
|
|
808
808
|
}>;
|
|
809
809
|
/**
|
|
810
810
|
* Options for loading configuration.
|
|
@@ -934,7 +934,7 @@ declare class ConfigService extends ConfigService_base {}
|
|
|
934
934
|
*/
|
|
935
935
|
declare const BuildRunnerOptionsSchema: Schema.Struct<{
|
|
936
936
|
/** Working directory for the build. Accepts string, Buffer, or URL. */
|
|
937
|
-
readonly cwd: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<URL, unknown>]>, never, never>>;
|
|
937
|
+
readonly cwd: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<import("node:url").URL, unknown>]>, never, never>>;
|
|
938
938
|
/** Clean output directory before building. Defaults to true. */
|
|
939
939
|
readonly clean: Schema.optional<Schema.Boolean>;
|
|
940
940
|
}>;
|
|
@@ -1190,7 +1190,7 @@ declare class PersistLocalService extends PersistLocalService_base {}
|
|
|
1190
1190
|
*/
|
|
1191
1191
|
declare const ValidateOptionsSchema: Schema.Struct<{
|
|
1192
1192
|
/** Working directory for file operations. Accepts string, Buffer, or URL. */
|
|
1193
|
-
readonly cwd: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<URL, unknown>]>, never, never>>;
|
|
1193
|
+
readonly cwd: Schema.optional<Schema.decodeTo<Schema.String, Schema.Union<readonly [Schema.String, Schema.instanceOf<Buffer<ArrayBufferLike>, unknown>, Schema.instanceOf<import("node:url").URL, unknown>]>, never, never>>;
|
|
1194
1194
|
/** Force strict mode regardless of environment. Auto-detects from CI when undefined. */
|
|
1195
1195
|
readonly strict: Schema.optional<Schema.Boolean>;
|
|
1196
1196
|
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@savvy-web/github-action-builder",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.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": [
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@effect/platform-node": "4.0.0-beta.101",
|
|
52
52
|
"@effected/yaml": "^0.6.0",
|
|
53
|
-
"@rsbuild/core": "^2.1.
|
|
53
|
+
"@rsbuild/core": "^2.1.8",
|
|
54
54
|
"effect": "4.0.0-beta.101",
|
|
55
55
|
"jiti": "^2.7.0",
|
|
56
56
|
"picocolors": "^1.1.1"
|
package/services/build-live.js
CHANGED
|
@@ -3,8 +3,8 @@ import { BuildService } from "./build.js";
|
|
|
3
3
|
import { ConfigService } from "./config.js";
|
|
4
4
|
import { buildNativeDynamicImportRules } from "./native-dynamic-imports.js";
|
|
5
5
|
import { Effect, Layer, Result } from "effect";
|
|
6
|
-
import { existsSync, mkdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
7
|
-
import { resolve } from "node:path";
|
|
6
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { basename, resolve } from "node:path";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { createRsbuild } from "@rsbuild/core";
|
|
10
10
|
|
|
@@ -99,6 +99,36 @@ function writeFile(path, content) {
|
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
101
|
/**
|
|
102
|
+
* Fold an extracted `*.LICENSE.txt` sidecar back into its bundle.
|
|
103
|
+
*
|
|
104
|
+
* `legalComments: "linked"` is the only mode whose extraction actually sees
|
|
105
|
+
* bundled license banners — the "inline" mode's SWC comment-preservation path
|
|
106
|
+
* never receives them and silently drops attribution (verified against
|
|
107
|
+
* rsbuild 2.1.8). A committed action still must not carry sidecar files
|
|
108
|
+
* (issue #94), so the sidecar's verbatim comment blocks replace the
|
|
109
|
+
* `LICENSE:` reference banner in the bundle and the sidecar is deleted —
|
|
110
|
+
* attribution inline, no extra dist file.
|
|
111
|
+
*/
|
|
112
|
+
function inlineLicenseSidecar(outputPath) {
|
|
113
|
+
return Effect.try({
|
|
114
|
+
try: () => {
|
|
115
|
+
const sidecarPath = `${outputPath}.LICENSE.txt`;
|
|
116
|
+
if (!existsSync(sidecarPath)) return;
|
|
117
|
+
const licenses = readFileSync(sidecarPath, "utf8").trim();
|
|
118
|
+
const bundle = readFileSync(outputPath, "utf8");
|
|
119
|
+
const reference = `/*! LICENSE: ${basename(sidecarPath)} */`;
|
|
120
|
+
const afterReference = bundle.startsWith(reference) && bundle.charAt(reference.length) === "\n" ? reference.length + 1 : bundle.startsWith(reference) ? reference.length : 0;
|
|
121
|
+
writeFileSync(outputPath, `${licenses}\n${bundle.slice(afterReference)}`, "utf8");
|
|
122
|
+
unlinkSync(sidecarPath);
|
|
123
|
+
},
|
|
124
|
+
/* v8 ignore next 5 - error branch requires fs permission failures */
|
|
125
|
+
catch: (error) => new WriteError({
|
|
126
|
+
path: outputPath,
|
|
127
|
+
cause: error
|
|
128
|
+
})
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
102
132
|
* Bundle a single entry with rsbuild.
|
|
103
133
|
*/
|
|
104
134
|
/* v8 ignore start - bundling requires actual rsbuild execution */
|
|
@@ -118,6 +148,7 @@ function bundleEntry(entry, config, cwd) {
|
|
|
118
148
|
}
|
|
119
149
|
const rsbuild = yield* Effect.tryPromise({
|
|
120
150
|
try: () => createRsbuild({ rsbuildConfig: {
|
|
151
|
+
mode: "production",
|
|
121
152
|
source: { entry: { [entry.type]: entry.path } },
|
|
122
153
|
resolve: { alias: ignoreAlias },
|
|
123
154
|
output: {
|
|
@@ -133,7 +164,7 @@ function bundleEntry(entry, config, cwd) {
|
|
|
133
164
|
return false;
|
|
134
165
|
},
|
|
135
166
|
cleanDistPath: false,
|
|
136
|
-
legalComments: "
|
|
167
|
+
legalComments: "linked",
|
|
137
168
|
minify: config.build.minify,
|
|
138
169
|
sourceMap: config.build.sourceMap ? { js: "source-map" } : false
|
|
139
170
|
},
|
|
@@ -171,6 +202,7 @@ function bundleEntry(entry, config, cwd) {
|
|
|
171
202
|
})
|
|
172
203
|
});
|
|
173
204
|
const outputPath = resolve(outputDir, `${entry.type}.js`);
|
|
205
|
+
yield* inlineLicenseSidecar(outputPath);
|
|
174
206
|
const size = yield* Effect.try({
|
|
175
207
|
try: () => statSync(outputPath).size,
|
|
176
208
|
catch: (error) => new BundleFailed({
|