@kinwan/infrascript 0.1.0

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.
Files changed (72) hide show
  1. package/README.md +291 -0
  2. package/dist/actions/Job.d.ts +36 -0
  3. package/dist/actions/Job.d.ts.map +1 -0
  4. package/dist/actions/Job.js +93 -0
  5. package/dist/actions/Job.js.map +1 -0
  6. package/dist/actions/Step.d.ts +25 -0
  7. package/dist/actions/Step.d.ts.map +1 -0
  8. package/dist/actions/Step.js +72 -0
  9. package/dist/actions/Step.js.map +1 -0
  10. package/dist/actions/Workflow.d.ts +27 -0
  11. package/dist/actions/Workflow.d.ts.map +1 -0
  12. package/dist/actions/Workflow.js +77 -0
  13. package/dist/actions/Workflow.js.map +1 -0
  14. package/dist/actions/types.d.ts +34 -0
  15. package/dist/actions/types.d.ts.map +1 -0
  16. package/dist/actions/types.js +3 -0
  17. package/dist/actions/types.js.map +1 -0
  18. package/dist/cli/index.d.ts +3 -0
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +160 -0
  21. package/dist/cli/index.js.map +1 -0
  22. package/dist/config.d.ts +40 -0
  23. package/dist/config.d.ts.map +1 -0
  24. package/dist/config.js +29 -0
  25. package/dist/config.js.map +1 -0
  26. package/dist/core/Builder.d.ts +12 -0
  27. package/dist/core/Builder.d.ts.map +1 -0
  28. package/dist/core/Builder.js +11 -0
  29. package/dist/core/Builder.js.map +1 -0
  30. package/dist/core/FileWriter.d.ts +10 -0
  31. package/dist/core/FileWriter.d.ts.map +1 -0
  32. package/dist/core/FileWriter.js +79 -0
  33. package/dist/core/FileWriter.js.map +1 -0
  34. package/dist/core/YamlSerializer.d.ts +2 -0
  35. package/dist/core/YamlSerializer.d.ts.map +1 -0
  36. package/dist/core/YamlSerializer.js +46 -0
  37. package/dist/core/YamlSerializer.js.map +1 -0
  38. package/dist/index.d.ts +16 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +32 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/k8s/Deployment.d.ts +41 -0
  43. package/dist/k8s/Deployment.d.ts.map +1 -0
  44. package/dist/k8s/Deployment.js +135 -0
  45. package/dist/k8s/Deployment.js.map +1 -0
  46. package/dist/k8s/EKSCluster.d.ts +77 -0
  47. package/dist/k8s/EKSCluster.d.ts.map +1 -0
  48. package/dist/k8s/EKSCluster.js +80 -0
  49. package/dist/k8s/EKSCluster.js.map +1 -0
  50. package/dist/k8s/K8sApp.d.ts +71 -0
  51. package/dist/k8s/K8sApp.d.ts.map +1 -0
  52. package/dist/k8s/K8sApp.js +175 -0
  53. package/dist/k8s/K8sApp.js.map +1 -0
  54. package/dist/k8s/Manifests.d.ts +80 -0
  55. package/dist/k8s/Manifests.d.ts.map +1 -0
  56. package/dist/k8s/Manifests.js +204 -0
  57. package/dist/k8s/Manifests.js.map +1 -0
  58. package/dist/k8s/types.d.ts +63 -0
  59. package/dist/k8s/types.d.ts.map +1 -0
  60. package/dist/k8s/types.js +13 -0
  61. package/dist/k8s/types.js.map +1 -0
  62. package/infrascript.config.ts +69 -0
  63. package/infrascript.eks.config.ts +121 -0
  64. package/k8s/api-config-configmap.yaml +7 -0
  65. package/k8s/api-deployment.yaml +54 -0
  66. package/k8s/api-ingress.yaml +21 -0
  67. package/k8s/api-pvc-pvc.yaml +10 -0
  68. package/k8s/api-secret-secret.yaml +8 -0
  69. package/k8s/api-service.yaml +12 -0
  70. package/k8s/worker-deployment.yaml +24 -0
  71. package/k8s/worker-service.yaml +12 -0
  72. package/package.json +34 -0
package/README.md ADDED
@@ -0,0 +1,291 @@
1
+ # infrascript
2
+
3
+ Typed TypeScript DSL for generating GitHub Actions workflows and Kubernetes manifests.
4
+
5
+ Write your infrastructure config once in TypeScript — fully typed, with autocomplete and compile-time validation — and let infrascript emit the YAML files exactly where they need to go.
6
+
7
+ ```bash
8
+ npx infrascript build
9
+ # → .github/workflows/ci.yml
10
+ # → .github/workflows/deploy.yml
11
+ # → k8s/api-configmap.yaml
12
+ # → k8s/api-secret.yaml
13
+ # → k8s/api-pvc.yaml
14
+ # → k8s/api-deployment.yaml
15
+ # → k8s/api-service.yaml
16
+ # → k8s/api-ingress.yaml
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Why
22
+
23
+ Writing YAML by hand has real costs:
24
+
25
+ - No type safety — invalid fields and typos fail silently until runtime
26
+ - Cross-manifest references (service names, secret names, label selectors) break when you rename things
27
+ - K8s requires 5–7 separate files for a single app — all manually kept in sync
28
+ - GitHub Actions has no guard against referencing a job that doesn't exist
29
+
30
+ infrascript fixes all of this. Your config is TypeScript, so your editor catches errors before `kubectl apply` does.
31
+
32
+ ---
33
+
34
+ ## Installation
35
+
36
+ ```bash
37
+ npm install -D infrascript ts-node
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Quick start
43
+
44
+ Create `infrascript.config.ts` at your project root:
45
+
46
+ ```typescript
47
+ import { defineConfig, ActionsWorkflow, K8sApp } from "infrascript";
48
+
49
+ const ci = new ActionsWorkflow("ci")
50
+ .on("push", { branches: ["main"] })
51
+ .on("pull_request")
52
+ .job("test", (j) =>
53
+ j
54
+ .runsOn("ubuntu-latest")
55
+ .step("Checkout").uses("actions/checkout@v4")
56
+ .step("Install").run("npm ci")
57
+ .step("Test").run("npm test")
58
+ );
59
+
60
+ const api = new K8sApp("api")
61
+ .image("ghcr.io/myorg/api:latest")
62
+ .replicas(2)
63
+ .port(3000)
64
+ .env({ NODE_ENV: "production" })
65
+ .secret({ DB_PASSWORD: "replace-me" })
66
+ .ingress({ host: "api.myapp.com", tls: true });
67
+
68
+ export default defineConfig({
69
+ actions: { ci },
70
+ k8s: { apps: { api } },
71
+ });
72
+ ```
73
+
74
+ Then run:
75
+
76
+ ```bash
77
+ npx infrascript build
78
+ ```
79
+
80
+ Files are written in-place — `.github/workflows/` and `k8s/` — exactly where GitHub and `kubectl` expect them. Directories are created automatically if they don't exist. Existing files are overwritten; git is your undo.
81
+
82
+ ---
83
+
84
+ ## CLI
85
+
86
+ ```bash
87
+ npx infrascript build # generate all YAML files
88
+ npx infrascript validate # validate config without writing files
89
+ ```
90
+
91
+ Build output is colored by result:
92
+
93
+ ```
94
+ ✓ created .github/workflows/ci.yml
95
+ ↻ updated k8s/api-deployment.yaml
96
+ – unchanged k8s/api-service.yaml
97
+ ```
98
+
99
+ ---
100
+
101
+ ## GitHub Actions
102
+
103
+ ### `ActionsWorkflow`
104
+
105
+ ```typescript
106
+ const deploy = new ActionsWorkflow("deploy")
107
+ .on("push", { branches: ["main"] })
108
+ .on("schedule", "0 2 * * *")
109
+ .on("workflow_dispatch")
110
+ .permissions({ contents: "read", packages: "write" })
111
+ .concurrency("deploy-${{ github.ref }}", true)
112
+ .env({ NODE_ENV: "production" })
113
+ .job("build", (j) => j
114
+ .runsOn("ubuntu-latest")
115
+ .step("Checkout").uses("actions/checkout@v4")
116
+ .step("Build").run("npm run build")
117
+ )
118
+ .job("deploy", (j) => j
119
+ .runsOn("ubuntu-latest")
120
+ .needs("build")
121
+ .step("Deploy").run("./scripts/deploy.sh")
122
+ );
123
+ ```
124
+
125
+ Outputs to `.github/workflows/deploy.yml`.
126
+
127
+ ### `Job`
128
+
129
+ | Method | Description |
130
+ |---|---|
131
+ | `.runsOn(runner)` | Runner label — typed union of all GitHub-hosted runners |
132
+ | `.needs(...jobIds)` | Job dependencies — must be IDs defined in the same workflow |
133
+ | `.step(name)` | Add a step, returns `Step` for chaining |
134
+ | `.env(vars)` | Job-level env vars |
135
+ | `.permissions(perms)` | Job-level permissions |
136
+ | `.matrix(matrix)` | Build matrix strategy |
137
+ | `.timeoutMinutes(n)` | Job timeout |
138
+ | `.if(condition)` | Conditional expression |
139
+
140
+ ### `Step`
141
+
142
+ ```typescript
143
+ // Use a community action
144
+ j.step("Login").uses("docker/login-action@v3", {
145
+ registry: "ghcr.io",
146
+ username: "${{ github.actor }}",
147
+ password: "${{ secrets.GITHUB_TOKEN }}",
148
+ });
149
+
150
+ // Run a shell command
151
+ j.step("Test").run("npm test");
152
+
153
+ // With extras
154
+ j.step("Deploy")
155
+ .run("kubectl apply -f k8s/")
156
+ .env({ KUBECONFIG: "${{ secrets.KUBECONFIG }}" })
157
+ .if("github.ref == 'refs/heads/main'")
158
+ .workingDirectory("./infra");
159
+ ```
160
+
161
+ ---
162
+
163
+ ## Kubernetes
164
+
165
+ ### `K8sApp` — recommended
166
+
167
+ `K8sApp` is a high-level facade. Define your app once and it generates all required manifests with names and cross-references kept consistent automatically.
168
+
169
+ ```typescript
170
+ const api = new K8sApp("api")
171
+ .image("ghcr.io/myorg/api:latest")
172
+ .replicas(2)
173
+ .port(3000)
174
+ .namespace("production")
175
+ .imagePullPolicy("Always")
176
+ .env({ NODE_ENV: "production", LOG_LEVEL: "info" })
177
+ .secret({ DB_PASSWORD: "replace-me", JWT_SECRET: "replace-me" })
178
+ .resources({
179
+ requests: { cpu: "100m", memory: "128Mi" },
180
+ limits: { cpu: "500m", memory: "512Mi" },
181
+ })
182
+ .ingress({ host: "api.myapp.com", tls: true, ingressClassName: "nginx" })
183
+ .volume({ mountPath: "/data", size: "5Gi" });
184
+ ```
185
+
186
+ This single definition emits:
187
+
188
+ | File | What |
189
+ |---|---|
190
+ | `k8s/api-configmap.yaml` | Plain env vars from `.env()` |
191
+ | `k8s/api-secret.yaml` | Secret env vars from `.secret()` |
192
+ | `k8s/api-pvc.yaml` | Persistent volume claim from `.volume()` |
193
+ | `k8s/api-deployment.yaml` | Deployment with env refs wired to ConfigMap and Secret |
194
+ | `k8s/api-service.yaml` | ClusterIP Service |
195
+ | `k8s/api-ingress.yaml` | Ingress with optional TLS |
196
+
197
+ Cross-references — ConfigMap name in envFrom, Secret name in envFrom, PVC name in volumeMounts — are guaranteed consistent because they all derive from the app name.
198
+
199
+ > **Note on secrets:** `.secret()` values are placeholders. The generated Secret uses `stringData` so you can fill in real values before applying, or replace the file with a sealed secret. Never commit real secret values.
200
+
201
+ ### Low-level escape hatch
202
+
203
+ For advanced cases, use individual manifest builders directly. Each emits exactly one file.
204
+
205
+ ```typescript
206
+ import {
207
+ defineConfig,
208
+ Deployment, K8sService, Ingress,
209
+ ConfigMap, Secret, PVC,
210
+ secretRef, configMapRef,
211
+ } from "infrascript";
212
+
213
+ const worker = new Deployment("worker", "ghcr.io/myorg/worker:latest")
214
+ .replicas(3)
215
+ .port(8080)
216
+ .env({ QUEUE: "jobs" })
217
+ .envFrom("DB_PASS", secretRef("db-secret", "password"))
218
+ .resources({ limits: { cpu: "200m", memory: "256Mi" } })
219
+ .livenessProbe({
220
+ httpGet: { path: "/healthz", port: 8080 },
221
+ initialDelaySeconds: 10,
222
+ periodSeconds: 5,
223
+ });
224
+
225
+ const workerSvc = new K8sService("worker")
226
+ .type("ClusterIP")
227
+ .port(8080);
228
+
229
+ export default defineConfig({
230
+ k8s: {
231
+ manifests: { worker, workerSvc },
232
+ },
233
+ });
234
+ ```
235
+
236
+ ### Mixing both
237
+
238
+ ```typescript
239
+ export default defineConfig({
240
+ k8s: {
241
+ apps: {
242
+ api, // high-level: emits 6 files automatically
243
+ },
244
+ manifests: {
245
+ worker, // low-level: one deployment, explicit control
246
+ workerSvc,
247
+ },
248
+ },
249
+ });
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Output paths
255
+
256
+ | Config | Output path |
257
+ |---|---|
258
+ | `actions: { ci }` | `.github/workflows/ci.yml` |
259
+ | `actions: { deploy }` | `.github/workflows/deploy.yml` |
260
+ | `k8s.apps: { api }` | `k8s/api-*.yaml` (one per manifest type) |
261
+ | `k8s.manifests: { worker }` (Deployment) | `k8s/worker-deployment.yaml` |
262
+ | `k8s.manifests: { workerSvc }` (Service) | `k8s/worker-service.yaml` |
263
+
264
+ Namespaced resources are placed in a subdirectory:
265
+
266
+ ```
267
+ k8s/production/api-deployment.yaml
268
+ k8s/production/api-service.yaml
269
+ ```
270
+
271
+ ---
272
+
273
+ ## Design philosophy
274
+
275
+ **One source of truth.** Your TypeScript config is the authoritative definition of your infrastructure. The YAML files are build artifacts — generated, not hand-maintained.
276
+
277
+ **Files go where tools expect them.** No intermediate output folder to copy from. `.github/workflows/` is where GitHub reads Actions. `k8s/` is where you point `kubectl apply -f`. infrascript writes there directly.
278
+
279
+ **Git is the safety net.** infrascript overwrites existing files without prompting. Review diffs in git before committing. This mirrors how most YAML changes are reviewed anyway.
280
+
281
+ **Newbie-friendly, expert-capable.** `K8sApp` covers the common case with zero K8s knowledge required. The low-level builders are there when you need full control.
282
+
283
+ ---
284
+
285
+ ## Roadmap
286
+
287
+ - `infrascript diff` — show pending changes without writing
288
+ - `infrascript watch` — regenerate on config file change
289
+ - HorizontalPodAutoscaler builder
290
+ - Helm values.yaml output target
291
+ - JSON Schema export for editor validation
@@ -0,0 +1,36 @@
1
+ import { Step } from "./Step";
2
+ import type { Runner, Permissions, StepEnv } from "./types";
3
+ export declare class Job {
4
+ private _runsOn;
5
+ private _steps;
6
+ private _needs;
7
+ private _if?;
8
+ private _env;
9
+ private _permissions?;
10
+ private _strategy?;
11
+ private _outputs;
12
+ private _timeoutMinutes?;
13
+ private _continueOnError?;
14
+ runsOn(runner: Runner): this;
15
+ needs(...jobIds: string[]): this;
16
+ if(condition: string): this;
17
+ env(vars: StepEnv): this;
18
+ permissions(perms: Permissions): this;
19
+ timeoutMinutes(minutes: number): this;
20
+ continueOnError(value: boolean): this;
21
+ /** Add a build matrix strategy */
22
+ matrix(matrix: Record<string, unknown[]>): this;
23
+ output(name: string, value: string): this;
24
+ /**
25
+ * Add a step via callback. The callback receives a Step builder;
26
+ * Job is returned for continued chaining.
27
+ *
28
+ * @example
29
+ * j.step("Checkout", s => s.uses("actions/checkout@v4"))
30
+ * .step("Install", s => s.run("npm ci"))
31
+ * .step("Test", s => s.run("npm test"))
32
+ */
33
+ step(name: string, configure: (step: Step) => void): this;
34
+ toObject(): Record<string, unknown>;
35
+ }
36
+ //# sourceMappingURL=Job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Job.d.ts","sourceRoot":"","sources":["../../src/actions/Job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE5D,qBAAa,GAAG;IACd,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAS;IACrB,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,SAAS,CAAC,CAA0B;IAC5C,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,eAAe,CAAC,CAAS;IACjC,OAAO,CAAC,gBAAgB,CAAC,CAAU;IAEnC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK5B,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI;IAKhC,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK3B,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAKxB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAKrC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKrC,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI;IAKrC,kCAAkC;IAClC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI;IAK/C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzC;;;;;;;;OAQG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI;IAOzD,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAsBpC"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Job = void 0;
4
+ const Step_1 = require("./Step");
5
+ class Job {
6
+ constructor() {
7
+ this._runsOn = "ubuntu-latest";
8
+ this._steps = [];
9
+ this._needs = [];
10
+ this._env = {};
11
+ this._outputs = {};
12
+ }
13
+ runsOn(runner) {
14
+ this._runsOn = runner;
15
+ return this;
16
+ }
17
+ needs(...jobIds) {
18
+ this._needs.push(...jobIds);
19
+ return this;
20
+ }
21
+ if(condition) {
22
+ this._if = condition;
23
+ return this;
24
+ }
25
+ env(vars) {
26
+ this._env = { ...this._env, ...vars };
27
+ return this;
28
+ }
29
+ permissions(perms) {
30
+ this._permissions = perms;
31
+ return this;
32
+ }
33
+ timeoutMinutes(minutes) {
34
+ this._timeoutMinutes = minutes;
35
+ return this;
36
+ }
37
+ continueOnError(value) {
38
+ this._continueOnError = value;
39
+ return this;
40
+ }
41
+ /** Add a build matrix strategy */
42
+ matrix(matrix) {
43
+ this._strategy = { matrix };
44
+ return this;
45
+ }
46
+ output(name, value) {
47
+ this._outputs[name] = value;
48
+ return this;
49
+ }
50
+ /**
51
+ * Add a step via callback. The callback receives a Step builder;
52
+ * Job is returned for continued chaining.
53
+ *
54
+ * @example
55
+ * j.step("Checkout", s => s.uses("actions/checkout@v4"))
56
+ * .step("Install", s => s.run("npm ci"))
57
+ * .step("Test", s => s.run("npm test"))
58
+ */
59
+ step(name, configure) {
60
+ const s = new Step_1.Step(name);
61
+ configure(s);
62
+ this._steps.push(s);
63
+ return this;
64
+ }
65
+ toObject() {
66
+ if (this._steps.length === 0) {
67
+ throw new Error("Job must have at least one step");
68
+ }
69
+ const obj = {
70
+ "runs-on": this._runsOn,
71
+ };
72
+ if (this._needs.length > 0)
73
+ obj["needs"] = this._needs;
74
+ if (this._if)
75
+ obj["if"] = this._if;
76
+ if (this._permissions)
77
+ obj["permissions"] = this._permissions;
78
+ if (Object.keys(this._env).length > 0)
79
+ obj["env"] = this._env;
80
+ if (this._timeoutMinutes)
81
+ obj["timeout-minutes"] = this._timeoutMinutes;
82
+ if (this._continueOnError !== undefined)
83
+ obj["continue-on-error"] = this._continueOnError;
84
+ if (this._strategy)
85
+ obj["strategy"] = this._strategy;
86
+ if (Object.keys(this._outputs).length > 0)
87
+ obj["outputs"] = this._outputs;
88
+ obj["steps"] = this._steps.map((s) => s.toObject());
89
+ return obj;
90
+ }
91
+ }
92
+ exports.Job = Job;
93
+ //# sourceMappingURL=Job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Job.js","sourceRoot":"","sources":["../../src/actions/Job.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { StepEnv } from "./types";
2
+ export declare class Step {
3
+ private _name;
4
+ private _uses?;
5
+ private _run?;
6
+ private _with;
7
+ private _env;
8
+ private _id?;
9
+ private _if?;
10
+ private _workingDirectory?;
11
+ private _shell?;
12
+ constructor(name: string);
13
+ id(id: string): this;
14
+ /** Reference a GitHub Action, e.g. "actions/checkout@v4" */
15
+ uses(action: string, withOptions?: Record<string, string>): this;
16
+ /** Shell command(s) to run */
17
+ run(command: string): this;
18
+ with(options: Record<string, string>): this;
19
+ env(vars: StepEnv): this;
20
+ if(condition: string): this;
21
+ workingDirectory(dir: string): this;
22
+ shell(shell: "bash" | "sh" | "pwsh" | "python" | "cmd" | (string & {})): this;
23
+ toObject(): Record<string, unknown>;
24
+ }
25
+ //# sourceMappingURL=Step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Step.d.ts","sourceRoot":"","sources":["../../src/actions/Step.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,qBAAa,IAAI;IACf,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,KAAK,CAAC,CAAS;IACvB,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,GAAG,CAAC,CAAS;IACrB,OAAO,CAAC,GAAG,CAAC,CAAS;IACrB,OAAO,CAAC,iBAAiB,CAAC,CAAS;IACnC,OAAO,CAAC,MAAM,CAAC,CAAS;gBAEZ,IAAI,EAAE,MAAM;IAIxB,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKpB,4DAA4D;IAC5D,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAQhE,8BAA8B;IAC9B,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAK1B,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI;IAK3C,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAKxB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK3B,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKnC,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,IAAI;IAK7E,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAkBpC"}
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Step = void 0;
4
+ class Step {
5
+ constructor(name) {
6
+ this._with = {};
7
+ this._env = {};
8
+ this._name = name;
9
+ }
10
+ id(id) {
11
+ this._id = id;
12
+ return this;
13
+ }
14
+ /** Reference a GitHub Action, e.g. "actions/checkout@v4" */
15
+ uses(action, withOptions) {
16
+ this._uses = action;
17
+ if (withOptions) {
18
+ this._with = { ...this._with, ...withOptions };
19
+ }
20
+ return this;
21
+ }
22
+ /** Shell command(s) to run */
23
+ run(command) {
24
+ this._run = command;
25
+ return this;
26
+ }
27
+ with(options) {
28
+ this._with = { ...this._with, ...options };
29
+ return this;
30
+ }
31
+ env(vars) {
32
+ this._env = { ...this._env, ...vars };
33
+ return this;
34
+ }
35
+ if(condition) {
36
+ this._if = condition;
37
+ return this;
38
+ }
39
+ workingDirectory(dir) {
40
+ this._workingDirectory = dir;
41
+ return this;
42
+ }
43
+ shell(shell) {
44
+ this._shell = shell;
45
+ return this;
46
+ }
47
+ toObject() {
48
+ if (!this._uses && !this._run) {
49
+ throw new Error(`Step "${this._name}" must have either .uses() or .run()`);
50
+ }
51
+ const obj = { name: this._name };
52
+ if (this._id)
53
+ obj["id"] = this._id;
54
+ if (this._if)
55
+ obj["if"] = this._if;
56
+ if (this._uses)
57
+ obj["uses"] = this._uses;
58
+ if (Object.keys(this._with).length > 0)
59
+ obj["with"] = this._with;
60
+ if (this._run)
61
+ obj["run"] = this._run;
62
+ if (this._workingDirectory)
63
+ obj["working-directory"] = this._workingDirectory;
64
+ if (this._shell)
65
+ obj["shell"] = this._shell;
66
+ if (Object.keys(this._env).length > 0)
67
+ obj["env"] = this._env;
68
+ return obj;
69
+ }
70
+ }
71
+ exports.Step = Step;
72
+ //# sourceMappingURL=Step.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Step.js","sourceRoot":"","sources":["../../src/actions/Step.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Builder } from "../core/Builder";
2
+ import { Job } from "./Job";
3
+ import type { PushTriggerOptions, PullRequestTriggerOptions, Permissions, StepEnv } from "./types";
4
+ type JobFactory = (job: Job) => void;
5
+ export declare class ActionsWorkflow extends Builder {
6
+ readonly kind = "ActionsWorkflow";
7
+ private _name;
8
+ private _triggers;
9
+ private _jobs;
10
+ private _env;
11
+ private _permissions?;
12
+ private _concurrency?;
13
+ constructor(name: string);
14
+ on(event: "push", options?: PushTriggerOptions): this;
15
+ on(event: "pull_request" | "pull_request_target", options?: PullRequestTriggerOptions): this;
16
+ on(event: "workflow_dispatch" | "workflow_call"): this;
17
+ on(event: "schedule", cron: string): this;
18
+ env(vars: StepEnv): this;
19
+ permissions(perms: Permissions): this;
20
+ concurrency(group: string, cancelInProgress?: boolean): this;
21
+ /** Define a job. The factory receives a Job builder to configure. */
22
+ job(id: string, factory: JobFactory): this;
23
+ outputPath(): string;
24
+ toObject(): Record<string, unknown>;
25
+ }
26
+ export {};
27
+ //# sourceMappingURL=Workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workflow.d.ts","sourceRoot":"","sources":["../../src/actions/Workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAC5B,OAAO,KAAK,EAEV,kBAAkB,EAClB,yBAAyB,EACzB,WAAW,EACX,OAAO,EACR,MAAM,SAAS,CAAC;AAEjB,KAAK,UAAU,GAAG,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;AAErC,qBAAa,eAAgB,SAAQ,OAAO;IAC1C,QAAQ,CAAC,IAAI,qBAAqB;IAElC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,YAAY,CAAC,CAAc;IACnC,OAAO,CAAC,YAAY,CAAC,CAAoD;gBAE7D,IAAI,EAAE,MAAM;IAKxB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,IAAI;IACrD,EAAE,CAAC,KAAK,EAAE,cAAc,GAAG,qBAAqB,EAAE,OAAO,CAAC,EAAE,yBAAyB,GAAG,IAAI;IAC5F,EAAE,CAAC,KAAK,EAAE,mBAAmB,GAAG,eAAe,GAAG,IAAI;IACtD,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAczC,GAAG,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;IAKxB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAKrC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,gBAAgB,UAAO,GAAG,IAAI;IAKzD,qEAAqE;IACrE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAO1C,UAAU,IAAI,MAAM;IAIpB,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAyBpC"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionsWorkflow = void 0;
4
+ const Builder_1 = require("../core/Builder");
5
+ const Job_1 = require("./Job");
6
+ class ActionsWorkflow extends Builder_1.Builder {
7
+ constructor(name) {
8
+ super();
9
+ this.kind = "ActionsWorkflow";
10
+ this._triggers = {};
11
+ this._jobs = new Map();
12
+ this._env = {};
13
+ this._name = name;
14
+ }
15
+ on(event, optionsOrCron) {
16
+ if (event === "schedule" && typeof optionsOrCron === "string") {
17
+ const existing = this._triggers["schedule"] ?? [];
18
+ this._triggers["schedule"] = [...existing, { cron: optionsOrCron }];
19
+ }
20
+ else if (optionsOrCron && typeof optionsOrCron === "object") {
21
+ this._triggers[event] = optionsOrCron;
22
+ }
23
+ else {
24
+ // null means the trigger fires with no filter options
25
+ this._triggers[event] = null;
26
+ }
27
+ return this;
28
+ }
29
+ env(vars) {
30
+ this._env = { ...this._env, ...vars };
31
+ return this;
32
+ }
33
+ permissions(perms) {
34
+ this._permissions = perms;
35
+ return this;
36
+ }
37
+ concurrency(group, cancelInProgress = true) {
38
+ this._concurrency = { group, "cancel-in-progress": cancelInProgress };
39
+ return this;
40
+ }
41
+ /** Define a job. The factory receives a Job builder to configure. */
42
+ job(id, factory) {
43
+ const j = new Job_1.Job();
44
+ factory(j);
45
+ this._jobs.set(id, j);
46
+ return this;
47
+ }
48
+ outputPath() {
49
+ return `.github/workflows/${this._name}.yml`;
50
+ }
51
+ toObject() {
52
+ if (Object.keys(this._triggers).length === 0) {
53
+ throw new Error(`Workflow "${this._name}" must have at least one trigger via .on()`);
54
+ }
55
+ if (this._jobs.size === 0) {
56
+ throw new Error(`Workflow "${this._name}" must have at least one job`);
57
+ }
58
+ const obj = {
59
+ name: this._name,
60
+ on: this._triggers,
61
+ };
62
+ if (this._permissions)
63
+ obj["permissions"] = this._permissions;
64
+ if (Object.keys(this._env).length > 0)
65
+ obj["env"] = this._env;
66
+ if (this._concurrency)
67
+ obj["concurrency"] = this._concurrency;
68
+ const jobs = {};
69
+ for (const [id, job] of this._jobs) {
70
+ jobs[id] = job.toObject();
71
+ }
72
+ obj["jobs"] = jobs;
73
+ return obj;
74
+ }
75
+ }
76
+ exports.ActionsWorkflow = ActionsWorkflow;
77
+ //# sourceMappingURL=Workflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workflow.js","sourceRoot":"","sources":["../../src/actions/Workflow.ts"],"names":[],"mappings":"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"}