@intentius/chant-lexicon-gitlab 0.0.4 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -46
- package/dist/integrity.json +5 -5
- package/dist/manifest.json +1 -1
- package/dist/meta.json +5 -0
- package/dist/skills/chant-gitlab.md +59 -0
- package/dist/types/index.d.ts +13 -0
- package/package.json +2 -2
- package/src/codegen/docs.ts +87 -441
- package/src/codegen/generate-lexicon.ts +1 -1
- package/src/codegen/package.ts +2 -0
- package/src/codegen/parse.test.ts +5 -4
- package/src/codegen/parse.ts +8 -10
- package/src/codegen/snapshot.test.ts +3 -3
- package/src/generated/index.d.ts +13 -0
- package/src/generated/index.ts +1 -0
- package/src/generated/lexicon-gitlab.json +5 -0
- package/src/import/parser.test.ts +3 -3
- package/src/import/parser.ts +12 -26
- package/src/lsp/completions.ts +2 -0
- package/src/lsp/hover.ts +2 -0
- package/src/plugin.test.ts +6 -8
- package/src/plugin.ts +73 -101
- package/src/serializer.test.ts +6 -6
- package/src/serializer.ts +1 -9
- package/src/validate.test.ts +13 -22
- package/src/validate.ts +17 -108
- package/dist/skills/gitlab-ci.md +0 -37
- package/src/codegen/rollback.ts +0 -26
package/src/codegen/docs.ts
CHANGED
|
@@ -28,20 +28,7 @@ npm install --save-dev @intentius/chant-lexicon-gitlab
|
|
|
28
28
|
|
|
29
29
|
## Quick Start
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
import { Job, Image, Cache, Artifacts, CI } from "@intentius/chant-lexicon-gitlab";
|
|
33
|
-
|
|
34
|
-
export const test = new Job({
|
|
35
|
-
stage: "test",
|
|
36
|
-
image: new Image({ name: "node:20" }),
|
|
37
|
-
cache: new Cache({ key: CI.CommitRef, paths: ["node_modules/"] }),
|
|
38
|
-
script: ["npm ci", "npm test"],
|
|
39
|
-
artifacts: new Artifacts({
|
|
40
|
-
paths: ["coverage/"],
|
|
41
|
-
expireIn: "1 week",
|
|
42
|
-
}),
|
|
43
|
-
});
|
|
44
|
-
\`\`\`
|
|
31
|
+
{{file:docs-snippets/src/quickstart.ts}}
|
|
45
32
|
|
|
46
33
|
The lexicon provides **3 resources** (Job, Workflow, Default), **13 property types** (Image, Cache, Artifacts, Rule, Environment, Trigger, and more), the \`CI\` pseudo-parameter object for predefined variables, and the \`reference()\` intrinsic for YAML \`!reference\` tags.
|
|
47
34
|
`;
|
|
@@ -71,8 +58,7 @@ The generated file includes:
|
|
|
71
58
|
| Chant (TypeScript) | YAML output | Rule |
|
|
72
59
|
|--------------------|-------------|------|
|
|
73
60
|
| \`export const buildApp = new Job({...})\` | \`build-app:\` | Export name → kebab-case job key |
|
|
74
|
-
| \`
|
|
75
|
-
| \`ifCondition: ...\` | \`if: ...\` | Reserved word properties use suffixed names |
|
|
61
|
+
| \`expire_in: "1 week"\` | \`expire_in: 1 week\` | Property names use spec-native snake_case |
|
|
76
62
|
| \`new Image({ name: "node:20" })\` | \`image: node:20\` | Single-property objects are collapsed |
|
|
77
63
|
|
|
78
64
|
## Validating locally
|
|
@@ -113,6 +99,7 @@ export async function generateDocs(opts?: { verbose?: boolean }): Promise<void>
|
|
|
113
99
|
outputFormat,
|
|
114
100
|
serviceFromType,
|
|
115
101
|
suppressPages: ["intrinsics", "rules"],
|
|
102
|
+
examplesDir: join(pkgDir, "examples"),
|
|
116
103
|
extraPages: [
|
|
117
104
|
{
|
|
118
105
|
slug: "pipeline-concepts",
|
|
@@ -120,19 +107,12 @@ export async function generateDocs(opts?: { verbose?: boolean }): Promise<void>
|
|
|
120
107
|
description: "Jobs, stages, artifacts, caching, images, rules, environments, and triggers in the GitLab CI/CD lexicon",
|
|
121
108
|
content: `Every exported \`Job\` declaration becomes a job entry in the generated \`.gitlab-ci.yml\`. The serializer handles the translation automatically:
|
|
122
109
|
|
|
123
|
-
-
|
|
110
|
+
- Property names use spec-native snake_case (\`expire_in\`, \`allow_failure\`)
|
|
124
111
|
- Converts export names to kebab-case job keys (\`buildApp\` → \`build-app\`)
|
|
125
112
|
- Collects stages from all jobs into a \`stages:\` list
|
|
126
113
|
- Collapses single-property objects (\`new Image({ name: "node:20" })\` → \`image: node:20\`)
|
|
127
114
|
|
|
128
|
-
|
|
129
|
-
// This chant declaration...
|
|
130
|
-
export const buildApp = new Job({
|
|
131
|
-
stage: "build",
|
|
132
|
-
image: new Image({ name: "node:20" }),
|
|
133
|
-
script: ["npm ci", "npm run build"],
|
|
134
|
-
});
|
|
135
|
-
\`\`\`
|
|
115
|
+
{{file:docs-snippets/src/job-basic.ts}}
|
|
136
116
|
|
|
137
117
|
Produces this YAML:
|
|
138
118
|
|
|
@@ -177,47 +157,17 @@ The lexicon provides 3 resource types and 13 property types:
|
|
|
177
157
|
| \`Release\` | Job | GitLab Release creation |
|
|
178
158
|
| \`AutoCancel\` | Workflow | Pipeline auto-cancellation settings |
|
|
179
159
|
|
|
180
|
-
##
|
|
181
|
-
|
|
182
|
-
Every chant project has a barrel file (conventionally \`_.ts\`) that re-exports the lexicon:
|
|
183
|
-
|
|
184
|
-
\`\`\`typescript
|
|
185
|
-
// _.ts — the barrel file
|
|
186
|
-
export * from "@intentius/chant-lexicon-gitlab";
|
|
187
|
-
export * from "./config";
|
|
188
|
-
\`\`\`
|
|
160
|
+
## Shared config
|
|
189
161
|
|
|
190
|
-
|
|
162
|
+
Extract reusable objects into a shared config file and import them across your pipeline files:
|
|
191
163
|
|
|
192
|
-
|
|
193
|
-
// pipeline.ts
|
|
194
|
-
import * as _ from "./_";
|
|
195
|
-
|
|
196
|
-
export const build = new _.Job({
|
|
197
|
-
stage: "build",
|
|
198
|
-
image: _.nodeImage, // from config.ts via barrel
|
|
199
|
-
cache: _.npmCache, // from config.ts via barrel
|
|
200
|
-
script: ["npm ci", "npm run build"],
|
|
201
|
-
artifacts: _.buildArtifacts,
|
|
202
|
-
});
|
|
203
|
-
\`\`\`
|
|
164
|
+
{{file:docs-snippets/src/pipeline-barrel.ts}}
|
|
204
165
|
|
|
205
166
|
## Jobs
|
|
206
167
|
|
|
207
168
|
A \`Job\` is the fundamental unit. Every exported \`Job\` becomes a job entry in the YAML:
|
|
208
169
|
|
|
209
|
-
|
|
210
|
-
export const test = new Job({
|
|
211
|
-
stage: "test",
|
|
212
|
-
image: new Image({ name: "node:20-alpine" }),
|
|
213
|
-
script: ["npm ci", "npm test"],
|
|
214
|
-
artifacts: new Artifacts({
|
|
215
|
-
paths: ["coverage/"],
|
|
216
|
-
expireIn: "1 week",
|
|
217
|
-
reports: { junit: "coverage/junit.xml" },
|
|
218
|
-
}),
|
|
219
|
-
});
|
|
220
|
-
\`\`\`
|
|
170
|
+
{{file:docs-snippets/src/job-test.ts}}
|
|
221
171
|
|
|
222
172
|
Key properties:
|
|
223
173
|
- \`script\` — **required** (or \`trigger\`/\`run\`). Array of shell commands to execute.
|
|
@@ -229,12 +179,7 @@ Key properties:
|
|
|
229
179
|
|
|
230
180
|
Stages define the execution order of a pipeline. The serializer automatically collects unique stage values from all jobs:
|
|
231
181
|
|
|
232
|
-
|
|
233
|
-
export const lint = new Job({ stage: "test", script: ["npm run lint"] });
|
|
234
|
-
export const test = new Job({ stage: "test", script: ["npm test"] });
|
|
235
|
-
export const build = new Job({ stage: "build", script: ["npm run build"] });
|
|
236
|
-
export const deploy = new Job({ stage: "deploy", script: ["npm run deploy"] });
|
|
237
|
-
\`\`\`
|
|
182
|
+
{{file:docs-snippets/src/stages.ts}}
|
|
238
183
|
|
|
239
184
|
Produces:
|
|
240
185
|
|
|
@@ -249,30 +194,9 @@ Jobs in the same stage run in parallel. Stages run sequentially in declaration o
|
|
|
249
194
|
|
|
250
195
|
## Artifacts and caching
|
|
251
196
|
|
|
252
|
-
**Artifacts** are files produced by a job and passed to later stages or stored for download:
|
|
197
|
+
**Artifacts** are files produced by a job and passed to later stages or stored for download. **Caches** persist files between pipeline runs to speed up builds. Both are shown in the shared config:
|
|
253
198
|
|
|
254
|
-
|
|
255
|
-
export const buildArtifacts = new Artifacts({
|
|
256
|
-
paths: ["dist/"],
|
|
257
|
-
expireIn: "1 hour", // always set expiry (WGL004 warns if missing)
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
export const testArtifacts = new Artifacts({
|
|
261
|
-
paths: ["coverage/"],
|
|
262
|
-
expireIn: "1 week",
|
|
263
|
-
reports: { junit: "coverage/junit.xml" }, // parsed by GitLab for MR display
|
|
264
|
-
});
|
|
265
|
-
\`\`\`
|
|
266
|
-
|
|
267
|
-
**Caches** persist files between pipeline runs to speed up builds:
|
|
268
|
-
|
|
269
|
-
\`\`\`typescript
|
|
270
|
-
export const npmCache = new Cache({
|
|
271
|
-
key: "$CI_COMMIT_REF_SLUG", // cache per branch
|
|
272
|
-
paths: ["node_modules/"],
|
|
273
|
-
policy: "pull-push", // "pull" for read-only, "push" for write-only
|
|
274
|
-
});
|
|
275
|
-
\`\`\`
|
|
199
|
+
{{file:docs-snippets/src/config.ts:4-22}}
|
|
276
200
|
|
|
277
201
|
The key difference: artifacts are for passing files between **stages in the same pipeline**; caches are for speeding up **repeated pipeline runs**.
|
|
278
202
|
|
|
@@ -280,22 +204,7 @@ The key difference: artifacts are for passing files between **stages in the same
|
|
|
280
204
|
|
|
281
205
|
\`Rule\` objects control when a job runs. They map to \`rules:\` entries in the YAML:
|
|
282
206
|
|
|
283
|
-
|
|
284
|
-
export const onMergeRequest = new Rule({
|
|
285
|
-
ifCondition: CI.MergeRequestIid, // → if: $CI_MERGE_REQUEST_IID
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
export const onDefaultBranch = new Rule({
|
|
289
|
-
ifCondition: \`\${CI.CommitBranch} == \${CI.DefaultBranch}\`,
|
|
290
|
-
when: "manual", // require manual trigger
|
|
291
|
-
});
|
|
292
|
-
|
|
293
|
-
export const deploy = new Job({
|
|
294
|
-
stage: "deploy",
|
|
295
|
-
script: ["npm run deploy"],
|
|
296
|
-
rules: [onDefaultBranch],
|
|
297
|
-
});
|
|
298
|
-
\`\`\`
|
|
207
|
+
{{file:docs-snippets/src/rules-conditions.ts}}
|
|
299
208
|
|
|
300
209
|
Produces:
|
|
301
210
|
|
|
@@ -315,19 +224,7 @@ The \`ifCondition\` property maps to \`if:\` in the YAML (since \`if\` is a rese
|
|
|
315
224
|
|
|
316
225
|
\`Environment\` defines a deployment target:
|
|
317
226
|
|
|
318
|
-
|
|
319
|
-
export const productionEnv = new Environment({
|
|
320
|
-
name: "production",
|
|
321
|
-
url: "https://example.com",
|
|
322
|
-
});
|
|
323
|
-
|
|
324
|
-
export const deploy = new Job({
|
|
325
|
-
stage: "deploy",
|
|
326
|
-
script: ["npm run deploy"],
|
|
327
|
-
environment: productionEnv,
|
|
328
|
-
rules: [onDefaultBranch],
|
|
329
|
-
});
|
|
330
|
-
\`\`\`
|
|
227
|
+
{{file:docs-snippets/src/environment.ts}}
|
|
331
228
|
|
|
332
229
|
GitLab tracks deployments to environments and provides rollback capabilities in the UI.
|
|
333
230
|
|
|
@@ -335,44 +232,19 @@ GitLab tracks deployments to environments and provides rollback capabilities in
|
|
|
335
232
|
|
|
336
233
|
\`Image\` specifies the Docker image for a job:
|
|
337
234
|
|
|
338
|
-
|
|
339
|
-
export const nodeImage = new Image({ name: "node:20-alpine" });
|
|
340
|
-
|
|
341
|
-
// With entrypoint override
|
|
342
|
-
export const customImage = new Image({
|
|
343
|
-
name: "registry.example.com/my-image:latest",
|
|
344
|
-
entrypoint: ["/bin/sh", "-c"],
|
|
345
|
-
});
|
|
346
|
-
\`\`\`
|
|
235
|
+
{{file:docs-snippets/src/images.ts}}
|
|
347
236
|
|
|
348
237
|
## Workflow
|
|
349
238
|
|
|
350
239
|
\`Workflow\` controls pipeline-level settings — when pipelines run, auto-cancellation, and global includes:
|
|
351
240
|
|
|
352
|
-
|
|
353
|
-
export const workflow = new Workflow({
|
|
354
|
-
name: "CI Pipeline for $CI_COMMIT_REF_NAME",
|
|
355
|
-
rules: [
|
|
356
|
-
new Rule({ ifCondition: CI.MergeRequestIid }),
|
|
357
|
-
new Rule({ ifCondition: CI.CommitBranch }),
|
|
358
|
-
],
|
|
359
|
-
autoCancel: new AutoCancel({
|
|
360
|
-
onNewCommit: "interruptible",
|
|
361
|
-
}),
|
|
362
|
-
});
|
|
363
|
-
\`\`\`
|
|
241
|
+
{{file:docs-snippets/src/workflow.ts}}
|
|
364
242
|
|
|
365
243
|
## Default
|
|
366
244
|
|
|
367
245
|
\`Default\` sets shared configuration inherited by all jobs:
|
|
368
246
|
|
|
369
|
-
|
|
370
|
-
export const defaults = new Default({
|
|
371
|
-
image: new Image({ name: "node:20-alpine" }),
|
|
372
|
-
cache: new Cache({ key: CI.CommitRef, paths: ["node_modules/"] }),
|
|
373
|
-
retry: new Retry({ max: 2, when: ["runner_system_failure"] }),
|
|
374
|
-
});
|
|
375
|
-
\`\`\`
|
|
247
|
+
{{file:docs-snippets/src/defaults.ts}}
|
|
376
248
|
|
|
377
249
|
Jobs can override any default property individually.
|
|
378
250
|
|
|
@@ -380,16 +252,7 @@ Jobs can override any default property individually.
|
|
|
380
252
|
|
|
381
253
|
\`Trigger\` creates downstream pipeline jobs:
|
|
382
254
|
|
|
383
|
-
|
|
384
|
-
export const deployInfra = new Job({
|
|
385
|
-
stage: "deploy",
|
|
386
|
-
trigger: new Trigger({
|
|
387
|
-
project: "my-group/infra-repo",
|
|
388
|
-
branch: "main",
|
|
389
|
-
strategy: "depend",
|
|
390
|
-
}),
|
|
391
|
-
});
|
|
392
|
-
\`\`\``,
|
|
255
|
+
{{file:docs-snippets/src/trigger.ts}}`,
|
|
393
256
|
},
|
|
394
257
|
{
|
|
395
258
|
slug: "variables",
|
|
@@ -397,25 +260,7 @@ export const deployInfra = new Job({
|
|
|
397
260
|
description: "GitLab CI/CD predefined variable references",
|
|
398
261
|
content: `The \`CI\` object provides type-safe access to GitLab CI/CD predefined variables. These map to \`$CI_*\` environment variables at runtime.
|
|
399
262
|
|
|
400
|
-
|
|
401
|
-
import { CI, Job, Rule } from "@intentius/chant-lexicon-gitlab";
|
|
402
|
-
|
|
403
|
-
// Use in rule conditions
|
|
404
|
-
const onDefault = new Rule({
|
|
405
|
-
ifCondition: \`\${CI.CommitBranch} == \${CI.DefaultBranch}\`,
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
// Use in cache keys
|
|
409
|
-
const cache = new Cache({
|
|
410
|
-
key: CI.CommitRef, // → $CI_COMMIT_REF_NAME
|
|
411
|
-
paths: ["node_modules/"],
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
// Use in workflow names
|
|
415
|
-
const workflow = new Workflow({
|
|
416
|
-
name: \`Pipeline for \${CI.CommitRef}\`,
|
|
417
|
-
});
|
|
418
|
-
\`\`\`
|
|
263
|
+
{{file:docs-snippets/src/variables-usage.ts}}
|
|
419
264
|
|
|
420
265
|
## Variable reference
|
|
421
266
|
|
|
@@ -442,44 +287,7 @@ const workflow = new Workflow({
|
|
|
442
287
|
|
|
443
288
|
## Common patterns
|
|
444
289
|
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
\`\`\`typescript
|
|
448
|
-
// Only on merge requests
|
|
449
|
-
new Rule({ ifCondition: CI.MergeRequestIid })
|
|
450
|
-
|
|
451
|
-
// Only on default branch
|
|
452
|
-
new Rule({ ifCondition: \`\${CI.CommitBranch} == \${CI.DefaultBranch}\` })
|
|
453
|
-
|
|
454
|
-
// Only on tags
|
|
455
|
-
new Rule({ ifCondition: CI.CommitTag })
|
|
456
|
-
\`\`\`
|
|
457
|
-
|
|
458
|
-
**Dynamic naming:**
|
|
459
|
-
|
|
460
|
-
\`\`\`typescript
|
|
461
|
-
export const deploy = new Job({
|
|
462
|
-
stage: "deploy",
|
|
463
|
-
environment: new Environment({
|
|
464
|
-
name: \`review/\${CI.CommitRef}\`,
|
|
465
|
-
url: \`https://\${CI.CommitRef}.preview.example.com\`,
|
|
466
|
-
}),
|
|
467
|
-
script: ["deploy-preview"],
|
|
468
|
-
});
|
|
469
|
-
\`\`\`
|
|
470
|
-
|
|
471
|
-
**Container registry:**
|
|
472
|
-
|
|
473
|
-
\`\`\`typescript
|
|
474
|
-
export const buildImage = new Job({
|
|
475
|
-
stage: "build",
|
|
476
|
-
image: new Image({ name: "docker:24" }),
|
|
477
|
-
script: [
|
|
478
|
-
\`docker build -t \${CI.RegistryImage}:\${CI.CommitSha} .\`,
|
|
479
|
-
\`docker push \${CI.RegistryImage}:\${CI.CommitSha}\`,
|
|
480
|
-
],
|
|
481
|
-
});
|
|
482
|
-
\`\`\`
|
|
290
|
+
{{file:docs-snippets/src/variables-patterns.ts}}
|
|
483
291
|
`,
|
|
484
292
|
},
|
|
485
293
|
{
|
|
@@ -488,21 +296,11 @@ export const buildImage = new Job({
|
|
|
488
296
|
description: "GitLab CI/CD intrinsic functions and their chant syntax",
|
|
489
297
|
content: `The GitLab lexicon provides one intrinsic function: \`reference()\`, which maps to GitLab's \`!reference\` YAML tag.
|
|
490
298
|
|
|
491
|
-
\`\`\`typescript
|
|
492
|
-
import { reference } from "@intentius/chant-lexicon-gitlab";
|
|
493
|
-
\`\`\`
|
|
494
|
-
|
|
495
299
|
## \`reference()\` — reuse job properties
|
|
496
300
|
|
|
497
301
|
The \`reference()\` intrinsic lets you reuse properties from other jobs or hidden keys. It produces the \`!reference\` YAML tag:
|
|
498
302
|
|
|
499
|
-
|
|
500
|
-
import { reference, Job } from "@intentius/chant-lexicon-gitlab";
|
|
501
|
-
|
|
502
|
-
export const deploy = new Job({
|
|
503
|
-
script: reference(".setup", "script"),
|
|
504
|
-
});
|
|
505
|
-
\`\`\`
|
|
303
|
+
{{file:docs-snippets/src/reference-basic.ts}}
|
|
506
304
|
|
|
507
305
|
Serializes to:
|
|
508
306
|
|
|
@@ -522,24 +320,7 @@ reference(jobName: string, property: string): ReferenceTag
|
|
|
522
320
|
|
|
523
321
|
### Use cases
|
|
524
322
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
\`\`\`typescript
|
|
528
|
-
// Hidden key with shared setup (defined in .gitlab-ci.yml or included)
|
|
529
|
-
// Reference its script from multiple jobs:
|
|
530
|
-
|
|
531
|
-
export const test = new Job({
|
|
532
|
-
stage: "test",
|
|
533
|
-
beforeScript: reference(".node-setup", "before_script"),
|
|
534
|
-
script: ["npm test"],
|
|
535
|
-
});
|
|
536
|
-
|
|
537
|
-
export const lint = new Job({
|
|
538
|
-
stage: "test",
|
|
539
|
-
beforeScript: reference(".node-setup", "before_script"),
|
|
540
|
-
script: ["npm run lint"],
|
|
541
|
-
});
|
|
542
|
-
\`\`\`
|
|
323
|
+
{{file:docs-snippets/src/reference-shared.ts}}
|
|
543
324
|
|
|
544
325
|
Produces:
|
|
545
326
|
|
|
@@ -557,46 +338,9 @@ lint:
|
|
|
557
338
|
- npm run lint
|
|
558
339
|
\`\`\`
|
|
559
340
|
|
|
560
|
-
**Shared rules:**
|
|
561
|
-
|
|
562
|
-
\`\`\`typescript
|
|
563
|
-
export const build = new Job({
|
|
564
|
-
stage: "build",
|
|
565
|
-
rules: reference(".default-rules", "rules"),
|
|
566
|
-
script: ["npm run build"],
|
|
567
|
-
});
|
|
568
|
-
\`\`\`
|
|
569
|
-
|
|
570
|
-
**Nested references (multi-level):**
|
|
571
|
-
|
|
572
|
-
\`\`\`typescript
|
|
573
|
-
// Reference a specific nested element
|
|
574
|
-
export const deploy = new Job({
|
|
575
|
-
script: reference(".setup", "script"),
|
|
576
|
-
environment: reference(".deploy-defaults", "environment"),
|
|
577
|
-
});
|
|
578
|
-
\`\`\`
|
|
579
|
-
|
|
580
341
|
### When to use \`reference()\` vs barrel imports
|
|
581
342
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
\`\`\`typescript
|
|
585
|
-
// Preferred for chant-managed config
|
|
586
|
-
export const test = new Job({
|
|
587
|
-
cache: _.npmCache, // resolved at build time
|
|
588
|
-
artifacts: _.testArtifacts, // resolved at build time
|
|
589
|
-
});
|
|
590
|
-
\`\`\`
|
|
591
|
-
|
|
592
|
-
Use **\`reference()\`** when referencing jobs or hidden keys defined outside chant (e.g. in included YAML files or templates):
|
|
593
|
-
|
|
594
|
-
\`\`\`typescript
|
|
595
|
-
// For external/included YAML definitions
|
|
596
|
-
export const test = new Job({
|
|
597
|
-
beforeScript: reference(".ci-setup", "before_script"),
|
|
598
|
-
});
|
|
599
|
-
\`\`\`
|
|
343
|
+
{{file:docs-snippets/src/reference-vs-barrel.ts}}
|
|
600
344
|
`,
|
|
601
345
|
},
|
|
602
346
|
{
|
|
@@ -615,23 +359,7 @@ Lint rules analyze your TypeScript source code before build.
|
|
|
615
359
|
|
|
616
360
|
Flags usage of \`only:\` and \`except:\` keywords, which are deprecated in favor of \`rules:\`. The \`rules:\` syntax is more flexible and is the recommended approach.
|
|
617
361
|
|
|
618
|
-
|
|
619
|
-
// Triggers WGL001
|
|
620
|
-
export const deploy = new Job({
|
|
621
|
-
stage: "deploy",
|
|
622
|
-
script: ["npm run deploy"],
|
|
623
|
-
only: ["main"], // deprecated
|
|
624
|
-
});
|
|
625
|
-
|
|
626
|
-
// Fixed — use rules instead
|
|
627
|
-
export const deploy = new Job({
|
|
628
|
-
stage: "deploy",
|
|
629
|
-
script: ["npm run deploy"],
|
|
630
|
-
rules: [new Rule({
|
|
631
|
-
ifCondition: \`\${CI.CommitBranch} == \${CI.DefaultBranch}\`,
|
|
632
|
-
})],
|
|
633
|
-
});
|
|
634
|
-
\`\`\`
|
|
362
|
+
{{file:docs-snippets/src/lint-wgl001.ts}}
|
|
635
363
|
|
|
636
364
|
### WGL002 — Missing script
|
|
637
365
|
|
|
@@ -639,26 +367,7 @@ export const deploy = new Job({
|
|
|
639
367
|
|
|
640
368
|
A GitLab CI job must have \`script\`, \`trigger\`, or \`run\` defined. Jobs without any of these will fail pipeline validation.
|
|
641
369
|
|
|
642
|
-
|
|
643
|
-
// Triggers WGL002
|
|
644
|
-
export const build = new Job({
|
|
645
|
-
stage: "build",
|
|
646
|
-
image: new Image({ name: "node:20" }),
|
|
647
|
-
// Missing script!
|
|
648
|
-
});
|
|
649
|
-
|
|
650
|
-
// Fixed — add script
|
|
651
|
-
export const build = new Job({
|
|
652
|
-
stage: "build",
|
|
653
|
-
image: new Image({ name: "node:20" }),
|
|
654
|
-
script: ["npm run build"],
|
|
655
|
-
});
|
|
656
|
-
|
|
657
|
-
// Also valid — trigger job (no script needed)
|
|
658
|
-
export const downstream = new Job({
|
|
659
|
-
trigger: new Trigger({ project: "my-group/other-repo" }),
|
|
660
|
-
});
|
|
661
|
-
\`\`\`
|
|
370
|
+
{{file:docs-snippets/src/lint-wgl002.ts}}
|
|
662
371
|
|
|
663
372
|
### WGL003 — Missing stage
|
|
664
373
|
|
|
@@ -666,19 +375,7 @@ export const downstream = new Job({
|
|
|
666
375
|
|
|
667
376
|
Jobs should declare a \`stage\` property. Without it, the job defaults to the \`test\` stage, which may not be the intended behavior.
|
|
668
377
|
|
|
669
|
-
|
|
670
|
-
// Triggers WGL003
|
|
671
|
-
export const build = new Job({
|
|
672
|
-
script: ["npm run build"],
|
|
673
|
-
// No stage — defaults to "test"
|
|
674
|
-
});
|
|
675
|
-
|
|
676
|
-
// Fixed — declare the stage
|
|
677
|
-
export const build = new Job({
|
|
678
|
-
stage: "build",
|
|
679
|
-
script: ["npm run build"],
|
|
680
|
-
});
|
|
681
|
-
\`\`\`
|
|
378
|
+
{{file:docs-snippets/src/lint-wgl003.ts}}
|
|
682
379
|
|
|
683
380
|
### WGL004 — Artifacts without expiry
|
|
684
381
|
|
|
@@ -686,25 +383,7 @@ export const build = new Job({
|
|
|
686
383
|
|
|
687
384
|
Flags \`Artifacts\` without \`expireIn\`. Artifacts without expiry are kept indefinitely, consuming storage. Always set an expiration.
|
|
688
385
|
|
|
689
|
-
|
|
690
|
-
// Triggers WGL004
|
|
691
|
-
export const build = new Job({
|
|
692
|
-
script: ["npm run build"],
|
|
693
|
-
artifacts: new Artifacts({
|
|
694
|
-
paths: ["dist/"],
|
|
695
|
-
// Missing expireIn!
|
|
696
|
-
}),
|
|
697
|
-
});
|
|
698
|
-
|
|
699
|
-
// Fixed — set expiry
|
|
700
|
-
export const build = new Job({
|
|
701
|
-
script: ["npm run build"],
|
|
702
|
-
artifacts: new Artifacts({
|
|
703
|
-
paths: ["dist/"],
|
|
704
|
-
expireIn: "1 hour",
|
|
705
|
-
}),
|
|
706
|
-
});
|
|
707
|
-
\`\`\`
|
|
386
|
+
{{file:docs-snippets/src/lint-wgl004.ts}}
|
|
708
387
|
|
|
709
388
|
## Post-synth checks
|
|
710
389
|
|
|
@@ -722,16 +401,7 @@ Flags jobs that reference a stage not present in the collected stages list. This
|
|
|
722
401
|
|
|
723
402
|
Flags jobs where all \`rules:\` entries have \`when: "never"\`, making the job unreachable. This usually indicates a configuration error.
|
|
724
403
|
|
|
725
|
-
|
|
726
|
-
// Triggers WGL011 — job can never run
|
|
727
|
-
export const noop = new Job({
|
|
728
|
-
script: ["echo unreachable"],
|
|
729
|
-
rules: [
|
|
730
|
-
new Rule({ ifCondition: CI.CommitBranch, when: "never" }),
|
|
731
|
-
new Rule({ ifCondition: CI.CommitTag, when: "never" }),
|
|
732
|
-
],
|
|
733
|
-
});
|
|
734
|
-
\`\`\`
|
|
404
|
+
{{file:docs-snippets/src/lint-wgl011.ts}}
|
|
735
405
|
|
|
736
406
|
## Running lint
|
|
737
407
|
|
|
@@ -756,7 +426,7 @@ To suppress globally in \`chant.config.ts\`:
|
|
|
756
426
|
export default {
|
|
757
427
|
lint: {
|
|
758
428
|
rules: {
|
|
759
|
-
WGL003: "off",
|
|
429
|
+
WGL003: "off",
|
|
760
430
|
},
|
|
761
431
|
},
|
|
762
432
|
};
|
|
@@ -783,100 +453,21 @@ bun test # runs the example's tests
|
|
|
783
453
|
|
|
784
454
|
\`\`\`
|
|
785
455
|
src/
|
|
786
|
-
├── _.ts # Barrel — re-exports lexicon + shared config
|
|
787
456
|
├── config.ts # Shared config: images, caches, artifacts, rules, environments
|
|
788
457
|
└── pipeline.ts # Job definitions: build, test, deploy
|
|
789
458
|
\`\`\`
|
|
790
459
|
|
|
791
|
-
### Barrel file
|
|
792
|
-
|
|
793
|
-
The barrel re-exports both the lexicon and shared config, so pipeline files only need one import:
|
|
794
|
-
|
|
795
|
-
\`\`\`typescript
|
|
796
|
-
// _.ts
|
|
797
|
-
export * from "@intentius/chant-lexicon-gitlab";
|
|
798
|
-
export * from "./config";
|
|
799
|
-
\`\`\`
|
|
800
|
-
|
|
801
460
|
### Shared configuration
|
|
802
461
|
|
|
803
462
|
\`config.ts\` extracts reusable objects — images, caches, artifacts, rules, and environments — so jobs stay concise:
|
|
804
463
|
|
|
805
|
-
|
|
806
|
-
// config.ts
|
|
807
|
-
import * as _ from "./_";
|
|
808
|
-
|
|
809
|
-
export const nodeImage = new _.Image({ name: "node:20-alpine" });
|
|
810
|
-
|
|
811
|
-
export const npmCache = new _.Cache({
|
|
812
|
-
key: "$CI_COMMIT_REF_SLUG",
|
|
813
|
-
paths: ["node_modules/"],
|
|
814
|
-
policy: "pull-push",
|
|
815
|
-
});
|
|
816
|
-
|
|
817
|
-
export const buildArtifacts = new _.Artifacts({
|
|
818
|
-
paths: ["dist/"],
|
|
819
|
-
expireIn: "1 hour",
|
|
820
|
-
});
|
|
821
|
-
|
|
822
|
-
export const testArtifacts = new _.Artifacts({
|
|
823
|
-
paths: ["coverage/"],
|
|
824
|
-
expireIn: "1 week",
|
|
825
|
-
reports: { junit: "coverage/junit.xml" },
|
|
826
|
-
});
|
|
827
|
-
|
|
828
|
-
export const onMergeRequest = new _.Rule({
|
|
829
|
-
ifCondition: _.CI.MergeRequestIid,
|
|
830
|
-
});
|
|
831
|
-
|
|
832
|
-
export const onCommit = new _.Rule({
|
|
833
|
-
ifCondition: _.CI.CommitBranch,
|
|
834
|
-
});
|
|
835
|
-
|
|
836
|
-
export const onDefaultBranch = new _.Rule({
|
|
837
|
-
ifCondition: \`\${_.CI.CommitBranch} == \${_.CI.DefaultBranch}\`,
|
|
838
|
-
when: "manual",
|
|
839
|
-
});
|
|
840
|
-
|
|
841
|
-
export const productionEnv = new _.Environment({
|
|
842
|
-
name: "production",
|
|
843
|
-
url: "https://example.com",
|
|
844
|
-
});
|
|
845
|
-
\`\`\`
|
|
464
|
+
{{file:getting-started/src/config.ts}}
|
|
846
465
|
|
|
847
466
|
### Pipeline jobs
|
|
848
467
|
|
|
849
|
-
\`pipeline.ts\` defines three jobs that
|
|
468
|
+
\`pipeline.ts\` defines three jobs that import shared config directly:
|
|
850
469
|
|
|
851
|
-
|
|
852
|
-
// pipeline.ts
|
|
853
|
-
import * as _ from "./_";
|
|
854
|
-
|
|
855
|
-
export const build = new _.Job({
|
|
856
|
-
stage: "build",
|
|
857
|
-
image: _.nodeImage,
|
|
858
|
-
cache: _.npmCache,
|
|
859
|
-
script: ["npm ci", "npm run build"],
|
|
860
|
-
artifacts: _.buildArtifacts,
|
|
861
|
-
});
|
|
862
|
-
|
|
863
|
-
export const test = new _.Job({
|
|
864
|
-
stage: "test",
|
|
865
|
-
image: _.nodeImage,
|
|
866
|
-
cache: _.npmCache,
|
|
867
|
-
script: ["npm ci", "npm test"],
|
|
868
|
-
artifacts: _.testArtifacts,
|
|
869
|
-
rules: [_.onMergeRequest, _.onCommit],
|
|
870
|
-
});
|
|
871
|
-
|
|
872
|
-
export const deploy = new _.Job({
|
|
873
|
-
stage: "deploy",
|
|
874
|
-
image: _.nodeImage,
|
|
875
|
-
script: ["npm run deploy"],
|
|
876
|
-
environment: _.productionEnv,
|
|
877
|
-
rules: [_.onDefaultBranch],
|
|
878
|
-
});
|
|
879
|
-
\`\`\`
|
|
470
|
+
{{file:getting-started/src/pipeline.ts}}
|
|
880
471
|
|
|
881
472
|
### Generated output
|
|
882
473
|
|
|
@@ -947,6 +538,61 @@ deploy:
|
|
|
947
538
|
5. **JUnit reports** — test artifacts include JUnit XML for GitLab MR display
|
|
948
539
|
`,
|
|
949
540
|
},
|
|
541
|
+
{
|
|
542
|
+
slug: "skills",
|
|
543
|
+
title: "AI Skills",
|
|
544
|
+
description: "AI agent skills bundled with the GitLab CI/CD lexicon",
|
|
545
|
+
content: `The GitLab lexicon ships an AI skill called **chant-gitlab** that teaches AI coding agents (like Claude Code) how to build, validate, and deploy GitLab CI pipelines from a chant project.
|
|
546
|
+
|
|
547
|
+
## What are skills?
|
|
548
|
+
|
|
549
|
+
Skills are structured markdown documents bundled with a lexicon. When an AI agent works in a chant project, it discovers and loads relevant skills automatically — giving it operational knowledge about the deployment workflow without requiring the user to explain each step.
|
|
550
|
+
|
|
551
|
+
## Installation
|
|
552
|
+
|
|
553
|
+
When you scaffold a new project with \`chant init --lexicon gitlab\`, the skill is installed to \`.claude/skills/chant-gitlab/SKILL.md\` for automatic discovery by Claude Code.
|
|
554
|
+
|
|
555
|
+
For existing projects, create the file manually:
|
|
556
|
+
|
|
557
|
+
\`\`\`
|
|
558
|
+
.claude/
|
|
559
|
+
skills/
|
|
560
|
+
chant-gitlab/
|
|
561
|
+
SKILL.md # skill content (see below)
|
|
562
|
+
\`\`\`
|
|
563
|
+
|
|
564
|
+
## Skill: chant-gitlab
|
|
565
|
+
|
|
566
|
+
The \`chant-gitlab\` skill covers the full deployment lifecycle:
|
|
567
|
+
|
|
568
|
+
- **Build** — \`chant build src/ --output .gitlab-ci.yml\`
|
|
569
|
+
- **Validate** — \`chant lint src/\` + GitLab CI Lint API
|
|
570
|
+
- **Deploy** — commit and push the generated YAML
|
|
571
|
+
- **Status** — GitLab UI or pipelines API
|
|
572
|
+
- **Retry** — retry failed jobs via UI or API
|
|
573
|
+
- **Cancel** — cancel running pipelines via API
|
|
574
|
+
- **Troubleshooting** — job logs, lint rule codes (WGL001–WGL004), post-synth checks (WGL010, WGL011)
|
|
575
|
+
|
|
576
|
+
The skill is invocable as a slash command: \`/chant-gitlab\`
|
|
577
|
+
|
|
578
|
+
## MCP integration
|
|
579
|
+
|
|
580
|
+
The lexicon also provides MCP (Model Context Protocol) tools and resources that AI agents can use programmatically:
|
|
581
|
+
|
|
582
|
+
| MCP tool | Description |
|
|
583
|
+
|----------|-------------|
|
|
584
|
+
| \`build\` | Build the chant project |
|
|
585
|
+
| \`lint\` | Run lint rules |
|
|
586
|
+
| \`explain\` | Summarize project resources |
|
|
587
|
+
| \`scaffold\` | Generate starter files |
|
|
588
|
+
| \`search\` | Search available resource types |
|
|
589
|
+
| \`gitlab:diff\` | Compare current build output against previous |
|
|
590
|
+
|
|
591
|
+
| MCP resource | Description |
|
|
592
|
+
|--------------|-------------|
|
|
593
|
+
| \`resource-catalog\` | JSON list of all supported GitLab CI entity types |
|
|
594
|
+
| \`examples/basic-pipeline\` | Example pipeline with build, test, and deploy jobs |`,
|
|
595
|
+
},
|
|
950
596
|
],
|
|
951
597
|
basePath: "/chant/lexicons/gitlab/",
|
|
952
598
|
};
|