@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,418 @@
1
+ export const compositeCatalog = [
2
+ {
3
+ "name": "BunPipeline",
4
+ "lexicon": "gitlab",
5
+ "description": "NodePipeline preset for Bun projects.",
6
+ "bundles": [
7
+ "Default",
8
+ "Job"
9
+ ],
10
+ "params": [
11
+ {
12
+ "name": "defaults",
13
+ "type": "{ defaults?: Partial<ConstructorParameters<typeof Default>[0]>; build?: Partial<ConstructorParameters<typeof Job>[0]>...",
14
+ "required": false,
15
+ "description": "Per-member defaults for customizing the generated resources."
16
+ },
17
+ {
18
+ "name": "nodeVersion",
19
+ "type": "string",
20
+ "required": false,
21
+ "description": "Node.js version."
22
+ },
23
+ {
24
+ "name": "installCommand",
25
+ "type": "string",
26
+ "required": false,
27
+ "description": "Override auto-detected install command"
28
+ },
29
+ {
30
+ "name": "buildScript",
31
+ "type": "string",
32
+ "required": false,
33
+ "description": "Build script name (runs via package manager)."
34
+ },
35
+ {
36
+ "name": "buildArtifactPaths",
37
+ "type": "string[]",
38
+ "required": false,
39
+ "description": "Artifact paths from build."
40
+ },
41
+ {
42
+ "name": "artifactExpiry",
43
+ "type": "string",
44
+ "required": false,
45
+ "description": "Artifact expiry."
46
+ },
47
+ {
48
+ "name": "testScript",
49
+ "type": "string",
50
+ "required": false,
51
+ "description": "Test script name."
52
+ },
53
+ {
54
+ "name": "packageManager",
55
+ "type": "\"npm\" | \"pnpm\" | \"bun\"",
56
+ "required": false,
57
+ "description": "Package manager."
58
+ }
59
+ ]
60
+ },
61
+ {
62
+ "name": "DockerBuild",
63
+ "lexicon": "gitlab",
64
+ "description": "Bundles Job.",
65
+ "bundles": [
66
+ "Job"
67
+ ],
68
+ "params": [
69
+ {
70
+ "name": "stage",
71
+ "type": "string",
72
+ "required": false,
73
+ "description": "Job stage."
74
+ },
75
+ {
76
+ "name": "tag",
77
+ "type": "string",
78
+ "required": false,
79
+ "description": "Image tag."
80
+ },
81
+ {
82
+ "name": "dockerfile",
83
+ "type": "string",
84
+ "required": false,
85
+ "description": "Dockerfile path."
86
+ },
87
+ {
88
+ "name": "context",
89
+ "type": "string",
90
+ "required": false,
91
+ "description": "Build context."
92
+ },
93
+ {
94
+ "name": "registry",
95
+ "type": "string",
96
+ "required": false,
97
+ "description": "Container registry."
98
+ },
99
+ {
100
+ "name": "image",
101
+ "type": "string",
102
+ "required": false,
103
+ "description": "Full image name."
104
+ },
105
+ {
106
+ "name": "tagLatest",
107
+ "type": "boolean",
108
+ "required": false,
109
+ "description": "Tag as :latest on default branch."
110
+ },
111
+ {
112
+ "name": "buildArgs",
113
+ "type": "Record<string, string>",
114
+ "required": false,
115
+ "description": "Extra docker build --build-arg flags"
116
+ },
117
+ {
118
+ "name": "rules",
119
+ "type": "InstanceType<typeof Rule>[]",
120
+ "required": false,
121
+ "description": "Job rules."
122
+ },
123
+ {
124
+ "name": "dockerVersion",
125
+ "type": "string",
126
+ "required": false,
127
+ "description": "Docker version."
128
+ },
129
+ {
130
+ "name": "defaults",
131
+ "type": "{ build?: Partial<ConstructorParameters<typeof Job>[0]>; }",
132
+ "required": false,
133
+ "description": "Per-member defaults for customizing the build job."
134
+ }
135
+ ]
136
+ },
137
+ {
138
+ "name": "MrPlanReport",
139
+ "lexicon": "gitlab",
140
+ "description": "A CI job that publishes `chant lifecycle plan` as the GitLab merge-request plan widget.",
141
+ "bundles": [
142
+ "Job"
143
+ ],
144
+ "params": [
145
+ {
146
+ "name": "environment",
147
+ "type": "string",
148
+ "required": true,
149
+ "description": "Lifecycle environment to plan against — the `<environment>` argument of `chant lifecycle plan`."
150
+ },
151
+ {
152
+ "name": "lexicon",
153
+ "type": "string",
154
+ "required": false,
155
+ "description": "Restrict the plan to one lexicon (the optional `[lexicon]` argument)."
156
+ },
157
+ {
158
+ "name": "stage",
159
+ "type": "string",
160
+ "required": false,
161
+ "description": "Stage for the plan job."
162
+ },
163
+ {
164
+ "name": "image",
165
+ "type": "string",
166
+ "required": false,
167
+ "description": "Image to run chant in."
168
+ },
169
+ {
170
+ "name": "ownedOnly",
171
+ "type": "boolean",
172
+ "required": false,
173
+ "description": "Plan against chant-owned resources only (passes `--owned`)."
174
+ },
175
+ {
176
+ "name": "reportFile",
177
+ "type": "string",
178
+ "required": false,
179
+ "description": "Artifact filename the report is written to."
180
+ },
181
+ {
182
+ "name": "before",
183
+ "type": "string[]",
184
+ "required": false,
185
+ "description": "Commands to run before the plan — typically cloud-credential setup, since the plan queries the live system to classify create/update/delete."
186
+ },
187
+ {
188
+ "name": "defaults",
189
+ "type": "{ plan?: Partial<ConstructorParameters<typeof Job>[0]>; }",
190
+ "required": false,
191
+ "description": "Per-member defaults for customizing the generated job."
192
+ }
193
+ ]
194
+ },
195
+ {
196
+ "name": "NodePipeline",
197
+ "lexicon": "gitlab",
198
+ "description": "Bundles Default, Job.",
199
+ "bundles": [
200
+ "Default",
201
+ "Job"
202
+ ],
203
+ "params": [
204
+ {
205
+ "name": "nodeVersion",
206
+ "type": "string",
207
+ "required": false,
208
+ "description": "Node.js version."
209
+ },
210
+ {
211
+ "name": "packageManager",
212
+ "type": "\"npm\" | \"pnpm\" | \"bun\"",
213
+ "required": false,
214
+ "description": "Package manager."
215
+ },
216
+ {
217
+ "name": "buildScript",
218
+ "type": "string",
219
+ "required": false,
220
+ "description": "Build script name (runs via package manager)."
221
+ },
222
+ {
223
+ "name": "testScript",
224
+ "type": "string",
225
+ "required": false,
226
+ "description": "Test script name."
227
+ },
228
+ {
229
+ "name": "buildArtifactPaths",
230
+ "type": "string[]",
231
+ "required": false,
232
+ "description": "Artifact paths from build."
233
+ },
234
+ {
235
+ "name": "artifactExpiry",
236
+ "type": "string",
237
+ "required": false,
238
+ "description": "Artifact expiry."
239
+ },
240
+ {
241
+ "name": "installCommand",
242
+ "type": "string",
243
+ "required": false,
244
+ "description": "Override auto-detected install command"
245
+ },
246
+ {
247
+ "name": "defaults",
248
+ "type": "{ defaults?: Partial<ConstructorParameters<typeof Default>[0]>; build?: Partial<ConstructorParameters<typeof Job>[0]>...",
249
+ "required": false,
250
+ "description": "Per-member defaults for customizing the generated resources."
251
+ }
252
+ ]
253
+ },
254
+ {
255
+ "name": "PnpmPipeline",
256
+ "lexicon": "gitlab",
257
+ "description": "NodePipeline preset for pnpm projects.",
258
+ "bundles": [
259
+ "Default",
260
+ "Job"
261
+ ],
262
+ "params": [
263
+ {
264
+ "name": "defaults",
265
+ "type": "{ defaults?: Partial<ConstructorParameters<typeof Default>[0]>; build?: Partial<ConstructorParameters<typeof Job>[0]>...",
266
+ "required": false,
267
+ "description": "Per-member defaults for customizing the generated resources."
268
+ },
269
+ {
270
+ "name": "nodeVersion",
271
+ "type": "string",
272
+ "required": false,
273
+ "description": "Node.js version."
274
+ },
275
+ {
276
+ "name": "installCommand",
277
+ "type": "string",
278
+ "required": false,
279
+ "description": "Override auto-detected install command"
280
+ },
281
+ {
282
+ "name": "buildScript",
283
+ "type": "string",
284
+ "required": false,
285
+ "description": "Build script name (runs via package manager)."
286
+ },
287
+ {
288
+ "name": "buildArtifactPaths",
289
+ "type": "string[]",
290
+ "required": false,
291
+ "description": "Artifact paths from build."
292
+ },
293
+ {
294
+ "name": "artifactExpiry",
295
+ "type": "string",
296
+ "required": false,
297
+ "description": "Artifact expiry."
298
+ },
299
+ {
300
+ "name": "testScript",
301
+ "type": "string",
302
+ "required": false,
303
+ "description": "Test script name."
304
+ },
305
+ {
306
+ "name": "packageManager",
307
+ "type": "\"npm\" | \"pnpm\" | \"bun\"",
308
+ "required": false,
309
+ "description": "Package manager."
310
+ }
311
+ ]
312
+ },
313
+ {
314
+ "name": "PythonPipeline",
315
+ "lexicon": "gitlab",
316
+ "description": "Bundles Default, Job.",
317
+ "bundles": [
318
+ "Default",
319
+ "Job"
320
+ ],
321
+ "params": [
322
+ {
323
+ "name": "pythonVersion",
324
+ "type": "string",
325
+ "required": false,
326
+ "description": "Python version."
327
+ },
328
+ {
329
+ "name": "testCommand",
330
+ "type": "string",
331
+ "required": false,
332
+ "description": "Test command."
333
+ },
334
+ {
335
+ "name": "lintCommand",
336
+ "type": "string | null",
337
+ "required": false,
338
+ "description": "Lint command."
339
+ },
340
+ {
341
+ "name": "requirementsFile",
342
+ "type": "string",
343
+ "required": false,
344
+ "description": "Requirements file."
345
+ },
346
+ {
347
+ "name": "usePoetry",
348
+ "type": "boolean",
349
+ "required": false,
350
+ "description": "Use poetry instead of pip."
351
+ },
352
+ {
353
+ "name": "defaults",
354
+ "type": "{ defaults?: Partial<ConstructorParameters<typeof Default>[0]>; test?: Partial<ConstructorParameters<typeof Job>[0]>;...",
355
+ "required": false,
356
+ "description": "Per-member defaults for customizing the generated resources."
357
+ }
358
+ ]
359
+ },
360
+ {
361
+ "name": "ReviewApp",
362
+ "lexicon": "gitlab",
363
+ "description": "Bundles Job.",
364
+ "bundles": [
365
+ "Job"
366
+ ],
367
+ "params": [
368
+ {
369
+ "name": "name",
370
+ "type": "string",
371
+ "required": true,
372
+ "description": "Base name for the jobs (e.g. \"review\" → review-deploy, review-stop in YAML)."
373
+ },
374
+ {
375
+ "name": "deployScript",
376
+ "type": "string | string[]",
377
+ "required": true,
378
+ "description": "Deploy script command(s)."
379
+ },
380
+ {
381
+ "name": "stopScript",
382
+ "type": "string | string[]",
383
+ "required": false,
384
+ "description": "Stop script command(s)."
385
+ },
386
+ {
387
+ "name": "urlPattern",
388
+ "type": "string",
389
+ "required": false,
390
+ "description": "Environment URL pattern."
391
+ },
392
+ {
393
+ "name": "autoStopIn",
394
+ "type": "string",
395
+ "required": false,
396
+ "description": "Auto-stop timer."
397
+ },
398
+ {
399
+ "name": "image",
400
+ "type": "InstanceType<typeof Image>",
401
+ "required": false,
402
+ "description": "Override image for both jobs."
403
+ },
404
+ {
405
+ "name": "stage",
406
+ "type": "string",
407
+ "required": false,
408
+ "description": "Job stage."
409
+ },
410
+ {
411
+ "name": "defaults",
412
+ "type": "{ deploy?: Partial<ConstructorParameters<typeof Job>[0]>; stop?: Partial<ConstructorParameters<typeof Job>[0]>; }",
413
+ "required": false,
414
+ "description": "Per-member defaults for customizing the deploy and stop jobs."
415
+ }
416
+ ]
417
+ }
418
+ ];
@@ -0,0 +1,38 @@
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
+ import { Job, Image, Service } from "../generated/index.js";
3
+ import { CI } from "../variables.js";
4
+ export const DockerBuild = Composite((props) => {
5
+ const { stage = "build", tag = CI.CommitRefSlug, dockerfile = "Dockerfile", context = ".", registry = CI.Registry, image = CI.RegistryImage, tagLatest = true, buildArgs, rules, dockerVersion = "27", defaults: defs, } = props;
6
+ const buildArgFlags = buildArgs
7
+ ? Object.entries(buildArgs)
8
+ .map(([k, v]) => `--build-arg ${k}=${v}`)
9
+ .join(" ")
10
+ : "";
11
+ const buildCmd = [
12
+ "docker build",
13
+ buildArgFlags,
14
+ `-t ${image}:${tag}`,
15
+ `-f ${dockerfile}`,
16
+ context,
17
+ ]
18
+ .filter(Boolean)
19
+ .join(" ");
20
+ const script = [buildCmd, `docker push ${image}:${tag}`];
21
+ if (tagLatest) {
22
+ script.push(`if [ "${CI.CommitBranch}" = "${CI.DefaultBranch}" ]; then docker tag ${image}:${tag} ${image}:latest && docker push ${image}:latest; fi`);
23
+ }
24
+ const build = new Job(mergeDefaults({
25
+ stage,
26
+ image: new Image({ name: `docker:${dockerVersion}-cli` }),
27
+ services: [new Service({ name: `docker:${dockerVersion}-dind`, alias: "docker" })],
28
+ variables: {
29
+ DOCKER_TLS_CERTDIR: "/certs",
30
+ },
31
+ before_script: [
32
+ `docker login -u ${CI.RegistryUser} -p ${CI.RegistryPassword} ${registry}`,
33
+ ],
34
+ script,
35
+ ...(rules ? { rules } : {}),
36
+ }, defs?.build));
37
+ return { build };
38
+ }, "DockerBuild");
@@ -0,0 +1,5 @@
1
+ export { DockerBuild } from "./docker-build.js";
2
+ export { NodePipeline, BunPipeline, PnpmPipeline } from "./node-pipeline.js";
3
+ export { PythonPipeline } from "./python-pipeline.js";
4
+ export { ReviewApp } from "./review-app.js";
5
+ export { MrPlanReport } from "./mr-plan-report.js";
@@ -0,0 +1,42 @@
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
+ import { Job, Image, Artifacts } from "../generated/index.js";
3
+ /**
4
+ * A CI job that publishes `chant lifecycle plan` as the GitLab merge-request
5
+ * plan widget.
6
+ *
7
+ * The job runs the plan with `--report gitlab-mr`, writes the count JSON to a
8
+ * file, and declares it as `artifacts:reports:terraform`. GitLab then renders
9
+ * "N to add, M to change, K to delete" on the MR — the same widget Terraform
10
+ * uses. The label reads "Terraform" regardless of producer; that is GitLab's
11
+ * fixed string. Counts are create/update/delete only — `adopt` and `noop` do
12
+ * not appear.
13
+ *
14
+ * The plan reads the live system to classify drift, so wire cloud credentials
15
+ * via `before` or CI variables.
16
+ */
17
+ export const MrPlanReport = Composite((props) => {
18
+ const { environment, lexicon, stage = "plan", image = "node:22-alpine", ownedOnly = false, reportFile = "tfplan.json", before, defaults: defs, } = props;
19
+ const planArgs = [
20
+ "lifecycle",
21
+ "plan",
22
+ environment,
23
+ ...(lexicon ? [lexicon] : []),
24
+ ...(ownedOnly ? ["--owned"] : []),
25
+ "--report",
26
+ "gitlab-mr",
27
+ ].join(" ");
28
+ const plan = new Job(mergeDefaults({
29
+ stage,
30
+ image: new Image({ name: image }),
31
+ ...(before ? { before_script: before } : {}),
32
+ script: [
33
+ "npx chant build",
34
+ `npx chant ${planArgs} > ${reportFile}`,
35
+ ],
36
+ artifacts: new Artifacts({
37
+ reports: { terraform: reportFile },
38
+ when: "always",
39
+ }),
40
+ }, defs?.plan));
41
+ return { plan };
42
+ }, "MrPlanReport");
@@ -0,0 +1,67 @@
1
+ import { Composite, mergeDefaults, withDefaults } from "@intentius/chant";
2
+ import { Job, Default, Image, Cache, Artifacts } from "../generated/index.js";
3
+ import { CI } from "../variables.js";
4
+ const cacheConfig = {
5
+ npm: {
6
+ paths: [".npm/"],
7
+ keyFile: "package-lock.json",
8
+ envVars: { npm_config_cache: `${CI.ProjectDir}/.npm/` },
9
+ installCmd: "npm ci",
10
+ runPrefix: "npm run",
11
+ },
12
+ pnpm: {
13
+ paths: [".pnpm-store/"],
14
+ keyFile: "pnpm-lock.yaml",
15
+ envVars: {},
16
+ installCmd: "pnpm install --frozen-lockfile",
17
+ runPrefix: "pnpm run",
18
+ },
19
+ bun: {
20
+ paths: [".bun/install/cache"],
21
+ keyFile: "bun.lock",
22
+ envVars: {},
23
+ installCmd: "bun install --frozen-lockfile",
24
+ runPrefix: "bun run",
25
+ },
26
+ };
27
+ export const NodePipeline = Composite((props) => {
28
+ const { nodeVersion = "22", packageManager = "npm", buildScript = "build", testScript = "test", buildArtifactPaths = ["dist/"], artifactExpiry = "1 hour", installCommand, defaults: defs, } = props;
29
+ const pm = cacheConfig[packageManager];
30
+ const install = installCommand ?? pm.installCmd;
31
+ const run = pm.runPrefix;
32
+ const nodeImage = new Image({ name: `node:${nodeVersion}-alpine` });
33
+ const cache = new Cache({
34
+ key: { files: [pm.keyFile] },
35
+ paths: pm.paths,
36
+ policy: "pull-push",
37
+ });
38
+ const variables = Object.keys(pm.envVars).length > 0 ? pm.envVars : undefined;
39
+ const defaults = new Default(mergeDefaults({
40
+ image: nodeImage,
41
+ cache: [cache],
42
+ ...(variables ? {} : {}),
43
+ }, defs?.defaults));
44
+ const build = new Job(mergeDefaults({
45
+ stage: "build",
46
+ script: [install, `${run} ${buildScript}`],
47
+ artifacts: new Artifacts({
48
+ paths: buildArtifactPaths,
49
+ expire_in: artifactExpiry,
50
+ }),
51
+ ...(variables ? { variables } : {}),
52
+ }, defs?.build));
53
+ const test = new Job(mergeDefaults({
54
+ stage: "test",
55
+ script: [install, `${run} ${testScript}`],
56
+ artifacts: new Artifacts({
57
+ reports: { junit: "junit.xml" },
58
+ when: "always",
59
+ }),
60
+ ...(variables ? { variables } : {}),
61
+ }, defs?.test));
62
+ return { defaults, build, test };
63
+ }, "NodePipeline");
64
+ /** NodePipeline preset for Bun projects. */
65
+ export const BunPipeline = withDefaults(NodePipeline, { packageManager: "bun" });
66
+ /** NodePipeline preset for pnpm projects. */
67
+ export const PnpmPipeline = withDefaults(NodePipeline, { packageManager: "pnpm" });
@@ -0,0 +1,45 @@
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
+ import { Job, Default, Image, Cache, Artifacts } from "../generated/index.js";
3
+ import { CI } from "../variables.js";
4
+ export const PythonPipeline = Composite((props) => {
5
+ const { pythonVersion = "3.12", testCommand = "pytest --junitxml=report.xml --cov", lintCommand = "ruff check .", requirementsFile = "requirements.txt", usePoetry = false, defaults: defs, } = props;
6
+ const pythonImage = new Image({ name: `python:${pythonVersion}-slim` });
7
+ const cache = new Cache({
8
+ key: { files: [usePoetry ? "poetry.lock" : requirementsFile] },
9
+ paths: [".pip-cache/", ".venv/"],
10
+ policy: "pull-push",
11
+ });
12
+ const installSteps = usePoetry
13
+ ? ["pip install poetry", "poetry config virtualenvs.in-project true", "poetry install"]
14
+ : [
15
+ "python -m venv .venv",
16
+ "source .venv/bin/activate",
17
+ `pip install -r ${requirementsFile}`,
18
+ ];
19
+ const activateStep = usePoetry ? "source .venv/bin/activate" : "source .venv/bin/activate";
20
+ const defaults = new Default(mergeDefaults({
21
+ image: pythonImage,
22
+ cache: [cache],
23
+ before_script: [...installSteps],
24
+ }, defs?.defaults));
25
+ const test = new Job(mergeDefaults({
26
+ stage: "test",
27
+ variables: { PIP_CACHE_DIR: `${CI.ProjectDir}/.pip-cache` },
28
+ script: [activateStep, testCommand],
29
+ artifacts: new Artifacts({
30
+ reports: { junit: "report.xml" },
31
+ when: "always",
32
+ }),
33
+ }, defs?.test));
34
+ const lint = lintCommand !== null
35
+ ? new Job(mergeDefaults({
36
+ stage: "test",
37
+ variables: { PIP_CACHE_DIR: `${CI.ProjectDir}/.pip-cache` },
38
+ script: [activateStep, lintCommand],
39
+ }, defs?.lint))
40
+ : undefined;
41
+ if (lint) {
42
+ return { defaults, test, lint };
43
+ }
44
+ return { defaults, test };
45
+ }, "PythonPipeline");
@@ -0,0 +1,32 @@
1
+ import { Composite, mergeDefaults } from "@intentius/chant";
2
+ import { Job, Environment, Rule } from "../generated/index.js";
3
+ import { CI } from "../variables.js";
4
+ export const ReviewApp = Composite((props) => {
5
+ const { name, deployScript, stopScript = 'echo "Stopping review app..."', urlPattern = `https://${CI.EnvironmentSlug}.example.com`, autoStopIn = "1 week", image, stage = "deploy", defaults: defs, } = props;
6
+ const stopJobName = `${name}-stop`;
7
+ const deployScriptArr = Array.isArray(deployScript) ? deployScript : [deployScript];
8
+ const stopScriptArr = Array.isArray(stopScript) ? stopScript : [stopScript];
9
+ const deploy = new Job(mergeDefaults({
10
+ stage,
11
+ ...(image ? { image } : {}),
12
+ environment: new Environment({
13
+ name: `review/${CI.CommitRefSlug}`,
14
+ url: urlPattern,
15
+ auto_stop_in: autoStopIn,
16
+ on_stop: stopJobName,
17
+ }),
18
+ rules: [new Rule({ if: CI.MergeRequestIid })],
19
+ script: deployScriptArr,
20
+ }, defs?.deploy));
21
+ const stop = new Job(mergeDefaults({
22
+ stage,
23
+ ...(image ? { image } : {}),
24
+ environment: new Environment({
25
+ name: `review/${CI.CommitRefSlug}`,
26
+ action: "stop",
27
+ }),
28
+ rules: [new Rule({ if: CI.MergeRequestIid, when: "manual" })],
29
+ script: stopScriptArr,
30
+ }, defs?.stop));
31
+ return { deploy, stop };
32
+ }, "ReviewApp");