@intentius/chant-lexicon-gitlab 0.124.31 → 0.124.32

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 (133) hide show
  1. package/dist/codegen/docs-cli.js +2 -0
  2. package/dist/codegen/docs.js +157 -0
  3. package/dist/codegen/fetch.js +93 -0
  4. package/dist/codegen/generate-cli.js +30 -0
  5. package/dist/codegen/generate-lexicon.js +36 -0
  6. package/dist/codegen/generate-typescript.js +105 -0
  7. package/dist/codegen/generate.js +125 -0
  8. package/dist/codegen/naming.js +48 -0
  9. package/dist/codegen/package.js +41 -0
  10. package/dist/codegen/parse.js +539 -0
  11. package/dist/codegen/patches.js +84 -0
  12. package/dist/codegen/typecheck.js +4 -0
  13. package/dist/components/ci-jobs.js +16 -0
  14. package/dist/components/generate-op-pipeline.js +288 -0
  15. package/dist/components/generate-op-waves-pipeline.js +125 -0
  16. package/dist/components/generate-pipeline.d.ts.map +1 -1
  17. package/dist/components/generate-pipeline.js +369 -0
  18. package/dist/composites/catalog.js +418 -0
  19. package/dist/composites/docker-build.js +38 -0
  20. package/dist/composites/index.js +5 -0
  21. package/dist/composites/mr-plan-report.js +42 -0
  22. package/dist/composites/node-pipeline.js +67 -0
  23. package/dist/composites/python-pipeline.js +45 -0
  24. package/dist/composites/review-app.js +32 -0
  25. package/dist/coverage.js +35 -0
  26. package/dist/generated/index.js +25 -0
  27. package/dist/generated/runtime.js +4 -0
  28. package/dist/graph-edges.js +202 -0
  29. package/dist/import/generator.js +196 -0
  30. package/dist/import/parser.js +111 -0
  31. package/dist/index.js +26 -0
  32. package/dist/integrity.json +3 -3
  33. package/dist/intrinsics.js +33 -0
  34. package/dist/lint/audit-catalog.js +53 -0
  35. package/dist/lint/audit-lineage.js +64 -0
  36. package/dist/lint/post-synth/index.js +84 -0
  37. package/dist/lint/post-synth/wgl010.js +34 -0
  38. package/dist/lint/post-synth/wgl011.js +48 -0
  39. package/dist/lint/post-synth/wgl012.d.ts.map +1 -1
  40. package/dist/lint/post-synth/wgl012.js +68 -0
  41. package/dist/lint/post-synth/wgl013.js +57 -0
  42. package/dist/lint/post-synth/wgl014.js +43 -0
  43. package/dist/lint/post-synth/wgl015.js +70 -0
  44. package/dist/lint/post-synth/wgl016.js +70 -0
  45. package/dist/lint/post-synth/wgl017.js +38 -0
  46. package/dist/lint/post-synth/wgl018.js +34 -0
  47. package/dist/lint/post-synth/wgl019.js +43 -0
  48. package/dist/lint/post-synth/wgl020.js +47 -0
  49. package/dist/lint/post-synth/wgl021.js +52 -0
  50. package/dist/lint/post-synth/wgl022.js +38 -0
  51. package/dist/lint/post-synth/wgl023.js +44 -0
  52. package/dist/lint/post-synth/wgl024.js +41 -0
  53. package/dist/lint/post-synth/wgl025.js +42 -0
  54. package/dist/lint/post-synth/wgl026.js +58 -0
  55. package/dist/lint/post-synth/wgl027.js +49 -0
  56. package/dist/lint/post-synth/wgl028.js +58 -0
  57. package/dist/lint/post-synth/wgl029.js +55 -0
  58. package/dist/lint/post-synth/wgl030.js +43 -0
  59. package/dist/lint/post-synth/wgl031.js +33 -0
  60. package/dist/lint/post-synth/wgl032.js +64 -0
  61. package/dist/lint/post-synth/wgl033.js +32 -0
  62. package/dist/lint/post-synth/wgl034.js +37 -0
  63. package/dist/lint/post-synth/wgl035.js +40 -0
  64. package/dist/lint/post-synth/wgl036.js +38 -0
  65. package/dist/lint/post-synth/wgl037.js +41 -0
  66. package/dist/lint/post-synth/wgl038.js +43 -0
  67. package/dist/lint/post-synth/wgl039.js +34 -0
  68. package/dist/lint/post-synth/wgl040.js +35 -0
  69. package/dist/lint/post-synth/wgl041.js +53 -0
  70. package/dist/lint/post-synth/wgl042.js +41 -0
  71. package/dist/lint/post-synth/wgl043.js +39 -0
  72. package/dist/lint/post-synth/wgl044.js +35 -0
  73. package/dist/lint/post-synth/wgl045.js +54 -0
  74. package/dist/lint/post-synth/wgl046.js +40 -0
  75. package/dist/lint/post-synth/wgl047.js +34 -0
  76. package/dist/lint/post-synth/wgl048.js +32 -0
  77. package/dist/lint/post-synth/wgl049.js +53 -0
  78. package/dist/lint/post-synth/wgl050.js +42 -0
  79. package/dist/lint/post-synth/yaml-helpers.js +432 -0
  80. package/dist/lint/rules/artifact-no-expiry.js +53 -0
  81. package/dist/lint/rules/data/known-include-sources.js +44 -0
  82. package/dist/lint/rules/data/untrusted-variables.js +30 -0
  83. package/dist/lint/rules/deprecated-only-except.js +46 -0
  84. package/dist/lint/rules/import-source.js +61 -0
  85. package/dist/lint/rules/index.js +7 -0
  86. package/dist/lint/rules/missing-script.js +67 -0
  87. package/dist/lint/rules/missing-stage.js +60 -0
  88. package/dist/lsp/completions.d.ts.map +1 -1
  89. package/dist/lsp/completions.js +18 -0
  90. package/dist/lsp/hover.d.ts.map +1 -1
  91. package/dist/lsp/hover.js +33 -0
  92. package/dist/manifest.json +1 -1
  93. package/dist/mcp/context-tools.js +262 -0
  94. package/dist/migrate/from-github/actions/index.js +17 -0
  95. package/dist/migrate/from-github/actions/registry.js +61 -0
  96. package/dist/migrate/from-github/actions/tier-1.js +298 -0
  97. package/dist/migrate/from-github/actions/tier-2.js +241 -0
  98. package/dist/migrate/from-github/actions/tier-3.js +96 -0
  99. package/dist/migrate/from-github/composites/patterns.js +151 -0
  100. package/dist/migrate/from-github/composites/rewriter.js +22 -0
  101. package/dist/migrate/from-github/diagnostics.js +53 -0
  102. package/dist/migrate/from-github/emit-yaml.js +121 -0
  103. package/dist/migrate/from-github/expressions.js +275 -0
  104. package/dist/migrate/from-github/index.js +96 -0
  105. package/dist/migrate/from-github/provenance.js +35 -0
  106. package/dist/migrate/from-github/rules.js +74 -0
  107. package/dist/migrate/from-github/security.js +189 -0
  108. package/dist/migrate/from-github/stages.js +156 -0
  109. package/dist/migrate/from-github/transformer.js +633 -0
  110. package/dist/op/activities/gitlab.js +38 -0
  111. package/dist/op/activities/index.js +10 -0
  112. package/dist/op/builders.js +26 -0
  113. package/dist/package-cli.js +21 -0
  114. package/dist/plugin.js +536 -0
  115. package/dist/rules/wgl012.ts +2 -2
  116. package/dist/serializer.js +197 -0
  117. package/dist/testdata/create-fixture.js +40 -0
  118. package/dist/testdata/load-fixtures.js +20 -0
  119. package/dist/validate-cli.js +16 -0
  120. package/dist/validate.js +29 -0
  121. package/dist/variables.js +30 -0
  122. package/package.json +8 -8
  123. package/src/codegen/fetch.ts +2 -2
  124. package/src/codegen/package.ts +2 -2
  125. package/src/components/__fixtures__/pr-loop-build.gitlab.golden.yml +3 -3
  126. package/src/components/__fixtures__/pr-loop-waves.gitlab.golden.yml +101 -0
  127. package/src/components/__fixtures__/pr-loop.gitlab.golden.yml +3 -3
  128. package/src/components/generate-pipeline.ts +60 -27
  129. package/src/components/generate-pr-pipeline.test.ts +14 -9
  130. package/src/components/generate-pr-waves-pipeline.test.ts +88 -0
  131. package/src/lint/post-synth/wgl012.ts +2 -2
  132. package/src/lsp/completions.ts +2 -1
  133. package/src/lsp/hover.ts +2 -1
