@synergenius/flow-weaver 0.17.3 → 0.17.5
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/chevrotain-parser/trigger-cancel-parser.js +8 -5
- package/dist/cli/commands/export.js +11 -1
- package/dist/cli/flow-weaver.mjs +67 -19
- package/dist/deployment/targets/base.d.ts +2 -0
- package/dist/export/index.d.ts +2 -0
- package/dist/export/index.js +2 -0
- package/dist/extensions/cicd/base-target.js +5 -5
- package/dist/extensions/cicd/tag-handler.js +16 -0
- package/dist/extensions/cicd/templates/cicd-multi-env.js +8 -0
- package/dist/extensions/cicd/templates/cicd-test-deploy.js +7 -0
- package/dist/generated-version.d.ts +1 -1
- package/dist/generated-version.js +1 -1
- package/dist/jsdoc-parser.js +6 -0
- package/dist/parser.js +6 -2
- package/docs/reference/jsdoc-grammar.md +5 -1
- package/package.json +1 -1
|
@@ -148,14 +148,17 @@ export function parseTriggerLine(input, warnings) {
|
|
|
148
148
|
parserInstance.input = lexResult.tokens;
|
|
149
149
|
const cst = parserInstance.triggerLine();
|
|
150
150
|
if (parserInstance.errors.length > 0) {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
warnings.push(`Failed to parse trigger line: "${truncatedInput}"\n` +
|
|
154
|
-
` Error: ${firstError.message}\n` +
|
|
155
|
-
` Expected format: @trigger event="name" or @trigger cron="expr"`);
|
|
151
|
+
// Don't warn here — return null so domain-specific handlers (e.g. CI/CD)
|
|
152
|
+
// get a chance to parse the trigger. The caller can warn if nothing handles it.
|
|
156
153
|
return null;
|
|
157
154
|
}
|
|
158
155
|
const result = visitorInstance.visit(cst);
|
|
156
|
+
// Empty result means the parser consumed @trigger but found no event=/cron= assignments.
|
|
157
|
+
// Return null so the caller can delegate to domain-specific handlers (e.g. CI/CD triggers
|
|
158
|
+
// like @trigger push, @trigger pull_request, etc.)
|
|
159
|
+
if (!result.event && !result.cron) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
159
162
|
// Validate cron expression
|
|
160
163
|
if (result.cron && !CRON_REGEX.test(result.cron)) {
|
|
161
164
|
warnings.push(`Invalid cron expression: "${result.cron}". Expected 5 fields (minute hour day month weekday).`);
|
|
@@ -103,7 +103,9 @@ export async function exportCommand(input, options) {
|
|
|
103
103
|
logger.section('Handler Preview');
|
|
104
104
|
const handlerFile = result.files.find((f) => f.path.endsWith('handler.ts') ||
|
|
105
105
|
f.path.endsWith(`${result.workflow}.ts`) ||
|
|
106
|
-
f.path.endsWith('index.ts')
|
|
106
|
+
f.path.endsWith('index.ts') ||
|
|
107
|
+
f.path.endsWith('.yml') ||
|
|
108
|
+
f.path.endsWith('.yaml'));
|
|
107
109
|
if (handlerFile) {
|
|
108
110
|
// Show first 40 lines of handler
|
|
109
111
|
const lines = handlerFile.content.split('\n');
|
|
@@ -114,6 +116,14 @@ export async function exportCommand(input, options) {
|
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
}
|
|
119
|
+
// Show warnings about unsupported annotations
|
|
120
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
121
|
+
logger.newline();
|
|
122
|
+
logger.section('Warnings');
|
|
123
|
+
for (const warning of result.warnings) {
|
|
124
|
+
logger.warn(warning);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
117
127
|
// Get deploy instructions from the target
|
|
118
128
|
logger.newline();
|
|
119
129
|
logger.section('Next Steps');
|
package/dist/cli/flow-weaver.mjs
CHANGED
|
@@ -17051,16 +17051,12 @@ function parseTriggerLine(input, warnings) {
|
|
|
17051
17051
|
parserInstance8.input = lexResult.tokens;
|
|
17052
17052
|
const cst = parserInstance8.triggerLine();
|
|
17053
17053
|
if (parserInstance8.errors.length > 0) {
|
|
17054
|
-
const firstError = parserInstance8.errors[0];
|
|
17055
|
-
const truncatedInput = input.length > 60 ? input.substring(0, 60) + "..." : input;
|
|
17056
|
-
warnings.push(
|
|
17057
|
-
`Failed to parse trigger line: "${truncatedInput}"
|
|
17058
|
-
Error: ${firstError.message}
|
|
17059
|
-
Expected format: @trigger event="name" or @trigger cron="expr"`
|
|
17060
|
-
);
|
|
17061
17054
|
return null;
|
|
17062
17055
|
}
|
|
17063
17056
|
const result = visitorInstance8.visit(cst);
|
|
17057
|
+
if (!result.event && !result.cron) {
|
|
17058
|
+
return null;
|
|
17059
|
+
}
|
|
17064
17060
|
if (result.cron && !CRON_REGEX.test(result.cron)) {
|
|
17065
17061
|
warnings.push(`Invalid cron expression: "${result.cron}". Expected 5 fields (minute hour day month weekday).`);
|
|
17066
17062
|
}
|
|
@@ -25611,7 +25607,7 @@ var VERSION2;
|
|
|
25611
25607
|
var init_generated_version = __esm({
|
|
25612
25608
|
"src/generated-version.ts"() {
|
|
25613
25609
|
"use strict";
|
|
25614
|
-
VERSION2 = "0.17.
|
|
25610
|
+
VERSION2 = "0.17.5";
|
|
25615
25611
|
}
|
|
25616
25612
|
});
|
|
25617
25613
|
|
|
@@ -35963,6 +35959,12 @@ var init_jsdoc_parser = __esm({
|
|
|
35963
35959
|
const comment = (tag.getCommentText() || "").trim();
|
|
35964
35960
|
const result = parseTriggerLine(`@trigger ${comment}`, warnings);
|
|
35965
35961
|
if (result) {
|
|
35962
|
+
const cicdKeywords = ["push", "pull_request", "dispatch", "tag", "schedule"];
|
|
35963
|
+
if (result.event && cicdKeywords.includes(result.event)) {
|
|
35964
|
+
warnings.push(
|
|
35965
|
+
`@trigger event="${result.event}" is treated as an Inngest event trigger, not a CI/CD trigger. For CI/CD, use: @trigger ${result.event}`
|
|
35966
|
+
);
|
|
35967
|
+
}
|
|
35966
35968
|
config2.trigger = config2.trigger || {};
|
|
35967
35969
|
if (result.event) config2.trigger.event = result.event;
|
|
35968
35970
|
if (result.cron) config2.trigger.cron = result.cron;
|
|
@@ -36677,7 +36679,8 @@ var init_parser2 = __esm({
|
|
|
36677
36679
|
nodeTypes.push(...inferredNodeTypes);
|
|
36678
36680
|
const workflows = this.extractWorkflows(sourceFile, nodeTypes, filePath, errors2, warnings);
|
|
36679
36681
|
const patterns = this.extractPatterns(sourceFile, nodeTypes, filePath, errors2, warnings);
|
|
36680
|
-
const
|
|
36682
|
+
const dedupedWarnings = [...new Set(warnings)];
|
|
36683
|
+
const result = { workflows, nodeTypes, patterns, errors: errors2, warnings: dedupedWarnings };
|
|
36681
36684
|
this.project.removeSourceFile(sourceFile);
|
|
36682
36685
|
if (!externalNodeTypes?.length) {
|
|
36683
36686
|
this.parseCache.set(filePath, {
|
|
@@ -36717,12 +36720,13 @@ var init_parser2 = __esm({
|
|
|
36717
36720
|
const workflows = this.extractWorkflows(sourceFile, nodeTypes, virtualPath, errors2, warnings);
|
|
36718
36721
|
const patterns = this.extractPatterns(sourceFile, nodeTypes, virtualPath, errors2, warnings);
|
|
36719
36722
|
this.project.removeSourceFile(sourceFile);
|
|
36723
|
+
const dedupedWarnings = [...new Set(warnings)];
|
|
36720
36724
|
return {
|
|
36721
36725
|
workflows,
|
|
36722
36726
|
nodeTypes,
|
|
36723
36727
|
patterns,
|
|
36724
36728
|
errors: errors2,
|
|
36725
|
-
warnings
|
|
36729
|
+
warnings: dedupedWarnings
|
|
36726
36730
|
};
|
|
36727
36731
|
}
|
|
36728
36732
|
clearCache() {
|
|
@@ -71463,7 +71467,7 @@ var init_base_target = __esm({
|
|
|
71463
71467
|
},
|
|
71464
71468
|
"slack-notify": {
|
|
71465
71469
|
githubAction: "slackapi/slack-github-action@v1",
|
|
71466
|
-
gitlabScript: [
|
|
71470
|
+
gitlabScript: [`curl -X POST -H 'Content-type: application/json' --data '{"text":"Pipeline complete"}' $SLACK_WEBHOOK_URL`],
|
|
71467
71471
|
label: "Send Slack notification"
|
|
71468
71472
|
},
|
|
71469
71473
|
"health-check": {
|
|
@@ -71575,11 +71579,10 @@ var init_base_target = __esm({
|
|
|
71575
71579
|
const stages = ast.options?.cicd?.stages;
|
|
71576
71580
|
if (stages && stages.length > 0) {
|
|
71577
71581
|
const depthMap = this.computeJobDepths(jobs);
|
|
71578
|
-
for (const
|
|
71579
|
-
|
|
71580
|
-
if (job && !job.stage) {
|
|
71582
|
+
for (const job of jobs) {
|
|
71583
|
+
if (!job.stage) {
|
|
71581
71584
|
for (const s of stages) {
|
|
71582
|
-
if (
|
|
71585
|
+
if (job.id === s.name || job.id.startsWith(s.name + "-") || job.id.startsWith(s.name + "_")) {
|
|
71583
71586
|
job.stage = s.name;
|
|
71584
71587
|
break;
|
|
71585
71588
|
}
|
|
@@ -73354,6 +73357,18 @@ function parseJob(text, d, warnings) {
|
|
|
73354
73357
|
jc.rules = jc.rules || [];
|
|
73355
73358
|
jc.rules.push({ if: value2 });
|
|
73356
73359
|
break;
|
|
73360
|
+
case "when": {
|
|
73361
|
+
jc.rules = jc.rules || [];
|
|
73362
|
+
if (jc.rules.length === 0) jc.rules.push({});
|
|
73363
|
+
jc.rules[jc.rules.length - 1].when = value2;
|
|
73364
|
+
break;
|
|
73365
|
+
}
|
|
73366
|
+
case "changes": {
|
|
73367
|
+
jc.rules = jc.rules || [];
|
|
73368
|
+
if (jc.rules.length === 0) jc.rules.push({});
|
|
73369
|
+
jc.rules[jc.rules.length - 1].changes = value2.split(",").map((s) => s.trim()).filter(Boolean);
|
|
73370
|
+
break;
|
|
73371
|
+
}
|
|
73357
73372
|
case "reports": {
|
|
73358
73373
|
jc.reports = jc.reports || [];
|
|
73359
73374
|
for (const pair of value2.split(",")) {
|
|
@@ -73794,6 +73809,18 @@ function deploySsh(sshKey: string = ''): { result: string } { return { result: '
|
|
|
73794
73809
|
*/
|
|
73795
73810
|
function deployS3(accessKey: string = '', secretKey: string = ''): { result: string } { return { result: 'deployed' }; }
|
|
73796
73811
|
` : "";
|
|
73812
|
+
const stageAnnotations = hasDeploy ? ` * @stage test
|
|
73813
|
+
* @stage build
|
|
73814
|
+
* @stage deploy
|
|
73815
|
+
` : ` * @stage test
|
|
73816
|
+
* @stage build
|
|
73817
|
+
`;
|
|
73818
|
+
const jobAnnotations = hasDeploy ? ` * @job test retry=1
|
|
73819
|
+
* @job build timeout="10m"
|
|
73820
|
+
* @job deploy allow_failure=false
|
|
73821
|
+
` : ` * @job test retry=1
|
|
73822
|
+
* @job build timeout="10m"
|
|
73823
|
+
`;
|
|
73797
73824
|
return `/** @flowWeaver nodeType
|
|
73798
73825
|
* @expression
|
|
73799
73826
|
* @label Checkout code
|
|
@@ -73832,6 +73859,7 @@ ${deployStub}
|
|
|
73832
73859
|
* @secret NPM_TOKEN - npm auth token${deploySecret}
|
|
73833
73860
|
* @cache npm key="package-lock.json"
|
|
73834
73861
|
*
|
|
73862
|
+
${stageAnnotations}${jobAnnotations} *
|
|
73835
73863
|
* @node co checkout [job: "test"] [position: 270 0]
|
|
73836
73864
|
* @node setup setupNode [job: "test"] [position: 540 0]
|
|
73837
73865
|
* @node install npmInstall [job: "test"] [position: 810 0]
|
|
@@ -73996,6 +74024,15 @@ var cicdMultiEnvTemplate = {
|
|
|
73996
74024
|
const name = opts.workflowName || "multiEnvPipeline";
|
|
73997
74025
|
const envs = (opts.config?.environments || "staging,production").split(",").map((e) => e.trim());
|
|
73998
74026
|
const envAnnotations = envs.map((env) => ` * @environment ${env} url="https://${env}.example.com"`).join("\n");
|
|
74027
|
+
const stageAnnotations = ` * @stage test
|
|
74028
|
+
* @stage build
|
|
74029
|
+
* @stage deploy
|
|
74030
|
+
`;
|
|
74031
|
+
const jobAnnotations = [
|
|
74032
|
+
` * @job test retry=1`,
|
|
74033
|
+
` * @job build timeout="10m"`,
|
|
74034
|
+
...envs.map((env) => ` * @job deploy-${env} allow_failure=${env === "staging" ? "true" : "false"}`)
|
|
74035
|
+
].join("\n");
|
|
73999
74036
|
let x = 270;
|
|
74000
74037
|
const nodeAnnotations = [];
|
|
74001
74038
|
const pathParts = ["Start"];
|
|
@@ -74048,6 +74085,8 @@ ${envAnnotations}
|
|
|
74048
74085
|
* @cache npm key="package-lock.json"
|
|
74049
74086
|
* @artifact dist path="dist/" retention=3
|
|
74050
74087
|
*
|
|
74088
|
+
${stageAnnotations}${jobAnnotations}
|
|
74089
|
+
*
|
|
74051
74090
|
${nodeAnnotations.join("\n")}
|
|
74052
74091
|
*
|
|
74053
74092
|
* @path ${pathParts.join(" -> ")}
|
|
@@ -107919,7 +107958,8 @@ async function exportSingleWorkflowViaRegistry(target, inputPath, outputDir, isD
|
|
|
107919
107958
|
target: options.target,
|
|
107920
107959
|
files,
|
|
107921
107960
|
workflow: workflow.name,
|
|
107922
|
-
description: workflow.description
|
|
107961
|
+
description: workflow.description,
|
|
107962
|
+
warnings: artifacts.warnings
|
|
107923
107963
|
};
|
|
107924
107964
|
}
|
|
107925
107965
|
async function exportMultiWorkflowViaRegistry(target, inputPath, outputDir, isDryRun, options) {
|
|
@@ -107981,7 +108021,8 @@ async function exportMultiWorkflowViaRegistry(target, inputPath, outputDir, isDr
|
|
|
107981
108021
|
target: options.target,
|
|
107982
108022
|
files,
|
|
107983
108023
|
workflow: serviceName,
|
|
107984
|
-
workflows: selectedWorkflows.map((w) => w.name)
|
|
108024
|
+
workflows: selectedWorkflows.map((w) => w.name),
|
|
108025
|
+
warnings: artifacts.warnings
|
|
107985
108026
|
};
|
|
107986
108027
|
}
|
|
107987
108028
|
async function compileToOutput(inputPath, functionName, outputDir, production) {
|
|
@@ -108070,7 +108111,7 @@ async function exportCommand(input, options) {
|
|
|
108070
108111
|
logger.newline();
|
|
108071
108112
|
logger.section("Handler Preview");
|
|
108072
108113
|
const handlerFile = result.files.find(
|
|
108073
|
-
(f) => f.path.endsWith("handler.ts") || f.path.endsWith(`${result.workflow}.ts`) || f.path.endsWith("index.ts")
|
|
108114
|
+
(f) => f.path.endsWith("handler.ts") || f.path.endsWith(`${result.workflow}.ts`) || f.path.endsWith("index.ts") || f.path.endsWith(".yml") || f.path.endsWith(".yaml")
|
|
108074
108115
|
);
|
|
108075
108116
|
if (handlerFile) {
|
|
108076
108117
|
const lines = handlerFile.content.split("\n");
|
|
@@ -108081,6 +108122,13 @@ async function exportCommand(input, options) {
|
|
|
108081
108122
|
}
|
|
108082
108123
|
}
|
|
108083
108124
|
}
|
|
108125
|
+
if (result.warnings && result.warnings.length > 0) {
|
|
108126
|
+
logger.newline();
|
|
108127
|
+
logger.section("Warnings");
|
|
108128
|
+
for (const warning of result.warnings) {
|
|
108129
|
+
logger.warn(warning);
|
|
108130
|
+
}
|
|
108131
|
+
}
|
|
108084
108132
|
logger.newline();
|
|
108085
108133
|
logger.section("Next Steps");
|
|
108086
108134
|
const { createTargetRegistry: createTargetRegistry2 } = await Promise.resolve().then(() => (init_deployment(), deployment_exports));
|
|
@@ -109257,7 +109305,7 @@ function displayInstalledPackage(pkg) {
|
|
|
109257
109305
|
|
|
109258
109306
|
// src/cli/index.ts
|
|
109259
109307
|
init_error_utils();
|
|
109260
|
-
var version2 = true ? "0.17.
|
|
109308
|
+
var version2 = true ? "0.17.5" : "0.0.0-dev";
|
|
109261
109309
|
var program2 = new Command();
|
|
109262
109310
|
program2.name("flow-weaver").description("Flow Weaver Annotations - Compile and validate workflow files").option("-v, --version", "Output the current version").option("--no-color", "Disable colors").option("--color", "Force colors").on("option:version", () => {
|
|
109263
109311
|
logger.banner(version2);
|
package/dist/export/index.d.ts
CHANGED
package/dist/export/index.js
CHANGED
|
@@ -112,6 +112,7 @@ async function exportSingleWorkflowViaRegistry(target, inputPath, outputDir, isD
|
|
|
112
112
|
files,
|
|
113
113
|
workflow: workflow.name,
|
|
114
114
|
description: workflow.description,
|
|
115
|
+
warnings: artifacts.warnings,
|
|
115
116
|
};
|
|
116
117
|
}
|
|
117
118
|
/**
|
|
@@ -177,6 +178,7 @@ async function exportMultiWorkflowViaRegistry(target, inputPath, outputDir, isDr
|
|
|
177
178
|
files,
|
|
178
179
|
workflow: serviceName,
|
|
179
180
|
workflows: selectedWorkflows.map((w) => w.name),
|
|
181
|
+
warnings: artifacts.warnings,
|
|
180
182
|
};
|
|
181
183
|
}
|
|
182
184
|
/**
|
|
@@ -79,7 +79,7 @@ export const NODE_ACTION_MAP = {
|
|
|
79
79
|
},
|
|
80
80
|
'slack-notify': {
|
|
81
81
|
githubAction: 'slackapi/slack-github-action@v1',
|
|
82
|
-
gitlabScript: [
|
|
82
|
+
gitlabScript: ["curl -X POST -H 'Content-type: application/json' --data '{\"text\":\"Pipeline complete\"}' $SLACK_WEBHOOK_URL"],
|
|
83
83
|
label: 'Send Slack notification',
|
|
84
84
|
},
|
|
85
85
|
'health-check': {
|
|
@@ -224,11 +224,11 @@ export class BaseCICDTarget extends BaseExportTarget {
|
|
|
224
224
|
const stages = ast.options?.cicd?.stages;
|
|
225
225
|
if (stages && stages.length > 0) {
|
|
226
226
|
const depthMap = this.computeJobDepths(jobs);
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (
|
|
227
|
+
// Match ALL jobs by name prefix to stages, not just configured ones
|
|
228
|
+
for (const job of jobs) {
|
|
229
|
+
if (!job.stage) {
|
|
230
230
|
for (const s of stages) {
|
|
231
|
-
if (
|
|
231
|
+
if (job.id === s.name || job.id.startsWith(s.name + '-') || job.id.startsWith(s.name + '_')) {
|
|
232
232
|
job.stage = s.name;
|
|
233
233
|
break;
|
|
234
234
|
}
|
|
@@ -326,6 +326,22 @@ function parseJob(text, d, warnings) {
|
|
|
326
326
|
jc.rules = jc.rules || [];
|
|
327
327
|
jc.rules.push({ if: value });
|
|
328
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
|
+
}
|
|
329
345
|
case 'reports': {
|
|
330
346
|
jc.reports = jc.reports || [];
|
|
331
347
|
for (const pair of value.split(',')) {
|
|
@@ -35,6 +35,12 @@ export const cicdMultiEnvTemplate = {
|
|
|
35
35
|
const envAnnotations = envs
|
|
36
36
|
.map((env) => ` * @environment ${env} url="https://${env}.example.com"`)
|
|
37
37
|
.join('\n');
|
|
38
|
+
const stageAnnotations = ` * @stage test\n * @stage build\n * @stage deploy\n`;
|
|
39
|
+
const jobAnnotations = [
|
|
40
|
+
` * @job test retry=1`,
|
|
41
|
+
` * @job build timeout="10m"`,
|
|
42
|
+
...envs.map((env) => ` * @job deploy-${env} allow_failure=${env === 'staging' ? 'true' : 'false'}`),
|
|
43
|
+
].join('\n');
|
|
38
44
|
let x = 270;
|
|
39
45
|
const nodeAnnotations = [];
|
|
40
46
|
const pathParts = ['Start'];
|
|
@@ -89,6 +95,8 @@ ${envAnnotations}
|
|
|
89
95
|
* @cache npm key="package-lock.json"
|
|
90
96
|
* @artifact dist path="dist/" retention=3
|
|
91
97
|
*
|
|
98
|
+
${stageAnnotations}${jobAnnotations}
|
|
99
|
+
*
|
|
92
100
|
${nodeAnnotations.join('\n')}
|
|
93
101
|
*
|
|
94
102
|
* @path ${pathParts.join(' -> ')}
|
|
@@ -78,6 +78,12 @@ function deploySsh(sshKey: string = ''): { result: string } { return { result: '
|
|
|
78
78
|
function deployS3(accessKey: string = '', secretKey: string = ''): { result: string } { return { result: 'deployed' }; }
|
|
79
79
|
`
|
|
80
80
|
: '';
|
|
81
|
+
const stageAnnotations = hasDeploy
|
|
82
|
+
? ` * @stage test\n * @stage build\n * @stage deploy\n`
|
|
83
|
+
: ` * @stage test\n * @stage build\n`;
|
|
84
|
+
const jobAnnotations = hasDeploy
|
|
85
|
+
? ` * @job test retry=1\n * @job build timeout="10m"\n * @job deploy allow_failure=false\n`
|
|
86
|
+
: ` * @job test retry=1\n * @job build timeout="10m"\n`;
|
|
81
87
|
return `/** @flowWeaver nodeType
|
|
82
88
|
* @expression
|
|
83
89
|
* @label Checkout code
|
|
@@ -116,6 +122,7 @@ ${deployStub}
|
|
|
116
122
|
* @secret NPM_TOKEN - npm auth token${deploySecret}
|
|
117
123
|
* @cache npm key="package-lock.json"
|
|
118
124
|
*
|
|
125
|
+
${stageAnnotations}${jobAnnotations} *
|
|
119
126
|
* @node co checkout [job: "test"] [position: 270 0]
|
|
120
127
|
* @node setup setupNode [job: "test"] [position: 540 0]
|
|
121
128
|
* @node install npmInstall [job: "test"] [position: 810 0]
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "0.17.
|
|
1
|
+
export declare const VERSION = "0.17.5";
|
|
2
2
|
//# sourceMappingURL=generated-version.d.ts.map
|
package/dist/jsdoc-parser.js
CHANGED
|
@@ -1055,6 +1055,12 @@ export class JSDocParser {
|
|
|
1055
1055
|
// Try core FW trigger parsing first (event= and/or cron=)
|
|
1056
1056
|
const result = parseTriggerLine(`@trigger ${comment}`, warnings);
|
|
1057
1057
|
if (result) {
|
|
1058
|
+
// Warn if the event name matches a CI/CD trigger keyword (likely user error)
|
|
1059
|
+
const cicdKeywords = ['push', 'pull_request', 'dispatch', 'tag', 'schedule'];
|
|
1060
|
+
if (result.event && cicdKeywords.includes(result.event)) {
|
|
1061
|
+
warnings.push(`@trigger event="${result.event}" is treated as an Inngest event trigger, not a CI/CD trigger. ` +
|
|
1062
|
+
`For CI/CD, use: @trigger ${result.event}`);
|
|
1063
|
+
}
|
|
1058
1064
|
// Merge: multiple @trigger tags accumulate (event + cron can be separate tags)
|
|
1059
1065
|
config.trigger = config.trigger || {};
|
|
1060
1066
|
if (result.event)
|
package/dist/parser.js
CHANGED
|
@@ -187,7 +187,9 @@ export class AnnotationParser {
|
|
|
187
187
|
nodeTypes.push(...inferredNodeTypes);
|
|
188
188
|
const workflows = this.extractWorkflows(sourceFile, nodeTypes, filePath, errors, warnings);
|
|
189
189
|
const patterns = this.extractPatterns(sourceFile, nodeTypes, filePath, errors, warnings);
|
|
190
|
-
|
|
190
|
+
// Deduplicate warnings (extractWorkflowSignatures + extractWorkflows both parse JSDoc)
|
|
191
|
+
const dedupedWarnings = [...new Set(warnings)];
|
|
192
|
+
const result = { workflows, nodeTypes, patterns, errors, warnings: dedupedWarnings };
|
|
191
193
|
// Clean up source file to prevent ts-morph Project bloat
|
|
192
194
|
// (results are captured in the returned AST, source file is no longer needed)
|
|
193
195
|
this.project.removeSourceFile(sourceFile);
|
|
@@ -238,12 +240,14 @@ export class AnnotationParser {
|
|
|
238
240
|
// Clean up virtual source file to prevent memory bloat
|
|
239
241
|
// (tests create many unique virtual paths that accumulate)
|
|
240
242
|
this.project.removeSourceFile(sourceFile);
|
|
243
|
+
// Deduplicate warnings (extractWorkflowSignatures + extractWorkflows both parse JSDoc)
|
|
244
|
+
const dedupedWarnings = [...new Set(warnings)];
|
|
241
245
|
return {
|
|
242
246
|
workflows,
|
|
243
247
|
nodeTypes,
|
|
244
248
|
patterns,
|
|
245
249
|
errors,
|
|
246
|
-
warnings,
|
|
250
|
+
warnings: dedupedWarnings,
|
|
247
251
|
};
|
|
248
252
|
}
|
|
249
253
|
clearCache() {
|
|
@@ -572,7 +572,9 @@ Configures per-job settings. The name must match a `[job: "name"]` attribute use
|
|
|
572
572
|
jobTag ::= "@job" IDENTIFIER { IDENTIFIER "=" ( STRING | IDENTIFIER | INTEGER ) }
|
|
573
573
|
```
|
|
574
574
|
|
|
575
|
-
Recognized keys: `retry` (number), `allow_failure` (boolean), `timeout` (string), `runner` (string), `tags` (comma-list), `coverage` (string), `reports` (comma-list of type=path), `rules` (string), `extends` (string), `before_script` (comma-list), `variables` (comma-list of KEY=VALUE).
|
|
575
|
+
Recognized keys: `retry` (number), `allow_failure` (boolean), `timeout` (string), `runner` (string), `tags` (comma-list), `coverage` (string), `reports` (comma-list of type=path), `rules` (string), `when` (rule modifier), `changes` (rule modifier, comma-list), `extends` (string), `before_script` (comma-list), `variables` (comma-list of KEY=VALUE).
|
|
576
|
+
|
|
577
|
+
The `when` and `changes` keys are rule modifiers: they apply to the most recently declared `rules` entry for that job. If no `rules` entry exists yet, one is created automatically.
|
|
576
578
|
|
|
577
579
|
**Examples:**
|
|
578
580
|
|
|
@@ -580,6 +582,8 @@ Recognized keys: `retry` (number), `allow_failure` (boolean), `timeout` (string)
|
|
|
580
582
|
@job build retry=2 timeout="10m"
|
|
581
583
|
@job test-unit coverage='/Coverage: (\d+)%/' reports="junit=test-results.xml"
|
|
582
584
|
@job deploy allow_failure=true rules="$CI_COMMIT_BRANCH == main"
|
|
585
|
+
@job deploy rules="$CI_COMMIT_BRANCH == main" when=manual
|
|
586
|
+
@job deploy rules="$CI_COMMIT_TAG" changes="src/**,lib/**"
|
|
583
587
|
@job lint tags="docker,linux" extends=".base-lint"
|
|
584
588
|
```
|
|
585
589
|
|
package/package.json
CHANGED