@synergenius/flow-weaver 0.17.0 → 0.17.2
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/dist/api/index.d.ts +4 -1
- package/dist/api/index.js +4 -1
- package/dist/api/templates.js +2 -2
- package/dist/api/validate.d.ts +2 -2
- package/dist/api/validate.js +6 -6
- package/dist/api/validation-registry.d.ts +10 -0
- package/dist/api/validation-registry.js +10 -0
- package/dist/ast/types.d.ts +91 -4
- package/dist/built-in-nodes/invoke-workflow.d.ts +1 -1
- package/dist/built-in-nodes/invoke-workflow.js +1 -1
- package/dist/chevrotain-parser/connect-parser.js +25 -7
- package/dist/cli/commands/compile.d.ts +5 -9
- package/dist/cli/commands/compile.js +21 -14
- package/dist/cli/commands/dev.d.ts +2 -13
- package/dist/cli/commands/dev.js +10 -204
- package/dist/cli/commands/doctor.js +6 -3
- package/dist/cli/commands/export.d.ts +8 -17
- package/dist/cli/commands/export.js +8 -17
- package/dist/cli/commands/init-personas.d.ts +17 -6
- package/dist/cli/commands/init-personas.js +73 -24
- package/dist/cli/commands/init.d.ts +5 -2
- package/dist/cli/commands/init.js +73 -42
- package/dist/cli/commands/mcp-setup.d.ts +7 -0
- package/dist/cli/commands/mcp-setup.js +16 -1
- package/dist/cli/flow-weaver.mjs +71002 -70385
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +9 -7
- package/dist/cli/templates/index.d.ts +20 -1
- package/dist/cli/templates/index.js +66 -15
- package/dist/cli/templates/nodes/human-approval.js +2 -3
- package/dist/cli/templates/nodes/rag-retriever.js +1 -1
- package/dist/constants.d.ts +7 -0
- package/dist/constants.js +13 -3
- package/dist/context/index.js +13 -3
- package/dist/deployment/config/loader.js +2 -1
- package/dist/deployment/core/adapters.d.ts +1 -25
- package/dist/deployment/core/adapters.js +0 -95
- package/dist/deployment/core/formatters.d.ts +0 -15
- package/dist/deployment/core/formatters.js +0 -24
- package/dist/deployment/index.d.ts +7 -5
- package/dist/deployment/index.js +8 -5
- package/dist/deployment/types.d.ts +2 -45
- package/dist/diagram/html-viewer.js +65 -32
- package/dist/diagram/renderer.js +9 -6
- package/dist/diagram/theme.js +4 -0
- package/dist/diagram/types.d.ts +2 -0
- package/dist/doc-metadata/extractors/annotations.js +5 -5
- package/dist/doc-metadata/extractors/cli-commands.js +1 -1
- package/dist/doc-metadata/extractors/mcp-tools.js +1 -2
- package/dist/docs/index.d.ts +28 -1
- package/dist/docs/index.js +95 -28
- package/dist/export/index.d.ts +2 -3
- package/dist/{deployment/targets/cicd-base.d.ts → extensions/cicd/base-target.d.ts} +35 -36
- package/dist/{deployment/targets/cicd-base.js → extensions/cicd/base-target.js} +97 -57
- package/dist/{validation/cicd-detection.d.ts → extensions/cicd/detection.d.ts} +2 -2
- package/dist/{validation/cicd-detection.js → extensions/cicd/detection.js} +13 -1
- package/dist/extensions/cicd/docs/cicd.md +395 -0
- package/dist/extensions/cicd/index.d.ts +10 -0
- package/dist/extensions/cicd/index.js +10 -0
- package/dist/extensions/cicd/register.d.ts +11 -0
- package/dist/extensions/cicd/register.js +62 -0
- package/dist/extensions/cicd/rules.d.ts +30 -0
- package/dist/{validation/cicd-rules.js → extensions/cicd/rules.js} +60 -56
- package/dist/extensions/cicd/tag-handler.d.ts +14 -0
- package/dist/extensions/cicd/tag-handler.js +488 -0
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-docker.d.ts +1 -1
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-matrix.d.ts +1 -1
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-multi-env.d.ts +1 -1
- package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-test-deploy.d.ts +1 -1
- package/dist/extensions/index.d.ts +12 -0
- package/dist/extensions/index.js +12 -0
- package/dist/extensions/inngest/dev-mode.d.ts +9 -0
- package/dist/extensions/inngest/dev-mode.js +213 -0
- package/dist/{generator/inngest.d.ts → extensions/inngest/generator.d.ts} +2 -2
- package/dist/{generator/inngest.js → extensions/inngest/generator.js} +4 -4
- package/dist/extensions/inngest/index.d.ts +2 -0
- package/dist/extensions/inngest/index.js +2 -0
- package/dist/extensions/inngest/register.d.ts +6 -0
- package/dist/extensions/inngest/register.js +23 -0
- package/dist/extensions/inngest/templates/ai-agent-durable.d.ts +8 -0
- package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-agent-durable.js +8 -8
- package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-pipeline-durable.d.ts +2 -2
- package/dist/{cli/templates/workflows → extensions/inngest/templates}/ai-pipeline-durable.js +7 -7
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/dist/generator/compile-target-registry.d.ts +20 -0
- package/dist/generator/compile-target-registry.js +20 -0
- package/dist/generator/dev-mode-registry.d.ts +27 -0
- package/dist/generator/dev-mode-registry.js +20 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/jsdoc-parser.d.ts +12 -114
- package/dist/jsdoc-parser.js +57 -362
- package/dist/marketplace/index.d.ts +2 -2
- package/dist/marketplace/index.js +1 -1
- package/dist/marketplace/registry.d.ts +39 -1
- package/dist/marketplace/registry.js +77 -0
- package/dist/marketplace/types.d.ts +76 -3
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +2 -0
- package/dist/mcp/tools-export.js +3 -3
- package/dist/mcp/tools-query.js +17 -11
- package/dist/mcp/tools-template.js +1 -1
- package/dist/parser/tag-registry.d.ts +47 -0
- package/dist/parser/tag-registry.js +57 -0
- package/dist/parser.d.ts +3 -0
- package/dist/parser.js +10 -23
- package/dist/validation/rule-registry.d.ts +36 -0
- package/dist/validation/rule-registry.js +37 -0
- package/dist/validator.js +3 -3
- package/docs/reference/concepts.md +2 -1
- package/docs/reference/deployment.md +21 -0
- package/docs/reference/jsdoc-grammar.md +242 -1
- package/docs/reference/scaffold.md +0 -6
- package/package.json +9 -1
- package/dist/cli/templates/workflows/ai-agent-durable.d.ts +0 -8
- package/dist/export/templates.d.ts +0 -24
- package/dist/export/templates.js +0 -186
- package/dist/validation/cicd-rules.d.ts +0 -62
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-docker.js +0 -0
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-matrix.js +0 -0
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-multi-env.js +0 -0
- /package/dist/{cli/templates/workflows → extensions/cicd/templates}/cicd-test-deploy.js +0 -0
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Key responsibilities:
|
|
9
9
|
* - Build job graph from AST (group nodes by @job, compute dependencies)
|
|
10
|
-
* - Resolve secret wiring (secret: pseudo-node connections
|
|
10
|
+
* - Resolve secret wiring (secret: pseudo-node connections -> job env vars)
|
|
11
11
|
* - Inject artifact upload/download steps between jobs
|
|
12
12
|
* - Generate SECRETS_SETUP.md documentation
|
|
13
13
|
*/
|
|
14
14
|
import type { TWorkflowAST, TCICDSecret, TCICDCache, TCICDArtifact, TCICDService, TCICDMatrix } from '../../ast/types.js';
|
|
15
|
-
import { BaseExportTarget, type ExportOptions, type MultiWorkflowArtifacts, type CompiledWorkflow, type NodeTypeArtifacts, type NodeTypeInfo, type NodeTypeExportOptions, type BundleArtifacts, type BundleWorkflow, type BundleNodeType } from '
|
|
15
|
+
import { BaseExportTarget, type ExportOptions, type MultiWorkflowArtifacts, type CompiledWorkflow, type NodeTypeArtifacts, type NodeTypeInfo, type NodeTypeExportOptions, type BundleArtifacts, type BundleWorkflow, type BundleNodeType } from '../../deployment/targets/base.js';
|
|
16
16
|
export interface CICDStep {
|
|
17
17
|
/** Node instance ID */
|
|
18
18
|
id: string;
|
|
@@ -50,6 +50,37 @@ export interface CICDJob {
|
|
|
50
50
|
uploadArtifacts?: TCICDArtifact[];
|
|
51
51
|
/** Artifact names to download before this job */
|
|
52
52
|
downloadArtifacts?: string[];
|
|
53
|
+
/** Maximum retry count on failure (from @job) */
|
|
54
|
+
retry?: number;
|
|
55
|
+
/** Whether this job can fail without failing the pipeline (from @job) */
|
|
56
|
+
allowFailure?: boolean;
|
|
57
|
+
/** Job-level timeout duration (from @job) */
|
|
58
|
+
timeout?: string;
|
|
59
|
+
/** Environment variables (from @job or @variables) */
|
|
60
|
+
variables?: Record<string, string>;
|
|
61
|
+
/** Runner selection tags (from @job or @tags) */
|
|
62
|
+
tags?: string[];
|
|
63
|
+
/** Setup commands before main script (from @job or @before_script) */
|
|
64
|
+
beforeScript?: string[];
|
|
65
|
+
/** Conditional execution rules (from @job) */
|
|
66
|
+
rules?: Array<{
|
|
67
|
+
if?: string;
|
|
68
|
+
when?: string;
|
|
69
|
+
allowFailure?: boolean;
|
|
70
|
+
variables?: Record<string, string>;
|
|
71
|
+
changes?: string[];
|
|
72
|
+
}>;
|
|
73
|
+
/** Coverage regex pattern (from @job) */
|
|
74
|
+
coverage?: string;
|
|
75
|
+
/** Test/coverage report declarations (from @job) */
|
|
76
|
+
reports?: Array<{
|
|
77
|
+
type: string;
|
|
78
|
+
path: string;
|
|
79
|
+
}>;
|
|
80
|
+
/** GitLab template to extend (from @job) */
|
|
81
|
+
extends?: string;
|
|
82
|
+
/** Explicit stage name (from @stage) */
|
|
83
|
+
stage?: string;
|
|
53
84
|
}
|
|
54
85
|
export interface ActionMapping {
|
|
55
86
|
/** GitHub Actions `uses:` value */
|
|
@@ -63,49 +94,17 @@ export interface ActionMapping {
|
|
|
63
94
|
/** Human-readable step name */
|
|
64
95
|
label?: string;
|
|
65
96
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Default mapping from FW node types to CI/CD platform actions.
|
|
68
|
-
* Unknown node types fall back to a TODO placeholder.
|
|
69
|
-
*/
|
|
70
97
|
export declare const NODE_ACTION_MAP: Record<string, ActionMapping>;
|
|
71
98
|
export declare abstract class BaseCICDTarget extends BaseExportTarget {
|
|
72
|
-
/**
|
|
73
|
-
* CI/CD targets don't compile workflows — they read the AST and generate YAML.
|
|
74
|
-
* The generate() method must be implemented by each platform target.
|
|
75
|
-
*/
|
|
76
99
|
generateMultiWorkflow(_workflows: CompiledWorkflow[], _options: ExportOptions): Promise<MultiWorkflowArtifacts>;
|
|
77
100
|
generateNodeTypeService(_nodeTypes: NodeTypeInfo[], _options: NodeTypeExportOptions): Promise<NodeTypeArtifacts>;
|
|
78
101
|
generateBundle(_workflows: BundleWorkflow[], _nodeTypes: BundleNodeType[], _options: ExportOptions): Promise<BundleArtifacts>;
|
|
79
|
-
/**
|
|
80
|
-
* Resolve the action mapping for a node type.
|
|
81
|
-
* Priority: @deploy annotations on the node type → NODE_ACTION_MAP fallback → undefined.
|
|
82
|
-
*
|
|
83
|
-
* This makes marketplace packages self-describing: a node type with
|
|
84
|
-
* `@deploy github-actions action="actions/checkout@v4"` contributes its own mapping.
|
|
85
|
-
*/
|
|
86
102
|
protected resolveActionMapping(step: CICDStep, targetName: string): ActionMapping | undefined;
|
|
87
|
-
/**
|
|
88
|
-
* Build the job graph from the workflow AST.
|
|
89
|
-
* Groups nodes by their [job: "name"] attribute and computes dependencies
|
|
90
|
-
* from connections between nodes in different jobs.
|
|
91
|
-
*/
|
|
92
103
|
protected buildJobGraph(ast: TWorkflowAST): CICDJob[];
|
|
93
|
-
/**
|
|
94
|
-
* Topologically sort jobs so that dependencies come first.
|
|
95
|
-
*/
|
|
96
104
|
private topoSortJobs;
|
|
97
|
-
|
|
98
|
-
* Map secret:NAME connections to the jobs that need them.
|
|
99
|
-
* Populates job.secrets and step.env for each secret connection.
|
|
100
|
-
*/
|
|
105
|
+
private computeJobDepths;
|
|
101
106
|
protected resolveJobSecrets(jobs: CICDJob[], ast: TWorkflowAST, renderSecretRef: (name: string) => string): void;
|
|
102
|
-
/**
|
|
103
|
-
* Add artifact upload/download steps between jobs.
|
|
104
|
-
*/
|
|
105
107
|
protected injectArtifactSteps(jobs: CICDJob[], artifacts: TCICDArtifact[]): void;
|
|
106
|
-
/**
|
|
107
|
-
* Generate SECRETS_SETUP.md with per-secret setup instructions.
|
|
108
|
-
*/
|
|
109
108
|
protected generateSecretsDoc(secrets: TCICDSecret[], platform: string): string;
|
|
110
109
|
}
|
|
111
|
-
//# sourceMappingURL=
|
|
110
|
+
//# sourceMappingURL=base-target.d.ts.map
|
|
@@ -7,15 +7,11 @@
|
|
|
7
7
|
*
|
|
8
8
|
* Key responsibilities:
|
|
9
9
|
* - Build job graph from AST (group nodes by @job, compute dependencies)
|
|
10
|
-
* - Resolve secret wiring (secret: pseudo-node connections
|
|
10
|
+
* - Resolve secret wiring (secret: pseudo-node connections -> job env vars)
|
|
11
11
|
* - Inject artifact upload/download steps between jobs
|
|
12
12
|
* - Generate SECRETS_SETUP.md documentation
|
|
13
13
|
*/
|
|
14
|
-
import { BaseExportTarget, } from '
|
|
15
|
-
/**
|
|
16
|
-
* Default mapping from FW node types to CI/CD platform actions.
|
|
17
|
-
* Unknown node types fall back to a TODO placeholder.
|
|
18
|
-
*/
|
|
14
|
+
import { BaseExportTarget, } from '../../deployment/targets/base.js';
|
|
19
15
|
export const NODE_ACTION_MAP = {
|
|
20
16
|
checkout: {
|
|
21
17
|
githubAction: 'actions/checkout@v4',
|
|
@@ -83,7 +79,7 @@ export const NODE_ACTION_MAP = {
|
|
|
83
79
|
},
|
|
84
80
|
'slack-notify': {
|
|
85
81
|
githubAction: 'slackapi/slack-github-action@v1',
|
|
86
|
-
gitlabScript: ['curl -X POST -H "Content-type: application/json" --data "{
|
|
82
|
+
gitlabScript: ['curl -X POST -H "Content-type: application/json" --data "{\\\"text\\\":\\\"Pipeline complete\\\"}" $SLACK_WEBHOOK_URL'],
|
|
87
83
|
label: 'Send Slack notification',
|
|
88
84
|
},
|
|
89
85
|
'health-check': {
|
|
@@ -101,11 +97,6 @@ export const NODE_ACTION_MAP = {
|
|
|
101
97
|
// Base CI/CD Target
|
|
102
98
|
// ---------------------------------------------------------------------------
|
|
103
99
|
export class BaseCICDTarget extends BaseExportTarget {
|
|
104
|
-
/**
|
|
105
|
-
* CI/CD targets don't compile workflows — they read the AST and generate YAML.
|
|
106
|
-
* The generate() method must be implemented by each platform target.
|
|
107
|
-
*/
|
|
108
|
-
// Not used by CI/CD targets (they don't produce serverless handlers)
|
|
109
100
|
async generateMultiWorkflow(_workflows, _options) {
|
|
110
101
|
throw new Error('CI/CD targets use generate() with AST, not generateMultiWorkflow()');
|
|
111
102
|
}
|
|
@@ -118,15 +109,7 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
118
109
|
// ---------------------------------------------------------------------------
|
|
119
110
|
// Shared CI/CD Logic
|
|
120
111
|
// ---------------------------------------------------------------------------
|
|
121
|
-
/**
|
|
122
|
-
* Resolve the action mapping for a node type.
|
|
123
|
-
* Priority: @deploy annotations on the node type → NODE_ACTION_MAP fallback → undefined.
|
|
124
|
-
*
|
|
125
|
-
* This makes marketplace packages self-describing: a node type with
|
|
126
|
-
* `@deploy github-actions action="actions/checkout@v4"` contributes its own mapping.
|
|
127
|
-
*/
|
|
128
112
|
resolveActionMapping(step, targetName) {
|
|
129
|
-
// 1. Check @deploy annotations on the node type
|
|
130
113
|
const deployConfig = step.nodeTypeDeploy?.[targetName];
|
|
131
114
|
if (deployConfig) {
|
|
132
115
|
return {
|
|
@@ -145,23 +128,16 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
145
128
|
label: deployConfig.label || step.name,
|
|
146
129
|
};
|
|
147
130
|
}
|
|
148
|
-
|
|
149
|
-
|
|
131
|
+
return NODE_ACTION_MAP[step.nodeType]
|
|
132
|
+
|| NODE_ACTION_MAP[step.nodeType.replace(/([A-Z])/g, '-$1').toLowerCase()];
|
|
150
133
|
}
|
|
151
|
-
/**
|
|
152
|
-
* Build the job graph from the workflow AST.
|
|
153
|
-
* Groups nodes by their [job: "name"] attribute and computes dependencies
|
|
154
|
-
* from connections between nodes in different jobs.
|
|
155
|
-
*/
|
|
156
134
|
buildJobGraph(ast) {
|
|
157
|
-
// Build node type lookup for @deploy annotations
|
|
158
135
|
const nodeTypeLookup = new Map();
|
|
159
136
|
for (const nt of ast.nodeTypes) {
|
|
160
137
|
nodeTypeLookup.set(nt.name, nt);
|
|
161
138
|
if (nt.functionName !== nt.name)
|
|
162
139
|
nodeTypeLookup.set(nt.functionName, nt);
|
|
163
140
|
}
|
|
164
|
-
// Group instances by job
|
|
165
141
|
const jobMap = new Map();
|
|
166
142
|
const defaultRunner = ast.options?.cicd?.runner;
|
|
167
143
|
for (const inst of ast.instances) {
|
|
@@ -170,12 +146,10 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
170
146
|
jobMap.set(jobName, []);
|
|
171
147
|
jobMap.get(jobName).push(inst);
|
|
172
148
|
}
|
|
173
|
-
// Build node -> job lookup
|
|
174
149
|
const nodeJob = new Map();
|
|
175
150
|
for (const inst of ast.instances) {
|
|
176
151
|
nodeJob.set(inst.id, inst.job || 'default');
|
|
177
152
|
}
|
|
178
|
-
// Build job dependency graph from connections
|
|
179
153
|
const jobDeps = new Map();
|
|
180
154
|
for (const conn of ast.connections) {
|
|
181
155
|
if (conn.from.node.startsWith('secret:'))
|
|
@@ -190,10 +164,8 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
190
164
|
jobDeps.get(toJob).add(fromJob);
|
|
191
165
|
}
|
|
192
166
|
}
|
|
193
|
-
// Convert to CICDJob array
|
|
194
167
|
const jobs = [];
|
|
195
168
|
for (const [jobId, instances] of jobMap) {
|
|
196
|
-
// Determine environment from first instance with one
|
|
197
169
|
const environment = instances.find((i) => i.environment)?.environment;
|
|
198
170
|
const steps = instances.map((inst) => {
|
|
199
171
|
const nt = nodeTypeLookup.get(inst.nodeType);
|
|
@@ -217,12 +189,76 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
217
189
|
secrets: [],
|
|
218
190
|
});
|
|
219
191
|
}
|
|
220
|
-
//
|
|
192
|
+
// Apply @job configs
|
|
193
|
+
const jobConfigs = ast.options?.cicd?.jobs;
|
|
194
|
+
if (jobConfigs) {
|
|
195
|
+
for (const jc of jobConfigs) {
|
|
196
|
+
const job = jobs.find(j => j.id === jc.id);
|
|
197
|
+
if (!job)
|
|
198
|
+
continue;
|
|
199
|
+
if (jc.retry !== undefined)
|
|
200
|
+
job.retry = jc.retry;
|
|
201
|
+
if (jc.allowFailure !== undefined)
|
|
202
|
+
job.allowFailure = jc.allowFailure;
|
|
203
|
+
if (jc.timeout)
|
|
204
|
+
job.timeout = jc.timeout;
|
|
205
|
+
if (jc.variables)
|
|
206
|
+
job.variables = { ...job.variables, ...jc.variables };
|
|
207
|
+
if (jc.tags)
|
|
208
|
+
job.tags = jc.tags;
|
|
209
|
+
if (jc.beforeScript)
|
|
210
|
+
job.beforeScript = jc.beforeScript;
|
|
211
|
+
if (jc.rules)
|
|
212
|
+
job.rules = jc.rules;
|
|
213
|
+
if (jc.coverage)
|
|
214
|
+
job.coverage = jc.coverage;
|
|
215
|
+
if (jc.reports)
|
|
216
|
+
job.reports = jc.reports;
|
|
217
|
+
if (jc.runner)
|
|
218
|
+
job.runner = jc.runner;
|
|
219
|
+
if (jc.extends)
|
|
220
|
+
job.extends = jc.extends;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// Apply @stage assignments
|
|
224
|
+
const stages = ast.options?.cicd?.stages;
|
|
225
|
+
if (stages && stages.length > 0) {
|
|
226
|
+
const depthMap = this.computeJobDepths(jobs);
|
|
227
|
+
for (const jc of jobConfigs || []) {
|
|
228
|
+
const job = jobs.find(j => j.id === jc.id);
|
|
229
|
+
if (job && !job.stage) {
|
|
230
|
+
for (const s of stages) {
|
|
231
|
+
if (jc.id === s.name || jc.id.startsWith(s.name + '-') || jc.id.startsWith(s.name + '_')) {
|
|
232
|
+
job.stage = s.name;
|
|
233
|
+
break;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
for (const job of jobs) {
|
|
239
|
+
if (!job.stage) {
|
|
240
|
+
const depth = depthMap.get(job.id) || 0;
|
|
241
|
+
job.stage = stages[Math.min(depth, stages.length - 1)].name;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Apply workflow-level defaults
|
|
246
|
+
const cicd = ast.options?.cicd;
|
|
247
|
+
if (cicd) {
|
|
248
|
+
for (const job of jobs) {
|
|
249
|
+
if (cicd.variables && !job.variables) {
|
|
250
|
+
job.variables = { ...cicd.variables };
|
|
251
|
+
}
|
|
252
|
+
if (cicd.beforeScript && !job.beforeScript) {
|
|
253
|
+
job.beforeScript = [...cicd.beforeScript];
|
|
254
|
+
}
|
|
255
|
+
if (cicd.tags && !job.tags) {
|
|
256
|
+
job.tags = [...cicd.tags];
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
221
260
|
return this.topoSortJobs(jobs);
|
|
222
261
|
}
|
|
223
|
-
/**
|
|
224
|
-
* Topologically sort jobs so that dependencies come first.
|
|
225
|
-
*/
|
|
226
262
|
topoSortJobs(jobs) {
|
|
227
263
|
const jobMap = new Map(jobs.map((j) => [j.id, j]));
|
|
228
264
|
const visited = new Set();
|
|
@@ -244,24 +280,40 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
244
280
|
}
|
|
245
281
|
return sorted;
|
|
246
282
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
283
|
+
computeJobDepths(jobs) {
|
|
284
|
+
const depths = new Map();
|
|
285
|
+
function depth(jobId, visited) {
|
|
286
|
+
if (depths.has(jobId))
|
|
287
|
+
return depths.get(jobId);
|
|
288
|
+
if (visited.has(jobId))
|
|
289
|
+
return 0;
|
|
290
|
+
visited.add(jobId);
|
|
291
|
+
const job = jobs.find(j => j.id === jobId);
|
|
292
|
+
if (!job || job.needs.length === 0) {
|
|
293
|
+
depths.set(jobId, 0);
|
|
294
|
+
return 0;
|
|
295
|
+
}
|
|
296
|
+
const maxDep = Math.max(...job.needs.map(n => depth(n, visited)));
|
|
297
|
+
const d = maxDep + 1;
|
|
298
|
+
depths.set(jobId, d);
|
|
299
|
+
return d;
|
|
300
|
+
}
|
|
301
|
+
for (const job of jobs) {
|
|
302
|
+
depth(job.id, new Set());
|
|
303
|
+
}
|
|
304
|
+
return depths;
|
|
305
|
+
}
|
|
251
306
|
resolveJobSecrets(jobs, ast, renderSecretRef) {
|
|
252
|
-
// Build node -> job lookup
|
|
253
307
|
const nodeJob = new Map();
|
|
254
308
|
for (const inst of ast.instances) {
|
|
255
309
|
nodeJob.set(inst.id, inst.job || 'default');
|
|
256
310
|
}
|
|
257
|
-
// Build step lookup
|
|
258
311
|
const stepMap = new Map();
|
|
259
312
|
for (const job of jobs) {
|
|
260
313
|
for (const step of job.steps) {
|
|
261
314
|
stepMap.set(step.id, step);
|
|
262
315
|
}
|
|
263
316
|
}
|
|
264
|
-
// Process secret connections
|
|
265
317
|
for (const conn of ast.connections) {
|
|
266
318
|
if (!conn.from.node.startsWith('secret:'))
|
|
267
319
|
continue;
|
|
@@ -274,34 +326,25 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
274
326
|
const job = jobs.find((j) => j.id === jobId);
|
|
275
327
|
if (!job)
|
|
276
328
|
continue;
|
|
277
|
-
// Add secret to job
|
|
278
329
|
if (!job.secrets.includes(secretName)) {
|
|
279
330
|
job.secrets.push(secretName);
|
|
280
331
|
}
|
|
281
|
-
// Add env var to the step
|
|
282
332
|
const step = stepMap.get(targetNode);
|
|
283
333
|
if (step) {
|
|
284
334
|
step.env = step.env || {};
|
|
285
|
-
// Convert port name to env var (e.g., npmToken -> NPM_TOKEN or use secret name directly)
|
|
286
335
|
step.env[targetPort.replace(/([A-Z])/g, '_$1').toUpperCase().replace(/^_/, '')] =
|
|
287
336
|
renderSecretRef(secretName);
|
|
288
337
|
}
|
|
289
338
|
}
|
|
290
339
|
}
|
|
291
|
-
/**
|
|
292
|
-
* Add artifact upload/download steps between jobs.
|
|
293
|
-
*/
|
|
294
340
|
injectArtifactSteps(jobs, artifacts) {
|
|
295
341
|
if (artifacts.length === 0)
|
|
296
342
|
return;
|
|
297
|
-
// For each job that has dependencies, check if any dependency produces artifacts
|
|
298
343
|
for (const job of jobs) {
|
|
299
344
|
if (job.needs.length === 0)
|
|
300
345
|
continue;
|
|
301
|
-
// Check if any needed job produces artifacts
|
|
302
346
|
const neededJobs = jobs.filter((j) => job.needs.includes(j.id));
|
|
303
347
|
for (const needed of neededJobs) {
|
|
304
|
-
// Find artifacts that match the producing job
|
|
305
348
|
const jobArtifacts = artifacts.filter((a) => !a.name || needed.steps.some((s) => s.nodeType === a.name));
|
|
306
349
|
if (jobArtifacts.length > 0) {
|
|
307
350
|
needed.uploadArtifacts = (needed.uploadArtifacts || []).concat(jobArtifacts);
|
|
@@ -310,9 +353,6 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
310
353
|
}
|
|
311
354
|
}
|
|
312
355
|
}
|
|
313
|
-
/**
|
|
314
|
-
* Generate SECRETS_SETUP.md with per-secret setup instructions.
|
|
315
|
-
*/
|
|
316
356
|
generateSecretsDoc(secrets, platform) {
|
|
317
357
|
if (secrets.length === 0)
|
|
318
358
|
return '';
|
|
@@ -354,4 +394,4 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
354
394
|
return lines.join('\n');
|
|
355
395
|
}
|
|
356
396
|
}
|
|
357
|
-
//# sourceMappingURL=
|
|
397
|
+
//# sourceMappingURL=base-target.js.map
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @secret, @runner, @cache, @artifact, @environment, @matrix, @service,
|
|
7
7
|
* @concurrency, [job: "..."], or CI/CD trigger types (push, pull_request, etc.)
|
|
8
8
|
*/
|
|
9
|
-
import type { TWorkflowAST } from '
|
|
9
|
+
import type { TWorkflowAST } from '../../ast/types.js';
|
|
10
10
|
/**
|
|
11
11
|
* Check if a workflow is a CI/CD pipeline.
|
|
12
12
|
*
|
|
@@ -30,4 +30,4 @@ export declare function getDeclaredSecrets(ast: TWorkflowAST): string[];
|
|
|
30
30
|
* Returns array of secret names that are wired via @connect.
|
|
31
31
|
*/
|
|
32
32
|
export declare function getReferencedSecrets(ast: TWorkflowAST): string[];
|
|
33
|
-
//# sourceMappingURL=
|
|
33
|
+
//# sourceMappingURL=detection.d.ts.map
|
|
@@ -36,6 +36,18 @@ export function isCICDWorkflow(ast) {
|
|
|
36
36
|
return true;
|
|
37
37
|
if (cicd.triggers && cicd.triggers.length > 0)
|
|
38
38
|
return true;
|
|
39
|
+
if (cicd.jobs && cicd.jobs.length > 0)
|
|
40
|
+
return true;
|
|
41
|
+
if (cicd.variables && Object.keys(cicd.variables).length > 0)
|
|
42
|
+
return true;
|
|
43
|
+
if (cicd.beforeScript && cicd.beforeScript.length > 0)
|
|
44
|
+
return true;
|
|
45
|
+
if (cicd.tags && cicd.tags.length > 0)
|
|
46
|
+
return true;
|
|
47
|
+
if (cicd.includes && cicd.includes.length > 0)
|
|
48
|
+
return true;
|
|
49
|
+
if (cicd.stages && cicd.stages.length > 0)
|
|
50
|
+
return true;
|
|
39
51
|
}
|
|
40
52
|
// Check node-level CI/CD annotations
|
|
41
53
|
if (ast.instances.some((inst) => inst.job))
|
|
@@ -73,4 +85,4 @@ export function getReferencedSecrets(ast) {
|
|
|
73
85
|
}
|
|
74
86
|
return Array.from(secrets);
|
|
75
87
|
}
|
|
76
|
-
//# sourceMappingURL=
|
|
88
|
+
//# sourceMappingURL=detection.js.map
|