@@ -0,0 +1,197 @@
1
+ /**
2
+ * GitLab CI YAML serializer.
3
+ *
4
+ * Converts Chant declarables to .gitlab-ci.yml YAML output.
5
+ * Uses snake_case keys (GitLab CI convention) and produces
6
+ * valid YAML without a library dependency — the CI schema is
7
+ * simple enough for a direct emitter.
8
+ */
9
+ import { isPropertyDeclarable, isResourceDeclarable } from "@intentius/chant/declarable";
10
+ import { walkValue } from "@intentius/chant/serializer-walker";
11
+ import { INTRINSIC_MARKER } from "@intentius/chant/intrinsic";
12
+ import { emitYAMLEntry } from "@intentius/chant/yaml";
13
+ /**
14
+ * `#` lines for a comment, one per line of the string (#3669). Only the file
15
+ * header and job comments exist, and both sit at column 0.
16
+ */
17
+ function commentLines(comment) {
18
+ return comment.split("\n").map((l) => `#${l.trimEnd() ? ` ${l.trimEnd()}` : ""}`).join("\n");
19
+ }
20
+ /** An entity's props without `comment`, and the comment if it is a non-empty string. */
21
+ function splitComment(entity) {
22
+ const props = isResourceDeclarable(entity) ? entity.props : undefined;
23
+ if (!props || !("comment" in props))
24
+ return { props };
25
+ const { comment, ...rest } = props;
26
+ return { props: rest, comment: typeof comment === "string" && comment !== "" ? comment : undefined };
27
+ }
28
+ /**
29
+ * GitLab CI visitor for the generic serializer walker.
30
+ */
31
+ function gitlabVisitor(entityNames) {
32
+ return {
33
+ attrRef: (name, _attr) => name,
34
+ resourceRef: (name) => name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(),
35
+ propertyDeclarable: (entity, walk) => {
36
+ if (!isResourceDeclarable(entity) || typeof entity.props !== "object" || entity.props === null) {
37
+ return undefined;
38
+ }
39
+ const props = entity.props;
40
+ const result = {};
41
+ for (const [key, value] of Object.entries(props)) {
42
+ if (value !== undefined) {
43
+ result[key] = walk(value);
44
+ }
45
+ }
46
+ return Object.keys(result).length > 0 ? result : undefined;
47
+ },
48
+ };
49
+ }
50
+ /**
51
+ * Pre-process values to convert intrinsics to their YAML representation
52
+ * before the walker (which would call toJSON instead of toYAML).
53
+ *
54
+ * IMPORTANT: Must not touch Declarable objects — their identity markers
55
+ * (DECLARABLE_MARKER, entityType, kind, props) are non-enumerable and
56
+ * would be stripped by Object.entries(), producing empty `{}` output.
57
+ */
58
+ function preprocessIntrinsics(value) {
59
+ if (value === null || value === undefined)
60
+ return value;
61
+ if (typeof value === "object" && INTRINSIC_MARKER in value) {
62
+ if ("toYAML" in value && typeof value.toYAML === "function") {
63
+ return value.toYAML();
64
+ }
65
+ }
66
+ // Leave Declarables untouched — the walker handles them
67
+ if (typeof value === "object" && value !== null && "entityType" in value) {
68
+ return value;
69
+ }
70
+ if (Array.isArray(value)) {
71
+ return value.map(preprocessIntrinsics);
72
+ }
73
+ if (typeof value === "object") {
74
+ const result = {};
75
+ for (const [k, v] of Object.entries(value)) {
76
+ result[k] = preprocessIntrinsics(v);
77
+ }
78
+ return result;
79
+ }
80
+ return value;
81
+ }
82
+ /**
83
+ * Convert a value to YAML-compatible form using the walker.
84
+ */
85
+ function toYAMLValue(value, entityNames) {
86
+ const preprocessed = preprocessIntrinsics(value);
87
+ return walkValue(preprocessed, entityNames, gitlabVisitor(entityNames));
88
+ }
89
+ /**
90
+ * GitLab CI YAML serializer implementation.
91
+ */
92
+ export const gitlabSerializer = {
93
+ name: "gitlab",
94
+ rulePrefix: "WGL",
95
+ serialize(entities, _outputs) {
96
+ // Build reverse map: entity → name
97
+ const entityNames = new Map();
98
+ for (const [name, entity] of entities) {
99
+ entityNames.set(entity, name);
100
+ }
101
+ const sections = [];
102
+ // Separate entities by type
103
+ const jobs = [];
104
+ const pipelines = [];
105
+ const defaults = [];
106
+ const workflows = [];
107
+ const others = [];
108
+ for (const [name, entity] of entities) {
109
+ if (isPropertyDeclarable(entity))
110
+ continue; // Skip property-only entities
111
+ const entityType = entity.entityType;
112
+ if (entityType === "GitLab::CI::Job") {
113
+ jobs.push([name, entity]);
114
+ }
115
+ else if (entityType === "GitLab::CI::Default") {
116
+ defaults.push([name, entity]);
117
+ }
118
+ else if (entityType === "GitLab::CI::Workflow") {
119
+ workflows.push([name, entity]);
120
+ }
121
+ else if (entityType === "GitLab::CI::Pipeline") {
122
+ pipelines.push([name, entity]);
123
+ }
124
+ else {
125
+ others.push([name, entity]);
126
+ }
127
+ }
128
+ // The Pipeline entity's top-level keys (#3669). More than one is merged
129
+ // in declaration order: comments joined, includes concatenated, stages
130
+ // in first-listed order, later variables overriding earlier ones.
131
+ const headers = [];
132
+ const includes = [];
133
+ const declaredStages = [];
134
+ let variables;
135
+ for (const [, entity] of pipelines) {
136
+ const { props, comment } = splitComment(entity);
137
+ if (comment)
138
+ headers.push(comment);
139
+ const converted = toYAMLValue(props, entityNames);
140
+ if (!converted)
141
+ continue;
142
+ if (converted.include !== undefined) {
143
+ includes.push(...(Array.isArray(converted.include) ? converted.include : [converted.include]));
144
+ }
145
+ if (Array.isArray(converted.stages))
146
+ declaredStages.push(...converted.stages.map(String));
147
+ if (converted.variables && typeof converted.variables === "object") {
148
+ variables = { ...variables, ...converted.variables };
149
+ }
150
+ }
151
+ if (headers.length > 0)
152
+ sections.push(commentLines(headers.join("\n\n")));
153
+ if (includes.length > 0)
154
+ sections.push(emitYAMLEntry("include", includes));
155
+ // Stages: a Pipeline's explicit list first, in its order, then any stage
156
+ // a job names that the list leaves out, in first use. Without a list,
157
+ // that is the jobs' stages alone.
158
+ const stages = new Set(declaredStages);
159
+ for (const [, entity] of jobs) {
160
+ const props = isResourceDeclarable(entity) ? entity.props : undefined;
161
+ if (props?.stage && typeof props.stage === "string") {
162
+ stages.add(props.stage);
163
+ }
164
+ }
165
+ if (stages.size > 0) {
166
+ sections.push(emitYAMLEntry("stages", [...stages]));
167
+ }
168
+ if (variables && Object.keys(variables).length > 0)
169
+ sections.push(emitYAMLEntry("variables", variables));
170
+ // Emit defaults
171
+ for (const [, entity] of defaults) {
172
+ const converted = toYAMLValue((isResourceDeclarable(entity) ? entity.props : undefined), entityNames);
173
+ if (converted) {
174
+ sections.push(emitYAMLEntry("default", converted));
175
+ }
176
+ }
177
+ // Emit workflow
178
+ for (const [, entity] of workflows) {
179
+ const converted = toYAMLValue((isResourceDeclarable(entity) ? entity.props : undefined), entityNames);
180
+ if (converted) {
181
+ sections.push(emitYAMLEntry("workflow", converted));
182
+ }
183
+ }
184
+ // Emit jobs
185
+ for (const [name, entity] of jobs) {
186
+ const { props, comment } = splitComment(entity);
187
+ const converted = toYAMLValue(props, entityNames);
188
+ if (converted) {
189
+ // Convert job name from camelCase to kebab-case for YAML
190
+ const yamlName = name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
191
+ const entry = emitYAMLEntry(yamlName, converted);
192
+ sections.push(comment ? `${commentLines(comment)}\n${entry}` : entry);
193
+ }
194
+ }
195
+ return sections.join("\n\n") + "\n";
196
+ },
197
+ };
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Script to create a minimal CI schema fixture for tests.
4
+ * Run once: npx tsx src/testdata/create-fixture.ts
5
+ */
6
+ import { readFileSync, writeFileSync } from "fs";
7
+ import { homedir } from "os";
8
+ import { join } from "path";
9
+ const schema = JSON.parse(readFileSync(join(homedir(), ".chant", "gitlab-ci-schema.json"), "utf-8"));
10
+ const neededDefs = [
11
+ "job_template", "image", "services", "artifacts", "cache_item",
12
+ "rules", "retry", "allow_failure", "parallel", "include_item",
13
+ "when", "retry_errors", "workflowAutoCancel",
14
+ "before_script", "after_script", "script", "optional_script",
15
+ "globalVariables", "jobVariables", "rulesVariables",
16
+ "id_tokens", "secrets", "timeout", "start_in",
17
+ ];
18
+ const defs = {};
19
+ for (const name of neededDefs) {
20
+ if (schema.definitions?.[name]) {
21
+ defs[name] = schema.definitions[name];
22
+ }
23
+ }
24
+ const keepProps = ["default", "workflow", "stages", "variables", "include"];
25
+ const filteredProps = {};
26
+ for (const key of keepProps) {
27
+ if (schema.properties?.[key])
28
+ filteredProps[key] = schema.properties[key];
29
+ }
30
+ const minimal = {
31
+ definitions: defs,
32
+ properties: filteredProps,
33
+ patternProperties: schema.patternProperties || {},
34
+ required: schema.required || [],
35
+ };
36
+ const outPath = join(import.meta.dirname, "ci-schema-fixture.json");
37
+ writeFileSync(outPath, JSON.stringify(minimal, null, 2));
38
+ console.log(`Fixture written to ${outPath}`);
39
+ console.log(`Definitions: ${Object.keys(defs).length}`);
40
+ console.log(`Missing: ${neededDefs.filter(n => !defs[n]).join(", ") || "none"}`);
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Test fixture loader for the GitLab CI lexicon.
3
+ */
4
+ import { readFileSync } from "fs";
5
+ import { join } from "path";
6
+ /**
7
+ * Load the minimal CI schema fixture for offline testing.
8
+ */
9
+ export function loadSchemaFixture() {
10
+ const fixturePath = join(import.meta.dirname, "ci-schema-fixture.json");
11
+ return Buffer.from(readFileSync(fixturePath));
12
+ }
13
+ /**
14
+ * Load the schema fixture as a Map compatible with generatePipeline.
15
+ */
16
+ export function loadSchemaFixtureMap() {
17
+ const schemas = new Map();
18
+ schemas.set("GitLab::CI::Pipeline", loadSchemaFixture());
19
+ return schemas;
20
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Thin entry point for `npm run validate` in lexicon-gitlab.
4
+ */
5
+ import { validate } from "./validate.js";
6
+ const result = await validate();
7
+ for (const check of result.checks) {
8
+ const status = check.ok ? "OK" : "FAIL";
9
+ const msg = check.error ? ` — ${check.error}` : "";
10
+ console.error(` [${status}] ${check.name}${msg}`);
11
+ }
12
+ if (!result.success) {
13
+ console.error("Validation failed");
14
+ process.exit(1);
15
+ }
16
+ console.error("All validation checks passed.");
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Validate generated lexicon-gitlab artifacts.
3
+ *
4
+ * Thin wrapper around the core validation framework
5
+ * with GitLab-specific configuration.
6
+ */
7
+ import { dirname } from "path";
8
+ import { fileURLToPath } from "url";
9
+ import { validateLexiconArtifacts } from "@intentius/chant/codegen/validate";
10
+ const REQUIRED_NAMES = [
11
+ "Job", "Default", "Workflow",
12
+ "Artifacts", "Cache", "Image", "Service", "Rule", "Retry",
13
+ "AllowFailure", "Parallel", "Include", "Release",
14
+ "Environment", "Trigger", "AutoCancel",
15
+ "WorkflowRule", "Need", "Inherit",
16
+ ];
17
+ /**
18
+ * Validate the generated lexicon-gitlab artifacts.
19
+ *
20
+ * @param opts.basePath - Override the package directory (defaults to lexicon-gitlab package root)
21
+ */
22
+ export async function validate(opts) {
23
+ const basePath = opts?.basePath ?? dirname(dirname(fileURLToPath(import.meta.url)));
24
+ return validateLexiconArtifacts({
25
+ lexiconJsonFilename: "lexicon-gitlab.json",
26
+ requiredNames: REQUIRED_NAMES,
27
+ basePath,
28
+ });
29
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * GitLab CI/CD predefined variable references.
3
+ *
4
+ * These expand to $CI_* variable strings in the serialized YAML.
5
+ * Provided for type-safe access and autocompletion.
6
+ */
7
+ export const CI = {
8
+ CommitBranch: "$CI_COMMIT_BRANCH",
9
+ CommitRef: "$CI_COMMIT_REF_NAME",
10
+ CommitRefSlug: "$CI_COMMIT_REF_SLUG",
11
+ CommitSha: "$CI_COMMIT_SHA",
12
+ CommitTag: "$CI_COMMIT_TAG",
13
+ DefaultBranch: "$CI_DEFAULT_BRANCH",
14
+ Environment: "$CI_ENVIRONMENT_NAME",
15
+ EnvironmentSlug: "$CI_ENVIRONMENT_SLUG",
16
+ JobId: "$CI_JOB_ID",
17
+ JobName: "$CI_JOB_NAME",
18
+ JobStage: "$CI_JOB_STAGE",
19
+ MergeRequestIid: "$CI_MERGE_REQUEST_IID",
20
+ PipelineId: "$CI_PIPELINE_ID",
21
+ PipelineSource: "$CI_PIPELINE_SOURCE",
22
+ ProjectDir: "$CI_PROJECT_DIR",
23
+ ProjectId: "$CI_PROJECT_ID",
24
+ ProjectName: "$CI_PROJECT_NAME",
25
+ ProjectPath: "$CI_PROJECT_PATH",
26
+ Registry: "$CI_REGISTRY",
27
+ RegistryImage: "$CI_REGISTRY_IMAGE",
28
+ RegistryUser: "$CI_REGISTRY_USER",
29
+ RegistryPassword: "$CI_REGISTRY_PASSWORD",
30
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-gitlab",
3
- "version": "0.124.31",
3
+ "version": "0.124.32",
4
4
  "description": "GitLab CI lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -32,22 +32,22 @@
32
32
  ".": {
33
33
  "development": "./src/index.ts",
34
34
  "types": "./dist/index.d.ts",
35
- "default": "./src/index.ts"
35
+ "default": "./dist/index.js"
36
36
  },
37
37
  "./*": {
38
38
  "development": "./src/*.ts",
39
39
  "types": "./dist/*.d.ts",
40
- "default": "./src/*.ts"
40
+ "default": "./dist/*.js"
41
41
  },
42
42
  "./lint/post-synth": {
43
43
  "development": "./src/lint/post-synth/index.ts",
44
44
  "types": "./dist/lint/post-synth/index.d.ts",
45
- "default": "./src/lint/post-synth/index.ts"
45
+ "default": "./dist/lint/post-synth/index.js"
46
46
  },
47
47
  "./op/activities": {
48
48
  "development": "./src/op/activities/index.ts",
49
49
  "types": "./dist/op/activities/index.d.ts",
50
- "default": "./src/op/activities/index.ts"
50
+ "default": "./dist/op/activities/index.js"
51
51
  },
52
52
  "./manifest": "./dist/manifest.json",
53
53
  "./meta": "./dist/meta.json",
@@ -59,7 +59,7 @@
59
59
  "validate": "tsx src/validate-cli.ts",
60
60
  "docs": "tsx src/codegen/docs-cli.ts",
61
61
  "prepack": "npm run generate && npm run bundle && npm run validate && npm run build",
62
- "build": "../../scripts/tsc7.sh -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
62
+ "build": "../../scripts/tsc7.sh -p tsconfig.build.json --sourceMap false && tsc-alias -p tsconfig.build.json"
63
63
  },
64
64
  "devDependencies": {
65
65
  "@intentius/chant": "*",
@@ -67,8 +67,8 @@
67
67
  "typescript": "^5.9.3"
68
68
  },
69
69
  "peerDependencies": {
70
- "@intentius/chant": "^0.124.31",
71
- "@intentius/chant-lexicon-github": "^0.124.31"
70
+ "@intentius/chant": "^0.124.32",
71
+ "@intentius/chant-lexicon-github": "^0.124.32"
72
72
  },
73
73
  "peerDependenciesMeta": {
74
74
  "@intentius/chant-lexicon-github": {
@@ -6,7 +6,7 @@
6
6
  import { join, dirname } from "path";
7
7
  import { homedir } from "os";
8
8
  import { readFileSync, writeFileSync } from "fs";
9
- import { fileURLToPath } from "url";
9
+ import { moduleSourceDir } from "@intentius/chant/module-source";
10
10
  import { fetchWithCache, clearCacheFile } from "@intentius/chant/codegen/fetch";
11
11
 
12
12
  /**
@@ -41,7 +41,7 @@ export function getCachePath(): string {
41
41
  * committed copy is equivalent and network-free.
42
42
  */
43
43
  export function getVendoredSchemaPath(): string {
44
- return join(dirname(fileURLToPath(import.meta.url)), "vendored", "gitlab-ci-schema.json");
44
+ return join(moduleSourceDir(import.meta.url), "vendored", "gitlab-ci-schema.json");
45
45
  }
46
46
 
47
47
  /**
@@ -6,7 +6,7 @@
6
6
  import { readFileSync } from "fs";
7
7
  import { gitlabPlugin } from "../plugin";
8
8
  import { join, dirname } from "path";
9
- import { fileURLToPath } from "url";
9
+ import { moduleSourceDir } from "@intentius/chant/module-source";
10
10
  import type { IntrinsicDef } from "@intentius/chant/lexicon";
11
11
  import {
12
12
  packagePipeline,
@@ -18,7 +18,7 @@ import { generate } from "./generate";
18
18
 
19
19
  export type { PackageOptions, PackageResult };
20
20
 
21
- const pkgDir = dirname(dirname(fileURLToPath(import.meta.url)));
21
+ const pkgDir = dirname(moduleSourceDir(import.meta.url));
22
22
 
23
23
  /**
24
24
  * Package the GitLab lexicon into a distributable BundleSpec.
@@ -24,7 +24,7 @@ plan:
24
24
  - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
25
25
  - chant build --env prod
26
26
  - chant lint
27
- - chant components pr-plan --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --output .chant/pr --forge gitlab
27
+ - chant ci run plan --in-place --no-push --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --forge gitlab
28
28
  artifacts:
29
29
  when: always
30
30
  paths:
@@ -40,10 +40,10 @@ apply:
40
40
  BASE_SHA: '$CI_COMMIT_BEFORE_SHA'
41
41
  script:
42
42
  - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
43
- - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-}"; if [ -z "$BASE_SHA" ]; then git fetch origin $CI_DEFAULT_BRANCH && BASE_SHA="$(git merge-base FETCH_HEAD "$CI_COMMIT_SHA")"; if [ "$BASE_SHA" = "$CI_COMMIT_SHA" ]; then BASE_SHA="$(git rev-parse "$CI_COMMIT_SHA^")"; fi; fi; fi; export BASE_SHA
43
+ - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-}"; if [ -z "$BASE_SHA" ]; then git fetch origin $CI_DEFAULT_BRANCH && BASE_SHA="$(git merge-base FETCH_HEAD "$CI_COMMIT_SHA")"; if [ "$BASE_SHA" = "$CI_COMMIT_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$CI_COMMIT_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; fi; export BASE_SHA
44
44
  - chant build --env prod
45
45
  - chant lint
46
- - chant components pr-apply --base "$BASE_SHA" --env prod --gate pr-apply --output .chant/pr --forge gitlab --require-review --resume .chant/pr-resume/pr-apply.json
46
+ - chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge gitlab
47
47
  cache:
48
48
  key: chant-apply-prod-$CI_COMMIT_SHA
49
49
  paths:
@@ -0,0 +1,101 @@
1
+ workflow:
2
+ name: chant-pr-prod
3
+ rules:
4
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
5
+ - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
6
+
7
+ stages:
8
+ - plan
9
+ - apply-wave-1
10
+ - apply-wave-2
11
+ - apply-wave-3
12
+
13
+ variables:
14
+ CHANT_ENV: prod
15
+ GIT_DEPTH: '0'
16
+
17
+ plan:
18
+ stage: plan
19
+ image: node:22
20
+ rules:
21
+ - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
22
+ variables:
23
+ BASE_SHA: '$CI_MERGE_REQUEST_DIFF_BASE_SHA'
24
+ PR_NUMBER: '$CI_MERGE_REQUEST_IID'
25
+ script:
26
+ - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
27
+ - chant ci run plan --in-place --no-push --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --forge gitlab --wave-gate release
28
+ artifacts:
29
+ when: always
30
+ paths:
31
+ - .chant/pr
32
+
33
+ apply-wave-1:
34
+ stage: apply-wave-1
35
+ image: node:22
36
+ resource_group: chant-apply-prod
37
+ rules:
38
+ - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
39
+ variables:
40
+ BASE_SHA: '$CI_COMMIT_BEFORE_SHA'
41
+ script:
42
+ - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
43
+ - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-}"; if [ -z "$BASE_SHA" ]; then git fetch origin $CI_DEFAULT_BRANCH && BASE_SHA="$(git merge-base FETCH_HEAD "$CI_COMMIT_SHA")"; if [ "$BASE_SHA" = "$CI_COMMIT_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$CI_COMMIT_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; fi; export BASE_SHA
44
+ - chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge gitlab --wave-gate release --wave 1
45
+ cache:
46
+ key: chant-apply-prod-$CI_COMMIT_SHA
47
+ paths:
48
+ - .chant/pr-resume/pr-apply.json
49
+ when: always
50
+ artifacts:
51
+ when: always
52
+ paths:
53
+ - .chant/pr
54
+
55
+ apply-wave-2:
56
+ stage: apply-wave-2
57
+ image: node:22
58
+ needs:
59
+ - apply-wave-1
60
+ resource_group: chant-apply-prod
61
+ rules:
62
+ - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
63
+ variables:
64
+ BASE_SHA: '$CI_COMMIT_BEFORE_SHA'
65
+ script:
66
+ - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
67
+ - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-}"; if [ -z "$BASE_SHA" ]; then git fetch origin $CI_DEFAULT_BRANCH && BASE_SHA="$(git merge-base FETCH_HEAD "$CI_COMMIT_SHA")"; if [ "$BASE_SHA" = "$CI_COMMIT_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$CI_COMMIT_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; fi; export BASE_SHA
68
+ - chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge gitlab --wave-gate release --wave 2
69
+ cache:
70
+ key: chant-apply-prod-$CI_COMMIT_SHA
71
+ paths:
72
+ - .chant/pr-resume/pr-apply.json
73
+ when: always
74
+ artifacts:
75
+ when: always
76
+ paths:
77
+ - .chant/pr
78
+
79
+ apply-wave-3:
80
+ stage: apply-wave-3
81
+ image: node:22
82
+ needs:
83
+ - apply-wave-2
84
+ resource_group: chant-apply-prod
85
+ rules:
86
+ - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
87
+ variables:
88
+ BASE_SHA: '$CI_COMMIT_BEFORE_SHA'
89
+ script:
90
+ - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
91
+ - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-}"; if [ -z "$BASE_SHA" ]; then git fetch origin $CI_DEFAULT_BRANCH && BASE_SHA="$(git merge-base FETCH_HEAD "$CI_COMMIT_SHA")"; if [ "$BASE_SHA" = "$CI_COMMIT_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$CI_COMMIT_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; fi; export BASE_SHA
92
+ - chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge gitlab --wave-gate release --wave 3
93
+ cache:
94
+ key: chant-apply-prod-$CI_COMMIT_SHA
95
+ paths:
96
+ - .chant/pr-resume/pr-apply.json
97
+ when: always
98
+ artifacts:
99
+ when: always
100
+ paths:
101
+ - .chant/pr
@@ -22,7 +22,7 @@ plan:
22
22
  PR_NUMBER: '$CI_MERGE_REQUEST_IID'
23
23
  script:
24
24
  - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
25
- - chant components pr-plan --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --output .chant/pr --forge gitlab
25
+ - chant ci run plan --in-place --no-push --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --forge gitlab
26
26
  artifacts:
27
27
  when: always
28
28
  paths:
@@ -38,8 +38,8 @@ apply:
38
38
  BASE_SHA: '$CI_COMMIT_BEFORE_SHA'
39
39
  script:
40
40
  - command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
41
- - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-}"; if [ -z "$BASE_SHA" ]; then git fetch origin $CI_DEFAULT_BRANCH && BASE_SHA="$(git merge-base FETCH_HEAD "$CI_COMMIT_SHA")"; if [ "$BASE_SHA" = "$CI_COMMIT_SHA" ]; then BASE_SHA="$(git rev-parse "$CI_COMMIT_SHA^")"; fi; fi; fi; export BASE_SHA
42
- - chant components pr-apply --base "$BASE_SHA" --env prod --gate pr-apply --output .chant/pr --forge gitlab --require-review --resume .chant/pr-resume/pr-apply.json
41
+ - if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA:-}"; if [ -z "$BASE_SHA" ]; then git fetch origin $CI_DEFAULT_BRANCH && BASE_SHA="$(git merge-base FETCH_HEAD "$CI_COMMIT_SHA")"; if [ "$BASE_SHA" = "$CI_COMMIT_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$CI_COMMIT_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; fi; export BASE_SHA
42
+ - chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge gitlab
43
43
  cache:
44
44
  key: chant-apply-prod-$CI_COMMIT_SHA
45
45
  paths: