@synergenius/flow-weaver 0.17.6 → 0.17.8

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 (52) hide show
  1. package/dist/api/parse.d.ts +5 -0
  2. package/dist/api/parse.js +4 -0
  3. package/dist/ast/types.d.ts +2 -0
  4. package/dist/cli/commands/compile.js +2 -1
  5. package/dist/cli/commands/init.js +15 -9
  6. package/dist/cli/commands/validate.js +1 -1
  7. package/dist/cli/exports.d.ts +17 -0
  8. package/dist/cli/exports.js +23 -0
  9. package/dist/cli/flow-weaver.mjs +59021 -62127
  10. package/dist/cli/templates/index.js +8 -1
  11. package/dist/extensions/index.d.ts +10 -6
  12. package/dist/extensions/index.js +11 -6
  13. package/dist/generated-version.d.ts +1 -1
  14. package/dist/generated-version.js +1 -1
  15. package/dist/generator/index.d.ts +11 -0
  16. package/dist/generator/index.js +11 -0
  17. package/dist/parser.d.ts +7 -0
  18. package/dist/parser.js +29 -0
  19. package/package.json +11 -7
  20. package/dist/extensions/cicd/base-target.d.ts +0 -110
  21. package/dist/extensions/cicd/base-target.js +0 -397
  22. package/dist/extensions/cicd/detection.d.ts +0 -33
  23. package/dist/extensions/cicd/detection.js +0 -88
  24. package/dist/extensions/cicd/docs/cicd.md +0 -395
  25. package/dist/extensions/cicd/index.d.ts +0 -15
  26. package/dist/extensions/cicd/index.js +0 -15
  27. package/dist/extensions/cicd/register.d.ts +0 -11
  28. package/dist/extensions/cicd/register.js +0 -62
  29. package/dist/extensions/cicd/rules.d.ts +0 -30
  30. package/dist/extensions/cicd/rules.js +0 -288
  31. package/dist/extensions/cicd/tag-handler.d.ts +0 -14
  32. package/dist/extensions/cicd/tag-handler.js +0 -504
  33. package/dist/extensions/cicd/templates/cicd-docker.d.ts +0 -9
  34. package/dist/extensions/cicd/templates/cicd-docker.js +0 -110
  35. package/dist/extensions/cicd/templates/cicd-matrix.d.ts +0 -9
  36. package/dist/extensions/cicd/templates/cicd-matrix.js +0 -112
  37. package/dist/extensions/cicd/templates/cicd-multi-env.d.ts +0 -9
  38. package/dist/extensions/cicd/templates/cicd-multi-env.js +0 -126
  39. package/dist/extensions/cicd/templates/cicd-test-deploy.d.ts +0 -11
  40. package/dist/extensions/cicd/templates/cicd-test-deploy.js +0 -156
  41. package/dist/extensions/inngest/dev-mode.d.ts +0 -9
  42. package/dist/extensions/inngest/dev-mode.js +0 -213
  43. package/dist/extensions/inngest/generator.d.ts +0 -53
  44. package/dist/extensions/inngest/generator.js +0 -1176
  45. package/dist/extensions/inngest/index.d.ts +0 -2
  46. package/dist/extensions/inngest/index.js +0 -2
  47. package/dist/extensions/inngest/register.d.ts +0 -6
  48. package/dist/extensions/inngest/register.js +0 -23
  49. package/dist/extensions/inngest/templates/ai-agent-durable.d.ts +0 -8
  50. package/dist/extensions/inngest/templates/ai-agent-durable.js +0 -334
  51. package/dist/extensions/inngest/templates/ai-pipeline-durable.d.ts +0 -8
  52. package/dist/extensions/inngest/templates/ai-pipeline-durable.js +0 -326
@@ -1,504 +0,0 @@
1
- /**
2
- * CI/CD tag handler for the TagHandlerRegistry.
3
- *
4
- * Handles all CI/CD annotation tags: @secret, @runner, @cache, @artifact,
5
- * @environment, @matrix, @service, @concurrency, @job, @stage, @variables,
6
- * @before_script, @tags, @includes, plus the synthetic _cicdTrigger tag
7
- * for CI/CD trigger variants of @trigger.
8
- *
9
- * Each parser writes to ctx.deploy (the 'cicd' namespace slot) using the
10
- * same structures as the former jsdoc-parser.ts private methods.
11
- */
12
- export const cicdTagHandler = (tagName, comment, ctx) => {
13
- const d = ctx.deploy;
14
- const warnings = ctx.warnings;
15
- const text = comment.trim();
16
- switch (tagName) {
17
- case 'secret':
18
- parseSecret(text, d, warnings);
19
- break;
20
- case 'runner': {
21
- const val = text.replace(/^["']|["']$/g, '');
22
- if (val)
23
- d['runner'] = val;
24
- break;
25
- }
26
- case 'cache':
27
- parseCache(text, d, warnings);
28
- break;
29
- case 'artifact':
30
- parseArtifact(text, d, warnings);
31
- break;
32
- case 'environment':
33
- parseEnvironment(text, d, warnings);
34
- break;
35
- case 'matrix':
36
- parseMatrix(text, d, warnings);
37
- break;
38
- case 'service':
39
- parseService(text, d, warnings);
40
- break;
41
- case 'concurrency':
42
- parseConcurrency(text, d, warnings);
43
- break;
44
- case 'job':
45
- parseJob(text, d, warnings);
46
- break;
47
- case 'stage':
48
- parseStage(text, d, warnings);
49
- break;
50
- case 'variables':
51
- parseVariables(text, d, warnings);
52
- break;
53
- case 'before_script':
54
- parseBeforeScript(text, d, warnings);
55
- break;
56
- case 'tags':
57
- parseTags(text, d, warnings);
58
- break;
59
- case 'includes':
60
- parseIncludes(text, d, warnings);
61
- break;
62
- case '_cicdTrigger':
63
- parseCicdTrigger(text, d, warnings);
64
- break;
65
- }
66
- };
67
- function parseSecret(text, d, warnings) {
68
- if (!text) {
69
- warnings.push('Empty @secret tag. Expected: @secret SECRET_NAME - description');
70
- return;
71
- }
72
- const match = text.match(/^(\S+)(.*?)(?:\s+-\s+(.*))?$/);
73
- if (!match) {
74
- warnings.push(`Invalid @secret format: @secret ${text}`);
75
- return;
76
- }
77
- const name = match[1];
78
- const attrs = match[2] || '';
79
- const description = match[3]?.trim();
80
- const secret = { name };
81
- if (description)
82
- secret.description = description;
83
- const scopeMatch = attrs.match(/scope\s*=\s*"([^"]+)"/);
84
- if (scopeMatch)
85
- secret.scope = scopeMatch[1];
86
- const platformMatch = attrs.match(/platform\s*=\s*"([^"]+)"/);
87
- if (platformMatch) {
88
- const validPlatforms = ['github', 'gitlab', 'all'];
89
- const p = platformMatch[1];
90
- if (validPlatforms.includes(p)) {
91
- secret.platform = p;
92
- }
93
- else {
94
- warnings.push(`Invalid @secret platform "${platformMatch[1]}". Must be: github, gitlab, or all`);
95
- }
96
- }
97
- const secrets = d['secrets'] ?? [];
98
- secrets.push(secret);
99
- d['secrets'] = secrets;
100
- }
101
- function parseCache(text, d, warnings) {
102
- if (!text) {
103
- warnings.push('Empty @cache tag. Expected: @cache npm key="package-lock.json"');
104
- return;
105
- }
106
- const parts = text.match(/^(\S+)(.*)?$/);
107
- if (!parts) {
108
- warnings.push(`Invalid @cache format: @cache ${text}`);
109
- return;
110
- }
111
- const cache = { strategy: parts[1] };
112
- const rest = parts[2] || '';
113
- const keyMatch = rest.match(/key\s*=\s*"([^"]+)"/);
114
- if (keyMatch)
115
- cache.key = keyMatch[1];
116
- const pathMatch = rest.match(/path\s*=\s*"([^"]+)"/);
117
- if (pathMatch)
118
- cache.path = pathMatch[1];
119
- const caches = d['caches'] ?? [];
120
- caches.push(cache);
121
- d['caches'] = caches;
122
- }
123
- function parseArtifact(text, d, warnings) {
124
- if (!text) {
125
- warnings.push('Empty @artifact tag. Expected: @artifact name path="dist/"');
126
- return;
127
- }
128
- const nameMatch = text.match(/^(\S+)/);
129
- if (!nameMatch) {
130
- warnings.push(`Invalid @artifact format: @artifact ${text}`);
131
- return;
132
- }
133
- const pathMatch = text.match(/path\s*=\s*"([^"]+)"/);
134
- if (!pathMatch) {
135
- warnings.push(`@artifact requires path="...": @artifact ${text}`);
136
- return;
137
- }
138
- const artifact = {
139
- name: nameMatch[1],
140
- path: pathMatch[1],
141
- };
142
- const retentionMatch = text.match(/retention\s*=\s*(\d+)/);
143
- if (retentionMatch)
144
- artifact.retention = parseInt(retentionMatch[1], 10);
145
- const artifacts = d['artifacts'] ?? [];
146
- artifacts.push(artifact);
147
- d['artifacts'] = artifacts;
148
- }
149
- function parseEnvironment(text, d, warnings) {
150
- if (!text) {
151
- warnings.push('Empty @environment tag. Expected: @environment production url="https://app.com"');
152
- return;
153
- }
154
- const nameMatch = text.match(/^(\S+)/);
155
- if (!nameMatch) {
156
- warnings.push(`Invalid @environment format: @environment ${text}`);
157
- return;
158
- }
159
- const env = { name: nameMatch[1] };
160
- const urlMatch = text.match(/url\s*=\s*"([^"]+)"/);
161
- if (urlMatch)
162
- env.url = urlMatch[1];
163
- const reviewersMatch = text.match(/reviewers\s*=\s*(\d+)/);
164
- if (reviewersMatch)
165
- env.reviewers = parseInt(reviewersMatch[1], 10);
166
- const environments = d['environments'] ?? [];
167
- environments.push(env);
168
- d['environments'] = environments;
169
- }
170
- function parseMatrix(text, d, warnings) {
171
- if (!text) {
172
- warnings.push('Empty @matrix tag. Expected: @matrix node="18,20,22" os="ubuntu-latest"');
173
- return;
174
- }
175
- const matrix = d['matrix'] ?? { dimensions: {} };
176
- d['matrix'] = matrix;
177
- const isInclude = text.startsWith('include ');
178
- const isExclude = text.startsWith('exclude ');
179
- if (isInclude || isExclude) {
180
- const rest = text.slice(isInclude ? 8 : 8);
181
- const entry = {};
182
- const kvRegex = /(\w[\w-]*)\s*=\s*"([^"]+)"/g;
183
- let m;
184
- while ((m = kvRegex.exec(rest)) !== null) {
185
- entry[m[1]] = m[2];
186
- }
187
- if (Object.keys(entry).length > 0) {
188
- if (isInclude) {
189
- matrix.include = matrix.include || [];
190
- matrix.include.push(entry);
191
- }
192
- else {
193
- matrix.exclude = matrix.exclude || [];
194
- matrix.exclude.push(entry);
195
- }
196
- }
197
- return;
198
- }
199
- const kvRegex = /(\w[\w-]*)\s*=\s*"([^"]+)"/g;
200
- let m;
201
- while ((m = kvRegex.exec(text)) !== null) {
202
- matrix.dimensions[m[1]] = m[2].split(',').map(v => v.trim());
203
- }
204
- }
205
- function parseService(text, d, warnings) {
206
- if (!text) {
207
- warnings.push('Empty @service tag. Expected: @service postgres image="postgres:16"');
208
- return;
209
- }
210
- const nameMatch = text.match(/^(\S+)/);
211
- if (!nameMatch) {
212
- warnings.push(`Invalid @service format: @service ${text}`);
213
- return;
214
- }
215
- const imageMatch = text.match(/image\s*=\s*"([^"]+)"/);
216
- if (!imageMatch) {
217
- warnings.push(`@service requires image="...": @service ${text}`);
218
- return;
219
- }
220
- const svc = {
221
- name: nameMatch[1],
222
- image: imageMatch[1],
223
- };
224
- const envMatch = text.match(/env\s*=\s*"([^"]+)"/);
225
- if (envMatch) {
226
- svc.env = {};
227
- for (const pair of envMatch[1].split(',')) {
228
- const [k, ...vParts] = pair.split('=');
229
- if (k && vParts.length > 0)
230
- svc.env[k.trim()] = vParts.join('=').trim();
231
- }
232
- }
233
- const portsMatch = text.match(/ports\s*=\s*"([^"]+)"/);
234
- if (portsMatch) {
235
- svc.ports = portsMatch[1].split(',').map(p => p.trim());
236
- }
237
- const services = d['services'] ?? [];
238
- services.push(svc);
239
- d['services'] = services;
240
- }
241
- function parseConcurrency(text, d, warnings) {
242
- if (!text) {
243
- warnings.push('Empty @concurrency tag. Expected: @concurrency group="deploy"');
244
- return;
245
- }
246
- const groupMatch = text.match(/group\s*=\s*"([^"]+)"/);
247
- if (!groupMatch) {
248
- const bareMatch = text.match(/^(\S+)/);
249
- if (bareMatch) {
250
- d['concurrency'] = { group: bareMatch[1], cancelInProgress: false };
251
- }
252
- else {
253
- warnings.push(`Invalid @concurrency format: @concurrency ${text}`);
254
- }
255
- return;
256
- }
257
- const cancelMatch = text.match(/cancel-in-progress\s*=\s*(true|false)/);
258
- d['concurrency'] = {
259
- group: groupMatch[1],
260
- cancelInProgress: cancelMatch ? cancelMatch[1] === 'true' : false,
261
- };
262
- }
263
- function parseJob(text, d, warnings) {
264
- if (!text) {
265
- warnings.push('Empty @job tag. Expected: @job <name> key=value ...');
266
- return;
267
- }
268
- const spaceIdx = text.indexOf(' ');
269
- const jobId = spaceIdx === -1 ? text : text.substring(0, spaceIdx);
270
- const rest = spaceIdx === -1 ? '' : text.substring(spaceIdx + 1);
271
- const jobs = d['jobs'] ?? [];
272
- d['jobs'] = jobs;
273
- let jc = jobs.find(j => j.id === jobId);
274
- if (!jc) {
275
- jc = { id: jobId };
276
- jobs.push(jc);
277
- }
278
- if (!rest)
279
- return;
280
- const kvRegex = /(\w[\w-]*)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|'((?:[^'\\]|\\.)*)'|([\S]+))/g;
281
- let match;
282
- while ((match = kvRegex.exec(rest)) !== null) {
283
- const key = match[1];
284
- const value = match[2] !== undefined ? match[2] : match[3] !== undefined ? match[3] : match[4];
285
- switch (key) {
286
- case 'retry': {
287
- const n = parseInt(value, 10);
288
- if (!isNaN(n) && n >= 0)
289
- jc.retry = n;
290
- else
291
- warnings.push(`Invalid retry value "${value}" in @job ${jobId}`);
292
- break;
293
- }
294
- case 'allow_failure':
295
- jc.allowFailure = value === 'true';
296
- break;
297
- case 'timeout':
298
- jc.timeout = value;
299
- break;
300
- case 'runner':
301
- jc.runner = value;
302
- break;
303
- case 'tags':
304
- jc.tags = value.split(',').map(t => t.trim()).filter(Boolean);
305
- break;
306
- case 'coverage':
307
- jc.coverage = value;
308
- break;
309
- case 'extends':
310
- jc.extends = value;
311
- break;
312
- case 'variables': {
313
- jc.variables = jc.variables || {};
314
- for (const pair of value.split(',')) {
315
- const eqIdx = pair.indexOf('=');
316
- if (eqIdx > 0) {
317
- jc.variables[pair.substring(0, eqIdx).trim()] = pair.substring(eqIdx + 1).trim();
318
- }
319
- }
320
- break;
321
- }
322
- case 'before_script':
323
- jc.beforeScript = value.split(',').map(s => s.trim()).filter(Boolean);
324
- break;
325
- case 'rules':
326
- jc.rules = jc.rules || [];
327
- jc.rules.push({ if: value });
328
- break;
329
- case 'when': {
330
- // Modifier: sets `when` on the last rule, or creates a standalone rule
331
- jc.rules = jc.rules || [];
332
- if (jc.rules.length === 0)
333
- jc.rules.push({});
334
- jc.rules[jc.rules.length - 1].when = value;
335
- break;
336
- }
337
- case 'changes': {
338
- // Modifier: sets `changes` on the last rule
339
- jc.rules = jc.rules || [];
340
- if (jc.rules.length === 0)
341
- jc.rules.push({});
342
- jc.rules[jc.rules.length - 1].changes = value.split(',').map(s => s.trim()).filter(Boolean);
343
- break;
344
- }
345
- case 'reports': {
346
- jc.reports = jc.reports || [];
347
- for (const pair of value.split(',')) {
348
- const eqIdx = pair.indexOf('=');
349
- if (eqIdx > 0) {
350
- jc.reports.push({
351
- type: pair.substring(0, eqIdx).trim(),
352
- path: pair.substring(eqIdx + 1).trim(),
353
- });
354
- }
355
- }
356
- break;
357
- }
358
- default:
359
- warnings.push(`Unknown @job attribute "${key}" in @job ${jobId}`);
360
- }
361
- }
362
- }
363
- function parseStage(text, d, warnings) {
364
- if (!text) {
365
- warnings.push('Empty @stage tag. Expected: @stage <name>');
366
- return;
367
- }
368
- const stages = d['stages'] ?? [];
369
- d['stages'] = stages;
370
- const name = text.split(/\s+/)[0];
371
- if (!stages.some(s => s.name === name)) {
372
- stages.push({ name });
373
- }
374
- }
375
- function parseVariables(text, d, warnings) {
376
- if (!text) {
377
- warnings.push('Empty @variables tag. Expected: @variables KEY=VALUE');
378
- return;
379
- }
380
- const variables = d['variables'] ?? {};
381
- d['variables'] = variables;
382
- const kvRegex = /(\w[\w-]*)\s*=\s*(?:"((?:[^"\\]|\\.)*)"|(\S+))/g;
383
- let match;
384
- while ((match = kvRegex.exec(text)) !== null) {
385
- variables[match[1]] = match[2] !== undefined ? match[2] : match[3];
386
- }
387
- }
388
- function parseBeforeScript(text, d, warnings) {
389
- if (!text) {
390
- warnings.push('Empty @before_script tag. Expected: @before_script "cmd1" "cmd2"');
391
- return;
392
- }
393
- const beforeScript = d['beforeScript'] ?? [];
394
- d['beforeScript'] = beforeScript;
395
- const strRegex = /"((?:[^"\\]|\\.)*)"/g;
396
- let match;
397
- const commands = [];
398
- while ((match = strRegex.exec(text)) !== null) {
399
- commands.push(match[1]);
400
- }
401
- if (commands.length > 0) {
402
- beforeScript.push(...commands);
403
- }
404
- else {
405
- beforeScript.push(text);
406
- }
407
- }
408
- function parseTags(text, d, warnings) {
409
- if (!text) {
410
- warnings.push('Empty @tags tag. Expected: @tags tag1 tag2');
411
- return;
412
- }
413
- d['tags'] = text.split(/[\s,]+/).filter(Boolean);
414
- }
415
- function parseIncludes(text, d, warnings) {
416
- if (!text) {
417
- warnings.push('Empty @includes tag. Expected: @includes local="path"');
418
- return;
419
- }
420
- const includes = d['includes'] ?? [];
421
- d['includes'] = includes;
422
- const localMatch = text.match(/local\s*=\s*"([^"]+)"/);
423
- const templateMatch = text.match(/template\s*=\s*"([^"]+)"/);
424
- const remoteMatch = text.match(/remote\s*=\s*"([^"]+)"/);
425
- const projectMatch = text.match(/project\s*=\s*"([^"]+)"/);
426
- if (localMatch) {
427
- includes.push({ type: 'local', file: localMatch[1] });
428
- }
429
- else if (templateMatch) {
430
- includes.push({ type: 'template', file: templateMatch[1] });
431
- }
432
- else if (remoteMatch) {
433
- includes.push({ type: 'remote', file: remoteMatch[1] });
434
- }
435
- else if (projectMatch) {
436
- const fileMatch = text.match(/file\s*=\s*"([^"]+)"/);
437
- const refMatch = text.match(/ref\s*=\s*"([^"]+)"/);
438
- if (fileMatch) {
439
- includes.push({
440
- type: 'project',
441
- file: fileMatch[1],
442
- project: projectMatch[1],
443
- ...(refMatch && { ref: refMatch[1] }),
444
- });
445
- }
446
- else {
447
- warnings.push(`@includes project requires file="...": @includes ${text}`);
448
- }
449
- }
450
- else {
451
- warnings.push(`Invalid @includes format: @includes ${text}. Expected: @includes local="path" or @includes template="name"`);
452
- }
453
- }
454
- function parseCicdTrigger(text, d, warnings) {
455
- // Check for CI/CD trigger types: push, pull_request, dispatch, tag, schedule
456
- const cicdMatch = text.match(/^(push|pull_request|dispatch|tag|schedule)\b(.*)?$/);
457
- if (!cicdMatch) {
458
- // Also detect standalone cron="..." as schedule trigger
459
- const cronOnlyMatch = text.match(/^cron\s*=\s*"([^"]+)"/);
460
- if (cronOnlyMatch) {
461
- const triggers = d['triggers'] ?? [];
462
- d['triggers'] = triggers;
463
- triggers.push({ type: 'schedule', cron: cronOnlyMatch[1] });
464
- return;
465
- }
466
- warnings.push(`Invalid CI/CD trigger format: @trigger ${text}`);
467
- return;
468
- }
469
- const type = cicdMatch[1];
470
- const rest = (cicdMatch[2] || '').trim();
471
- const triggerType = type;
472
- const trigger = { type: triggerType };
473
- const branchesMatch = rest.match(/branches\s*=\s*"([^"]+)"/);
474
- if (branchesMatch)
475
- trigger.branches = branchesMatch[1].split(',').map(b => b.trim());
476
- const pathsMatch = rest.match(/(?<![a-z])paths\s*=\s*"([^"]+)"/);
477
- if (pathsMatch)
478
- trigger.paths = pathsMatch[1].split(',').map(p => p.trim());
479
- const pathsIgnoreMatch = rest.match(/paths-ignore\s*=\s*"([^"]+)"/);
480
- if (pathsIgnoreMatch)
481
- trigger.pathsIgnore = pathsIgnoreMatch[1].split(',').map(p => p.trim());
482
- const typesMatch = rest.match(/types\s*=\s*"([^"]+)"/);
483
- if (typesMatch)
484
- trigger.types = typesMatch[1].split(',').map(t => t.trim());
485
- const patternMatch = rest.match(/pattern\s*=\s*"([^"]+)"/);
486
- if (patternMatch)
487
- trigger.pattern = patternMatch[1];
488
- const cronMatch = rest.match(/cron\s*=\s*"([^"]+)"/);
489
- if (cronMatch)
490
- trigger.cron = cronMatch[1];
491
- const inputsMatch = rest.match(/inputs\s*=\s*"([^"]+)"/);
492
- if (inputsMatch) {
493
- trigger.inputs = {};
494
- for (const input of inputsMatch[1].split(',')) {
495
- const name = input.trim();
496
- if (name)
497
- trigger.inputs[name] = {};
498
- }
499
- }
500
- const triggers = d['triggers'] ?? [];
501
- d['triggers'] = triggers;
502
- triggers.push(trigger);
503
- }
504
- //# sourceMappingURL=tag-handler.js.map
@@ -1,9 +0,0 @@
1
- /**
2
- * CI/CD: Docker Pipeline template
3
- *
4
- * Generates a Flow Weaver workflow for building and pushing Docker images:
5
- * checkout → docker-login → docker-build → docker-push
6
- */
7
- import type { WorkflowTemplate } from '../../../cli/templates/index.js';
8
- export declare const cicdDockerTemplate: WorkflowTemplate;
9
- //# sourceMappingURL=cicd-docker.d.ts.map
@@ -1,110 +0,0 @@
1
- /**
2
- * CI/CD: Docker Pipeline template
3
- *
4
- * Generates a Flow Weaver workflow for building and pushing Docker images:
5
- * checkout → docker-login → docker-build → docker-push
6
- */
7
- const configSchema = {
8
- platform: {
9
- type: 'select',
10
- label: 'CI/CD Platform',
11
- default: 'github-actions',
12
- options: [
13
- { value: 'github-actions', label: 'GitHub Actions' },
14
- { value: 'gitlab-ci', label: 'GitLab CI' },
15
- ],
16
- },
17
- registry: {
18
- type: 'select',
19
- label: 'Container Registry',
20
- default: 'ghcr',
21
- options: [
22
- { value: 'ghcr', label: 'GitHub Container Registry (ghcr.io)' },
23
- { value: 'dockerhub', label: 'Docker Hub' },
24
- { value: 'ecr', label: 'AWS ECR' },
25
- { value: 'gcr', label: 'Google Container Registry' },
26
- ],
27
- },
28
- };
29
- export const cicdDockerTemplate = {
30
- id: 'cicd-docker',
31
- name: 'CI/CD: Docker Pipeline',
32
- description: 'Build and push Docker images to a container registry',
33
- category: 'automation',
34
- configSchema,
35
- generate: (opts) => {
36
- const name = opts.workflowName || 'dockerPipeline';
37
- const registry = opts.config?.registry || 'ghcr';
38
- const registrySecrets = {
39
- ghcr: ' * @secret GITHUB_TOKEN - GitHub token for ghcr.io',
40
- dockerhub: ' * @secret DOCKER_USERNAME - Docker Hub username\n * @secret DOCKER_PASSWORD - Docker Hub password',
41
- ecr: ' * @secret AWS_ACCESS_KEY_ID - AWS access key\n * @secret AWS_SECRET_ACCESS_KEY - AWS secret key',
42
- gcr: ' * @secret GCR_KEY - Google Cloud service account key',
43
- };
44
- const registryConnect = {
45
- ghcr: ' * @connect secret:GITHUB_TOKEN -> login.token',
46
- dockerhub: ' * @connect secret:DOCKER_USERNAME -> login.username\n * @connect secret:DOCKER_PASSWORD -> login.password',
47
- ecr: ' * @connect secret:AWS_ACCESS_KEY_ID -> login.accessKey\n * @connect secret:AWS_SECRET_ACCESS_KEY -> login.secretKey',
48
- gcr: ' * @connect secret:GCR_KEY -> login.serviceAccountKey',
49
- };
50
- return `/** @flowWeaver nodeType
51
- * @expression
52
- * @label Checkout code
53
- */
54
- function checkout(): { repo: string } { return { repo: '.' }; }
55
-
56
- /** @flowWeaver nodeType
57
- * @expression
58
- * @label Docker login
59
- */
60
- function dockerLogin(${registry === 'dockerhub' ? 'username: string = \'\', password: string = \'\'' : registry === 'ecr' ? 'accessKey: string = \'\', secretKey: string = \'\'' : registry === 'gcr' ? 'serviceAccountKey: string = \'\'' : 'token: string = \'\''}): { loggedIn: boolean } { return { loggedIn: true }; }
61
-
62
- /** @flowWeaver nodeType
63
- * @expression
64
- * @label Docker build
65
- */
66
- function dockerBuild(): { imageTag: string } { return { imageTag: 'latest' }; }
67
-
68
- /** @flowWeaver nodeType
69
- * @expression
70
- * @label Docker push
71
- */
72
- function dockerPush(): { digest: string } { return { digest: 'sha256:abc123' }; }
73
-
74
- /**
75
- * @flowWeaver workflow
76
- * @trigger push branches="main" paths="Dockerfile,src/**"
77
- * @trigger tag pattern="v*"
78
- * @runner ubuntu-latest
79
- ${registrySecrets[registry]}
80
- *
81
- * @node co checkout [job: "build"] [position: 270 0]
82
- * @node login dockerLogin [job: "build"] [position: 540 0]
83
- * @node build dockerBuild [job: "build"] [position: 810 0]
84
- * @node push dockerPush [job: "build"] [position: 1080 0]
85
- *
86
- * @path Start -> co -> login -> build -> push -> Exit
87
- * @position Start 0 0
88
- * @position Exit 1350 0
89
- ${registryConnect[registry]}
90
- * @connect push.digest -> Exit.imageDigest
91
- *
92
- * @param execute [order:-1] - Execute
93
- * @param params [order:0] - Params
94
- * @returns onSuccess [order:-2] - On Success
95
- * @returns onFailure [order:-1] - On Failure
96
- * @returns imageDigest [order:0] - Docker image digest
97
- */
98
- export async function ${name}(
99
- execute: boolean,
100
- params: Record<string, never> = {},
101
- ): Promise<{ onSuccess: boolean; onFailure: boolean; imageDigest: string | null }> {
102
- // @flow-weaver-body-start
103
- throw new Error('Compile with: npx flow-weaver compile <this-file>');
104
- // @flow-weaver-body-end
105
- return { onSuccess: false, onFailure: true, imageDigest: null };
106
- }
107
- `;
108
- },
109
- };
110
- //# sourceMappingURL=cicd-docker.js.map
@@ -1,9 +0,0 @@
1
- /**
2
- * CI/CD: Matrix Testing template
3
- *
4
- * Generates a pipeline with matrix strategy for testing across
5
- * multiple Node.js versions and/or operating systems.
6
- */
7
- import type { WorkflowTemplate } from '../../../cli/templates/index.js';
8
- export declare const cicdMatrixTemplate: WorkflowTemplate;
9
- //# sourceMappingURL=cicd-matrix.d.ts.map