@intentius/chant-lexicon-github 0.44.14 → 0.45.0
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/codegen/docs.d.ts.map +1 -1
- package/dist/integrity.json +2 -2
- package/dist/manifest.json +1 -1
- package/package.json +2 -2
- package/src/codegen/docs.ts +0 -1308
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8EH;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/codegen/docs.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8EH;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B9E"}
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "e30d7f473b8a2e2f5043a3cb45b1904b7a3863a8a114d534e0fe87147352f632",
|
|
5
5
|
"meta.json": "798c5f5f37b0174756d2451299acfdc95c014f11d06d32b9153bbdfa9f3a580c",
|
|
6
6
|
"types/index.d.ts": "39c0791f0e58025bcef82e0f7a92240508f899fc2771d5dd51b2369b4d330f13",
|
|
7
7
|
"rules/deprecated-action-version.ts": "d41e6e532ab7f623af1bee4ac5279fcb2baada7defa1c5d022a5bc71983e8797",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"skills/chant-github-patterns.md": "bb3abef289a8fdfcf07d6bb2d7289dcb2f38bc0cb0321ea320b78b45a6f548c0",
|
|
68
68
|
"skills/chant-github-security.md": "aab111cb0871cad30281ce48d7da23663689619351029219e2be019a1a61e394"
|
|
69
69
|
},
|
|
70
|
-
"composite": "
|
|
70
|
+
"composite": "77a265cdec5d2163e1ce49b12ef260aaa7e23b3d8989fcb6de23a90ce9612227"
|
|
71
71
|
}
|
package/dist/manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"description": "GitHub Actions lexicon for chant — declarative IaC in TypeScript",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://intentius.io/chant",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"typescript": "^5.9.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@intentius/chant": "^0.
|
|
64
|
+
"@intentius/chant": "^0.45.0",
|
|
65
65
|
"typescript": "^5.9.3"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/src/codegen/docs.ts
CHANGED
|
@@ -101,1315 +101,7 @@ export async function generateDocs(opts?: { verbose?: boolean }): Promise<void>
|
|
|
101
101
|
content: `The GitLab lexicon ships a typed-compiler migration tool that translates \`.github/workflows/*.yml\` into \`.gitlab-ci.yml\` (or chant TypeScript) with provenance, 33 curated marketplace-action mappings, and optional composite recognition. See [GitLab → Migration from GitHub Actions](/chant/lexicons/gitlab/migration/) or the [\`chant migrate\` CLI reference](/chant/cli/migrate/).`,
|
|
102
102
|
},
|
|
103
103
|
],
|
|
104
|
-
extraPages: [
|
|
105
|
-
{
|
|
106
|
-
slug: "getting-started",
|
|
107
|
-
title: "Getting Started",
|
|
108
|
-
description: "Step-by-step guide to building your first GitHub Actions workflow with chant",
|
|
109
|
-
content: `## 1. Install
|
|
110
|
-
|
|
111
|
-
\`\`\`bash
|
|
112
|
-
mkdir my-project && cd my-project
|
|
113
|
-
npm init -y
|
|
114
|
-
npm install --save-dev @intentius/chant @intentius/chant-lexicon-github typescript
|
|
115
|
-
\`\`\`
|
|
116
|
-
|
|
117
|
-
## 2. Create your workflow
|
|
118
|
-
|
|
119
|
-
Create \`src/ci.ts\`:
|
|
120
|
-
|
|
121
|
-
{{file:docs-snippets/src/quickstart.ts}}
|
|
122
|
-
|
|
123
|
-
## 3. Build
|
|
124
|
-
|
|
125
|
-
\`\`\`bash
|
|
126
|
-
chant build src/ --output .github/workflows/ci.yml
|
|
127
|
-
\`\`\`
|
|
128
|
-
|
|
129
|
-
This produces \`.github/workflows/ci.yml\`:
|
|
130
|
-
|
|
131
|
-
\`\`\`yaml
|
|
132
|
-
name: CI
|
|
133
|
-
on:
|
|
134
|
-
push:
|
|
135
|
-
branches:
|
|
136
|
-
- main
|
|
137
|
-
pull_request:
|
|
138
|
-
branches:
|
|
139
|
-
- main
|
|
140
|
-
permissions:
|
|
141
|
-
contents: read
|
|
142
|
-
jobs:
|
|
143
|
-
build:
|
|
144
|
-
runs-on: ubuntu-latest
|
|
145
|
-
timeout-minutes: 15
|
|
146
|
-
steps:
|
|
147
|
-
- name: Checkout
|
|
148
|
-
uses: actions/checkout@v4
|
|
149
|
-
- name: Setup Node.js
|
|
150
|
-
uses: actions/setup-node@v4
|
|
151
|
-
with:
|
|
152
|
-
node-version: '22'
|
|
153
|
-
cache: npm
|
|
154
|
-
- name: Install
|
|
155
|
-
run: npm ci
|
|
156
|
-
- name: Build
|
|
157
|
-
run: npm run build
|
|
158
|
-
- name: Test
|
|
159
|
-
run: npm test
|
|
160
|
-
\`\`\`
|
|
161
|
-
|
|
162
|
-
## 4. Lint
|
|
163
|
-
|
|
164
|
-
\`\`\`bash
|
|
165
|
-
chant lint src/
|
|
166
|
-
\`\`\`
|
|
167
|
-
|
|
168
|
-
Lint checks for common issues — missing timeouts, hardcoded secrets, raw expression strings, and more. See the [Lint Rules](/chant/lexicons/github/lint-rules/) page for the full list.
|
|
169
|
-
|
|
170
|
-
## 5. Deploy
|
|
171
|
-
|
|
172
|
-
Commit the generated YAML and push:
|
|
173
|
-
|
|
174
|
-
\`\`\`bash
|
|
175
|
-
git add .github/workflows/ci.yml
|
|
176
|
-
git commit -m "Add CI workflow"
|
|
177
|
-
git push
|
|
178
|
-
\`\`\`
|
|
179
|
-
|
|
180
|
-
GitHub automatically picks up any \`.github/workflows/*.yml\` files and runs them on the configured triggers.
|
|
181
|
-
|
|
182
|
-
## Next steps
|
|
183
|
-
|
|
184
|
-
- [Workflow Concepts](/chant/lexicons/github/workflow-concepts/) — resource types, triggers, permissions
|
|
185
|
-
- [Expressions](/chant/lexicons/github/expressions/) — typed expression system and condition helpers
|
|
186
|
-
- [Composites](/chant/lexicons/github/composites/) — pre-built action wrappers (Checkout, SetupNode, etc.)
|
|
187
|
-
- [Lint Rules](/chant/lexicons/github/lint-rules/) — 13 lint rules and 45 post-synth checks`,
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
slug: "workflow-concepts",
|
|
191
|
-
title: "Workflow Concepts",
|
|
192
|
-
description: "Resource types, triggers, jobs, steps, permissions, and strategy in the GitHub Actions lexicon",
|
|
193
|
-
content: `## Resource types
|
|
194
|
-
|
|
195
|
-
The lexicon provides 2 resource types and several property types:
|
|
196
|
-
|
|
197
|
-
### Resources
|
|
198
|
-
|
|
199
|
-
| Type | Description |
|
|
200
|
-
|------|-------------|
|
|
201
|
-
| \`Workflow\` | Top-level workflow configuration — name, triggers, permissions, concurrency |
|
|
202
|
-
| \`Job\` | A job within a workflow — runs-on, steps, strategy, needs, outputs |
|
|
203
|
-
|
|
204
|
-
### Property types
|
|
205
|
-
|
|
206
|
-
| Type | Used in | Description |
|
|
207
|
-
|------|---------|-------------|
|
|
208
|
-
| \`Step\` | Job | A single step — run command or action usage |
|
|
209
|
-
| \`Strategy\` | Job | Matrix strategy for parallel job execution |
|
|
210
|
-
| \`Permissions\` | Workflow, Job | GITHUB_TOKEN permission scopes |
|
|
211
|
-
| \`Concurrency\` | Workflow, Job | Concurrency group and cancel-in-progress settings |
|
|
212
|
-
| \`PushTrigger\` | Workflow (on) | Push event trigger with branch/tag/path filters |
|
|
213
|
-
| \`PullRequestTrigger\` | Workflow (on) | Pull request event trigger with filters |
|
|
214
|
-
| \`ScheduleTrigger\` | Workflow (on) | Cron-based schedule trigger |
|
|
215
|
-
| \`WorkflowDispatchTrigger\` | Workflow (on) | Manual dispatch with typed inputs |
|
|
216
|
-
| \`Environment\` | Job | Deployment environment with protection rules |
|
|
217
|
-
| \`Output\` | Job | Job output values for downstream jobs |
|
|
218
|
-
|
|
219
|
-
## Triggers
|
|
220
|
-
|
|
221
|
-
Triggers define when a workflow runs. Pass them in the \`on:\` field:
|
|
222
|
-
|
|
223
|
-
\`\`\`typescript
|
|
224
|
-
import { Workflow } from "@intentius/chant-lexicon-github";
|
|
225
|
-
|
|
226
|
-
export const workflow = new Workflow({
|
|
227
|
-
name: "CI",
|
|
228
|
-
on: {
|
|
229
|
-
push: { branches: ["main", "release/*"] },
|
|
230
|
-
pull_request: {
|
|
231
|
-
branches: ["main"],
|
|
232
|
-
types: ["opened", "synchronize"],
|
|
233
|
-
},
|
|
234
|
-
schedule: [{ cron: "0 0 * * 1" }], // Weekly on Monday
|
|
235
|
-
workflow_dispatch: { // Manual trigger
|
|
236
|
-
inputs: {
|
|
237
|
-
environment: {
|
|
238
|
-
description: "Deploy target",
|
|
239
|
-
required: true,
|
|
240
|
-
type: "choice",
|
|
241
|
-
options: ["staging", "production"],
|
|
242
|
-
},
|
|
243
|
-
},
|
|
244
|
-
},
|
|
245
|
-
},
|
|
246
|
-
});
|
|
247
|
-
\`\`\`
|
|
248
|
-
|
|
249
|
-
## Jobs and steps
|
|
250
|
-
|
|
251
|
-
Each exported \`Job\` becomes a job entry under \`jobs:\`. Steps run sequentially within a job:
|
|
252
|
-
|
|
253
|
-
\`\`\`typescript
|
|
254
|
-
import { Job, Step, Checkout, SetupNode } from "@intentius/chant-lexicon-github";
|
|
255
|
-
|
|
256
|
-
export const test = new Job({
|
|
257
|
-
"runs-on": "ubuntu-latest",
|
|
258
|
-
timeoutMinutes: 10,
|
|
259
|
-
steps: [
|
|
260
|
-
Checkout({}).step,
|
|
261
|
-
SetupNode({ nodeVersion: "22", cache: "npm" }).step,
|
|
262
|
-
new Step({ name: "Install", run: "npm ci" }),
|
|
263
|
-
new Step({ name: "Test", run: "npm test" }),
|
|
264
|
-
],
|
|
265
|
-
});
|
|
266
|
-
\`\`\`
|
|
267
|
-
|
|
268
|
-
Key job properties:
|
|
269
|
-
- \`runs-on\` — **required**. Runner label (\`ubuntu-latest\`, \`macos-latest\`, \`windows-latest\`).
|
|
270
|
-
- \`steps\` — **required**. Array of \`Step\` objects.
|
|
271
|
-
- \`timeoutMinutes\` — maximum job duration (recommended, flagged by GHA014 if missing).
|
|
272
|
-
- \`needs\` — job dependencies for execution ordering.
|
|
273
|
-
- \`if\` — conditional execution using Expressions.
|
|
274
|
-
- \`strategy\` — matrix builds for parallel execution.
|
|
275
|
-
|
|
276
|
-
## Matrix strategy
|
|
277
|
-
|
|
278
|
-
Run a job across multiple configurations:
|
|
279
|
-
|
|
280
|
-
\`\`\`typescript
|
|
281
|
-
import { Job, Step, Checkout, SetupNode } from "@intentius/chant-lexicon-github";
|
|
282
|
-
|
|
283
|
-
export const test = new Job({
|
|
284
|
-
"runs-on": "ubuntu-latest",
|
|
285
|
-
strategy: {
|
|
286
|
-
matrix: {
|
|
287
|
-
"node-version": ["18", "20", "22"],
|
|
288
|
-
os: ["ubuntu-latest", "macos-latest"],
|
|
289
|
-
},
|
|
290
|
-
"fail-fast": false,
|
|
291
|
-
},
|
|
292
|
-
steps: [
|
|
293
|
-
Checkout({}).step,
|
|
294
|
-
SetupNode({ nodeVersion: "\${{ matrix.node-version }}", cache: "npm" }).step,
|
|
295
|
-
new Step({ name: "Test", run: "npm test" }),
|
|
296
|
-
],
|
|
297
|
-
});
|
|
298
|
-
\`\`\`
|
|
299
|
-
|
|
300
|
-
## Permissions
|
|
301
|
-
|
|
302
|
-
Control GITHUB_TOKEN permissions at the workflow or job level:
|
|
303
|
-
|
|
304
|
-
\`\`\`typescript
|
|
305
|
-
import { Workflow, Job, Step } from "@intentius/chant-lexicon-github";
|
|
306
|
-
|
|
307
|
-
// Workflow-level (applies to all jobs)
|
|
308
|
-
export const workflow = new Workflow({
|
|
309
|
-
name: "Release",
|
|
310
|
-
on: { push: { tags: ["v*"] } },
|
|
311
|
-
permissions: {
|
|
312
|
-
contents: "write",
|
|
313
|
-
packages: "write",
|
|
314
|
-
"id-token": "write",
|
|
315
|
-
},
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
// Job-level (overrides workflow permissions for this job)
|
|
319
|
-
export const publish = new Job({
|
|
320
|
-
"runs-on": "ubuntu-latest",
|
|
321
|
-
permissions: { contents: "read", packages: "write" },
|
|
322
|
-
steps: [
|
|
323
|
-
new Step({ name: "Publish", run: "npm publish" }),
|
|
324
|
-
],
|
|
325
|
-
});
|
|
326
|
-
\`\`\`
|
|
327
|
-
|
|
328
|
-
Available permission scopes: \`actions\`, \`checks\`, \`contents\`, \`deployments\`, \`id-token\`, \`issues\`, \`packages\`, \`pages\`, \`pull-requests\`, \`repository-projects\`, \`security-events\`, \`statuses\`. Values: \`"read"\`, \`"write"\`, \`"none"\`.
|
|
329
|
-
|
|
330
|
-
## Concurrency
|
|
331
|
-
|
|
332
|
-
Prevent concurrent runs of the same workflow or job:
|
|
333
|
-
|
|
334
|
-
\`\`\`typescript
|
|
335
|
-
import { Workflow } from "@intentius/chant-lexicon-github";
|
|
336
|
-
|
|
337
|
-
export const workflow = new Workflow({
|
|
338
|
-
name: "Deploy",
|
|
339
|
-
on: { push: { branches: ["main"] } },
|
|
340
|
-
concurrency: {
|
|
341
|
-
group: "deploy-\${{ github.ref }}",
|
|
342
|
-
"cancel-in-progress": true,
|
|
343
|
-
},
|
|
344
|
-
});
|
|
345
|
-
\`\`\`
|
|
346
|
-
|
|
347
|
-
## Job dependencies
|
|
348
|
-
|
|
349
|
-
Use \`needs\` to order jobs and pass outputs between them:
|
|
350
|
-
|
|
351
|
-
\`\`\`typescript
|
|
352
|
-
import { Job, Step } from "@intentius/chant-lexicon-github";
|
|
353
|
-
|
|
354
|
-
export const build = new Job({
|
|
355
|
-
"runs-on": "ubuntu-latest",
|
|
356
|
-
outputs: { version: "\${{ steps.version.outputs.value }}" },
|
|
357
|
-
steps: [
|
|
358
|
-
new Step({
|
|
359
|
-
id: "version",
|
|
360
|
-
name: "Get version",
|
|
361
|
-
run: 'echo "value=$(node -p \\"require(\'./package.json\').version\\")" >> $GITHUB_OUTPUT',
|
|
362
|
-
}),
|
|
363
|
-
],
|
|
364
|
-
});
|
|
365
|
-
|
|
366
|
-
export const deploy = new Job({
|
|
367
|
-
"runs-on": "ubuntu-latest",
|
|
368
|
-
needs: ["build"],
|
|
369
|
-
steps: [
|
|
370
|
-
new Step({
|
|
371
|
-
name: "Deploy",
|
|
372
|
-
run: "echo Deploying version \${{ needs.build.outputs.version }}",
|
|
373
|
-
}),
|
|
374
|
-
],
|
|
375
|
-
});
|
|
376
|
-
\`\`\``,
|
|
377
|
-
},
|
|
378
|
-
{
|
|
379
|
-
slug: "expressions",
|
|
380
|
-
title: "Expressions",
|
|
381
|
-
description: "Typed expression system, condition helpers, and utility functions for GitHub Actions",
|
|
382
|
-
content: `The Expression system provides type-safe access to GitHub Actions \`\${{ }}\` expressions. Instead of writing raw strings, use the typed helpers for better IDE support and lint coverage.
|
|
383
|
-
|
|
384
|
-
{{file:docs-snippets/src/expressions-usage.ts}}
|
|
385
|
-
|
|
386
|
-
## Expression class
|
|
387
|
-
|
|
388
|
-
The \`Expression\` class wraps a raw expression string and provides operator methods:
|
|
389
|
-
|
|
390
|
-
| Method | Example | Result |
|
|
391
|
-
|--------|---------|--------|
|
|
392
|
-
| \`.and(other)\` | \`github.ref.eq("refs/heads/main").and(isPR)\` | \`\${{ github.ref == 'refs/heads/main' && ... }}\` |
|
|
393
|
-
| \`.or(other)\` | \`isMain.or(isDev)\` | \`\${{ ... \\|\\| ... }}\` |
|
|
394
|
-
| \`.not()\` | \`isPR.not()\` | \`\${{ !(...) }}\` |
|
|
395
|
-
| \`.eq(value)\` | \`github.ref.eq("refs/heads/main")\` | \`\${{ github.ref == 'refs/heads/main' }}\` |
|
|
396
|
-
| \`.ne(value)\` | \`github.eventName.ne("schedule")\` | \`\${{ github.event_name != 'schedule' }}\` |
|
|
397
|
-
|
|
398
|
-
## Context accessors
|
|
399
|
-
|
|
400
|
-
The \`github\` and \`runner\` objects provide typed access to context properties:
|
|
401
|
-
|
|
402
|
-
\`\`\`typescript
|
|
403
|
-
import { github, runner } from "@intentius/chant-lexicon-github";
|
|
404
|
-
|
|
405
|
-
github.ref // \${{ github.ref }}
|
|
406
|
-
github.sha // \${{ github.sha }}
|
|
407
|
-
github.actor // \${{ github.actor }}
|
|
408
|
-
runner.os // \${{ runner.os }}
|
|
409
|
-
runner.arch // \${{ runner.arch }}
|
|
410
|
-
\`\`\`
|
|
411
|
-
|
|
412
|
-
See [Variables](/chant/lexicons/github/variables/) for the full reference table.
|
|
413
|
-
|
|
414
|
-
## Dynamic context accessors
|
|
415
|
-
|
|
416
|
-
Access dynamic context values — secrets, matrix, step outputs, job outputs, inputs, vars, env:
|
|
417
|
-
|
|
418
|
-
\`\`\`typescript
|
|
419
|
-
import { secrets, matrix, steps, needs, inputs, vars, env } from "@intentius/chant-lexicon-github";
|
|
420
|
-
|
|
421
|
-
secrets("NPM_TOKEN") // \${{ secrets.NPM_TOKEN }}
|
|
422
|
-
matrix("node-version") // \${{ matrix.node-version }}
|
|
423
|
-
steps("build").outputs("path") // \${{ steps.build.outputs.path }}
|
|
424
|
-
needs("build").outputs("version") // \${{ needs.build.outputs.version }}
|
|
425
|
-
inputs("environment") // \${{ inputs.environment }}
|
|
426
|
-
vars("API_URL") // \${{ vars.API_URL }}
|
|
427
|
-
env("NODE_ENV") // \${{ env.NODE_ENV }}
|
|
428
|
-
\`\`\`
|
|
429
|
-
|
|
430
|
-
## Condition helpers
|
|
431
|
-
|
|
432
|
-
Status check functions for job and step \`if:\` fields:
|
|
433
|
-
|
|
434
|
-
| Function | Expression | Description |
|
|
435
|
-
|----------|-----------|-------------|
|
|
436
|
-
| \`always()\` | \`\${{ always() }}\` | Always run, regardless of status |
|
|
437
|
-
| \`failure()\` | \`\${{ failure() }}\` | Run only if a previous step failed |
|
|
438
|
-
| \`success()\` | \`\${{ success() }}\` | Run only if all previous steps succeeded (default) |
|
|
439
|
-
| \`cancelled()\` | \`\${{ cancelled() }}\` | Run only if the workflow was cancelled |
|
|
440
|
-
|
|
441
|
-
Use them in \`if:\` conditions:
|
|
442
|
-
|
|
443
|
-
\`\`\`typescript
|
|
444
|
-
import { Job, Step, failure, always } from "@intentius/chant-lexicon-github";
|
|
445
|
-
|
|
446
|
-
export const test = new Job({
|
|
447
|
-
"runs-on": "ubuntu-latest",
|
|
448
|
-
steps: [
|
|
449
|
-
new Step({ name: "Test", run: "npm test" }),
|
|
450
|
-
new Step({
|
|
451
|
-
name: "Upload coverage",
|
|
452
|
-
if: always(),
|
|
453
|
-
run: "npx codecov",
|
|
454
|
-
}),
|
|
455
|
-
new Step({
|
|
456
|
-
name: "Notify failure",
|
|
457
|
-
if: failure(),
|
|
458
|
-
run: "curl -X POST $SLACK_WEBHOOK",
|
|
459
|
-
}),
|
|
460
|
-
],
|
|
461
|
-
});
|
|
462
|
-
\`\`\`
|
|
463
|
-
|
|
464
|
-
## Function helpers
|
|
465
|
-
|
|
466
|
-
Utility functions that produce expression strings:
|
|
467
|
-
|
|
468
|
-
| Function | Example | Expression |
|
|
469
|
-
|----------|---------|-----------|
|
|
470
|
-
| \`contains(haystack, needle)\` | \`contains(github.event, "bug")\` | \`\${{ contains(github.event, 'bug') }}\` |
|
|
471
|
-
| \`startsWith(value, prefix)\` | \`startsWith(github.ref, "refs/tags/")\` | \`\${{ startsWith(github.ref, 'refs/tags/') }}\` |
|
|
472
|
-
| \`toJSON(value)\` | \`toJSON(github.event)\` | \`\${{ toJSON(github.event) }}\` |
|
|
473
|
-
| \`fromJSON(json)\` | \`fromJSON(steps("meta").outputs("matrix"))\` | \`\${{ fromJSON(steps.meta.outputs.matrix) }}\` |
|
|
474
|
-
| \`format(template, ...args)\` | \`format("v{0}.{1}", major, minor)\` | \`\${{ format('v{0}.{1}', ...) }}\` |
|
|
475
|
-
|
|
476
|
-
## Convenience helpers
|
|
477
|
-
|
|
478
|
-
Shorthand functions for common checks:
|
|
479
|
-
|
|
480
|
-
\`\`\`typescript
|
|
481
|
-
import { branch, tag } from "@intentius/chant-lexicon-github";
|
|
482
|
-
|
|
483
|
-
branch("main") // github.ref == 'refs/heads/main'
|
|
484
|
-
tag("v1") // startsWith(github.ref, 'refs/tags/v1')
|
|
485
|
-
\`\`\`
|
|
486
|
-
|
|
487
|
-
These are useful in job \`if:\` conditions:
|
|
488
|
-
|
|
489
|
-
\`\`\`typescript
|
|
490
|
-
import { Job, Step, branch } from "@intentius/chant-lexicon-github";
|
|
491
|
-
|
|
492
|
-
export const deploy = new Job({
|
|
493
|
-
"runs-on": "ubuntu-latest",
|
|
494
|
-
if: branch("main"),
|
|
495
|
-
steps: [
|
|
496
|
-
new Step({ name: "Deploy", run: "npm run deploy" }),
|
|
497
|
-
],
|
|
498
|
-
});
|
|
499
|
-
\`\`\``,
|
|
500
|
-
},
|
|
501
|
-
{
|
|
502
|
-
slug: "variables",
|
|
503
|
-
title: "Variables",
|
|
504
|
-
description: "GitHub and Runner context variable references for GitHub Actions workflows",
|
|
505
|
-
content: `The \`GitHub\` and \`Runner\` objects provide type-safe access to GitHub Actions context variables. These expand to \`\${{ github.* }}\` and \`\${{ runner.* }}\` expressions in the generated YAML.
|
|
506
|
-
|
|
507
|
-
{{file:docs-snippets/src/variables-usage.ts}}
|
|
508
|
-
|
|
509
|
-
## GitHub context
|
|
510
|
-
|
|
511
|
-
| Property | Expression | Description |
|
|
512
|
-
|----------|-----------|-------------|
|
|
513
|
-
| \`GitHub.Ref\` | \`\${{ github.ref }}\` | Full ref (e.g. \`refs/heads/main\`, \`refs/tags/v1.0\`) |
|
|
514
|
-
| \`GitHub.RefName\` | \`\${{ github.ref_name }}\` | Short ref name (e.g. \`main\`, \`v1.0\`) |
|
|
515
|
-
| \`GitHub.RefType\` | \`\${{ github.ref_type }}\` | Ref type: \`branch\` or \`tag\` |
|
|
516
|
-
| \`GitHub.Sha\` | \`\${{ github.sha }}\` | Full commit SHA |
|
|
517
|
-
| \`GitHub.Actor\` | \`\${{ github.actor }}\` | Username that triggered the workflow |
|
|
518
|
-
| \`GitHub.TriggeringActor\` | \`\${{ github.triggering_actor }}\` | Username that triggered the workflow run |
|
|
519
|
-
| \`GitHub.Repository\` | \`\${{ github.repository }}\` | Owner/repo (e.g. \`octocat/hello-world\`) |
|
|
520
|
-
| \`GitHub.RepositoryOwner\` | \`\${{ github.repository_owner }}\` | Repository owner (e.g. \`octocat\`) |
|
|
521
|
-
| \`GitHub.EventName\` | \`\${{ github.event_name }}\` | Triggering event name (\`push\`, \`pull_request\`, etc.) |
|
|
522
|
-
| \`GitHub.Event\` | \`\${{ github.event }}\` | Full event payload object |
|
|
523
|
-
| \`GitHub.RunId\` | \`\${{ github.run_id }}\` | Unique run ID |
|
|
524
|
-
| \`GitHub.RunNumber\` | \`\${{ github.run_number }}\` | Run number for this workflow |
|
|
525
|
-
| \`GitHub.RunAttempt\` | \`\${{ github.run_attempt }}\` | Attempt number for this run |
|
|
526
|
-
| \`GitHub.Workflow\` | \`\${{ github.workflow }}\` | Workflow name |
|
|
527
|
-
| \`GitHub.WorkflowRef\` | \`\${{ github.workflow_ref }}\` | Workflow ref path |
|
|
528
|
-
| \`GitHub.Workspace\` | \`\${{ github.workspace }}\` | Default working directory on the runner |
|
|
529
|
-
| \`GitHub.Token\` | \`\${{ github.token }}\` | Automatically-generated GITHUB_TOKEN |
|
|
530
|
-
| \`GitHub.Job\` | \`\${{ github.job }}\` | Current job ID |
|
|
531
|
-
| \`GitHub.HeadRef\` | \`\${{ github.head_ref }}\` | PR head branch (pull_request events only) |
|
|
532
|
-
| \`GitHub.BaseRef\` | \`\${{ github.base_ref }}\` | PR base branch (pull_request events only) |
|
|
533
|
-
| \`GitHub.ServerUrl\` | \`\${{ github.server_url }}\` | GitHub server URL |
|
|
534
|
-
| \`GitHub.ApiUrl\` | \`\${{ github.api_url }}\` | GitHub API URL |
|
|
535
|
-
| \`GitHub.GraphqlUrl\` | \`\${{ github.graphql_url }}\` | GitHub GraphQL API URL |
|
|
536
|
-
| \`GitHub.Action\` | \`\${{ github.action }}\` | Action name or step ID |
|
|
537
|
-
| \`GitHub.ActionPath\` | \`\${{ github.action_path }}\` | Path where the action is located |
|
|
538
|
-
|
|
539
|
-
## Runner context
|
|
540
|
-
|
|
541
|
-
| Property | Expression | Description |
|
|
542
|
-
|----------|-----------|-------------|
|
|
543
|
-
| \`Runner.Os\` | \`\${{ runner.os }}\` | Runner operating system (\`Linux\`, \`Windows\`, \`macOS\`) |
|
|
544
|
-
| \`Runner.Arch\` | \`\${{ runner.arch }}\` | Runner architecture (\`X86\`, \`X64\`, \`ARM\`, \`ARM64\`) |
|
|
545
|
-
| \`Runner.Name\` | \`\${{ runner.name }}\` | Runner name |
|
|
546
|
-
| \`Runner.Temp\` | \`\${{ runner.temp }}\` | Path to a temporary directory on the runner |
|
|
547
|
-
| \`Runner.ToolCache\` | \`\${{ runner.tool_cache }}\` | Path to the tool cache directory |
|
|
548
|
-
|
|
549
|
-
## Common patterns
|
|
550
|
-
|
|
551
|
-
### Branch checks
|
|
552
|
-
|
|
553
|
-
\`\`\`typescript
|
|
554
|
-
import { Job, Step, GitHub } from "@intentius/chant-lexicon-github";
|
|
555
|
-
import { branch } from "@intentius/chant-lexicon-github";
|
|
556
|
-
|
|
557
|
-
// Deploy only on main
|
|
558
|
-
export const deploy = new Job({
|
|
559
|
-
"runs-on": "ubuntu-latest",
|
|
560
|
-
if: branch("main"),
|
|
561
|
-
steps: [
|
|
562
|
-
new Step({ name: "Deploy", run: "npm run deploy" }),
|
|
563
|
-
],
|
|
564
|
-
});
|
|
565
|
-
\`\`\`
|
|
566
|
-
|
|
567
|
-
### Event filtering
|
|
568
|
-
|
|
569
|
-
\`\`\`typescript
|
|
570
|
-
import { Job, Step, GitHub } from "@intentius/chant-lexicon-github";
|
|
571
|
-
import { github } from "@intentius/chant-lexicon-github";
|
|
572
|
-
|
|
573
|
-
// Skip scheduled runs
|
|
574
|
-
export const test = new Job({
|
|
575
|
-
"runs-on": "ubuntu-latest",
|
|
576
|
-
if: github.eventName.ne("schedule"),
|
|
577
|
-
steps: [
|
|
578
|
-
new Step({ name: "Test", run: "npm test" }),
|
|
579
|
-
],
|
|
580
|
-
});
|
|
581
|
-
\`\`\`
|
|
582
|
-
|
|
583
|
-
### Runner-specific logic
|
|
584
|
-
|
|
585
|
-
\`\`\`typescript
|
|
586
|
-
import { Job, Step, runner } from "@intentius/chant-lexicon-github";
|
|
587
|
-
|
|
588
|
-
export const build = new Job({
|
|
589
|
-
"runs-on": "ubuntu-latest",
|
|
590
|
-
steps: [
|
|
591
|
-
new Step({
|
|
592
|
-
name: "Platform-specific setup",
|
|
593
|
-
if: runner.os.eq("Linux"),
|
|
594
|
-
run: "sudo apt-get update && sudo apt-get install -y jq",
|
|
595
|
-
}),
|
|
596
|
-
new Step({ name: "Build", run: "npm run build" }),
|
|
597
|
-
],
|
|
598
|
-
});
|
|
599
|
-
\`\`\``,
|
|
600
|
-
},
|
|
601
|
-
{
|
|
602
|
-
slug: "composites",
|
|
603
|
-
title: "Composites",
|
|
604
|
-
description: "Pre-built composites — action wrappers, CI pipelines, Docker builds, and deploy environments",
|
|
605
|
-
content: `Composites are pre-built abstractions that produce typed GitHub Actions resources. They range from single-action wrappers to full multi-job workflow pipelines.
|
|
606
|
-
|
|
607
|
-
{{file:docs-snippets/src/composites-usage.ts}}
|
|
608
|
-
|
|
609
|
-
**A note on folding.** These two composite shapes fold differently (see [Folded vs Run](/chant/concepts/typescript-as-data/#folded-vs-run)). A single-action wrapper like \`Checkout({...})\` is normally embedded inline as \`checkout.step\` inside a \`Job\`'s \`steps\` array — a call nested as a value inside another resource's own properties, which is outside the fold subset, so a file using it falls back to the normal run path. A multi-job pipeline composite like \`NodePipeline({...})\` is normally consumed the other way: bound to a local \`const\`, then each member re-exported separately (\`export const nodeWorkflow = node.workflow\`) — a top-level export whose value is a call result's member access, which is exactly the composite-call shape folding resolves (chant #1023).
|
|
610
|
-
|
|
611
|
-
## Checkout
|
|
612
|
-
|
|
613
|
-
Wraps \`actions/checkout@v4\`. Clones the repository.
|
|
614
|
-
|
|
615
|
-
\`\`\`typescript
|
|
616
|
-
import { Checkout } from "@intentius/chant-lexicon-github";
|
|
617
|
-
|
|
618
|
-
Checkout({}).step // Default checkout
|
|
619
|
-
Checkout({ fetchDepth: 0 }).step // Full history
|
|
620
|
-
Checkout({ ref: "develop" }).step // Specific branch
|
|
621
|
-
Checkout({ submodules: "recursive" }).step // With submodules
|
|
622
|
-
\`\`\`
|
|
623
|
-
|
|
624
|
-
**Props:** \`ref?\`, \`repository?\`, \`fetchDepth?\`, \`token?\`, \`submodules?\`, \`sshKey?\`
|
|
625
|
-
|
|
626
|
-
## SetupNode
|
|
627
|
-
|
|
628
|
-
Wraps \`actions/setup-node@v4\`. Installs Node.js with optional dependency caching.
|
|
629
|
-
|
|
630
|
-
\`\`\`typescript
|
|
631
|
-
import { SetupNode } from "@intentius/chant-lexicon-github";
|
|
632
|
-
|
|
633
|
-
SetupNode({ nodeVersion: "22" }).step // Node 22
|
|
634
|
-
SetupNode({ nodeVersion: "22", cache: "npm" }).step // With npm cache
|
|
635
|
-
SetupNode({ nodeVersion: "20", cache: "pnpm" }).step // pnpm cache
|
|
636
|
-
\`\`\`
|
|
637
|
-
|
|
638
|
-
**Props:** \`nodeVersion?\`, \`cache?\` (\`"npm"\` | \`"pnpm"\` | \`"yarn"\`), \`registryUrl?\`
|
|
639
|
-
|
|
640
|
-
## SetupGo
|
|
641
|
-
|
|
642
|
-
Wraps \`actions/setup-go@v5\`. Installs Go.
|
|
643
|
-
|
|
644
|
-
\`\`\`typescript
|
|
645
|
-
import { SetupGo } from "@intentius/chant-lexicon-github";
|
|
646
|
-
|
|
647
|
-
SetupGo({ goVersion: "1.22" }).step
|
|
648
|
-
SetupGo({ goVersion: "stable" }).step
|
|
649
|
-
\`\`\`
|
|
650
|
-
|
|
651
|
-
**Props:** \`goVersion?\`, \`cache?\`
|
|
652
|
-
|
|
653
|
-
## SetupPython
|
|
654
|
-
|
|
655
|
-
Wraps \`actions/setup-python@v5\`. Installs Python.
|
|
656
|
-
|
|
657
|
-
\`\`\`typescript
|
|
658
|
-
import { SetupPython } from "@intentius/chant-lexicon-github";
|
|
659
|
-
|
|
660
|
-
SetupPython({ pythonVersion: "3.12" }).step
|
|
661
|
-
SetupPython({ pythonVersion: "3.12", cache: "pip" }).step
|
|
662
|
-
\`\`\`
|
|
663
|
-
|
|
664
|
-
**Props:** \`pythonVersion?\`, \`cache?\` (\`"pip"\` | \`"pipenv"\` | \`"poetry"\`), \`architecture?\`
|
|
665
|
-
|
|
666
|
-
## CacheAction
|
|
667
|
-
|
|
668
|
-
Wraps \`actions/cache@v4\`. Caches files between workflow runs.
|
|
669
|
-
|
|
670
|
-
\`\`\`typescript
|
|
671
|
-
import { CacheAction } from "@intentius/chant-lexicon-github";
|
|
672
|
-
|
|
673
|
-
CacheAction({
|
|
674
|
-
path: "~/.npm",
|
|
675
|
-
key: "npm-\${{ runner.os }}-\${{ hashFiles('**/package-lock.json') }}",
|
|
676
|
-
restoreKeys: ["npm-\${{ runner.os }}-"],
|
|
677
|
-
}).step
|
|
678
|
-
\`\`\`
|
|
679
|
-
|
|
680
|
-
**Props:** \`path\`, \`key\`, \`restoreKeys?\`
|
|
681
|
-
|
|
682
|
-
## UploadArtifact
|
|
683
|
-
|
|
684
|
-
Wraps \`actions/upload-artifact@v4\`. Uploads files as workflow artifacts.
|
|
685
|
-
|
|
686
|
-
\`\`\`typescript
|
|
687
|
-
import { UploadArtifact } from "@intentius/chant-lexicon-github";
|
|
688
|
-
|
|
689
|
-
UploadArtifact({
|
|
690
|
-
name: "build-output",
|
|
691
|
-
path: "dist/",
|
|
692
|
-
retentionDays: 7,
|
|
693
|
-
}).step
|
|
694
|
-
\`\`\`
|
|
695
|
-
|
|
696
|
-
**Props:** \`name\`, \`path\`, \`retentionDays?\`, \`ifNoFilesFound?\`
|
|
697
|
-
|
|
698
|
-
## DownloadArtifact
|
|
699
|
-
|
|
700
|
-
Wraps \`actions/download-artifact@v4\`. Downloads previously uploaded artifacts.
|
|
701
|
-
|
|
702
|
-
\`\`\`typescript
|
|
703
|
-
import { DownloadArtifact } from "@intentius/chant-lexicon-github";
|
|
704
|
-
|
|
705
|
-
DownloadArtifact({
|
|
706
|
-
name: "build-output",
|
|
707
|
-
path: "dist/",
|
|
708
|
-
}).step
|
|
709
|
-
\`\`\`
|
|
710
|
-
|
|
711
|
-
**Props:** \`name\`, \`path?\`
|
|
712
|
-
|
|
713
|
-
## NodeCI
|
|
714
|
-
|
|
715
|
-
A batteries-included composite that produces a full CI workflow and job. Generates a \`Workflow\` (push + PR on main) and a \`Job\` with checkout, setup-node, install, build, and test steps.
|
|
716
|
-
|
|
717
|
-
\`\`\`typescript
|
|
718
|
-
import { NodeCI } from "@intentius/chant-lexicon-github";
|
|
719
|
-
|
|
720
|
-
// Default: Node 22, npm, "build" + "test" scripts
|
|
721
|
-
const { workflow, job } = NodeCI({});
|
|
722
|
-
|
|
723
|
-
// Customized
|
|
724
|
-
const { workflow: w, job: j } = NodeCI({
|
|
725
|
-
nodeVersion: "20",
|
|
726
|
-
packageManager: "pnpm",
|
|
727
|
-
buildScript: "compile",
|
|
728
|
-
testScript: "test:ci",
|
|
729
|
-
});
|
|
730
|
-
\`\`\`
|
|
731
|
-
|
|
732
|
-
**Props:** \`nodeVersion?\`, \`packageManager?\` (\`"npm"\` | \`"pnpm"\` | \`"yarn"\` | \`"bun"\`), \`buildScript?\`, \`testScript?\`, \`installCommand?\`
|
|
733
|
-
|
|
734
|
-
The returned \`workflow\` and \`job\` can be exported directly:
|
|
735
|
-
|
|
736
|
-
\`\`\`typescript
|
|
737
|
-
const ci = NodeCI({ nodeVersion: "22", packageManager: "npm" });
|
|
738
|
-
export const workflow = ci.workflow;
|
|
739
|
-
export const build = ci.job;
|
|
740
|
-
\`\`\`
|
|
741
|
-
|
|
742
|
-
## NodePipeline
|
|
743
|
-
|
|
744
|
-
A production-grade Node pipeline with separate build and test jobs connected by artifact passing. The build job uploads artifacts; the test job downloads them and runs tests with \`needs: ["build"]\`.
|
|
745
|
-
|
|
746
|
-
\`\`\`typescript
|
|
747
|
-
import { NodePipeline } from "@intentius/chant-lexicon-github";
|
|
748
|
-
|
|
749
|
-
const { workflow, buildJob, testJob } = NodePipeline({
|
|
750
|
-
nodeVersion: "22",
|
|
751
|
-
packageManager: "pnpm",
|
|
752
|
-
buildScript: "build",
|
|
753
|
-
testScript: "test:ci",
|
|
754
|
-
buildArtifactPaths: ["dist/", "lib/"],
|
|
755
|
-
});
|
|
756
|
-
\`\`\`
|
|
757
|
-
|
|
758
|
-
**Props:** \`nodeVersion?\`, \`packageManager?\` (\`"npm"\` | \`"pnpm"\` | \`"yarn"\` | \`"bun"\`), \`buildScript?\`, \`testScript?\`, \`installCommand?\`, \`buildArtifactPaths?\`, \`artifactName?\`, \`artifactRetentionDays?\`, \`runsOn?\`
|
|
759
|
-
|
|
760
|
-
### Presets
|
|
761
|
-
|
|
762
|
-
\`\`\`typescript
|
|
763
|
-
import { BunPipeline, PnpmPipeline, YarnPipeline } from "@intentius/chant-lexicon-github";
|
|
764
|
-
|
|
765
|
-
const bun = BunPipeline({}); // packageManager: "bun", uses oven-sh/setup-bun@v2
|
|
766
|
-
const pnpm = PnpmPipeline({}); // packageManager: "pnpm"
|
|
767
|
-
const yarn = YarnPipeline({}); // packageManager: "yarn"
|
|
768
|
-
\`\`\`
|
|
769
|
-
|
|
770
|
-
## PythonCI
|
|
771
|
-
|
|
772
|
-
Python CI with test and optional lint jobs. Supports pip and Poetry workflows.
|
|
773
|
-
|
|
774
|
-
\`\`\`typescript
|
|
775
|
-
import { PythonCI } from "@intentius/chant-lexicon-github";
|
|
776
|
-
|
|
777
|
-
const { workflow, testJob, lintJob } = PythonCI({
|
|
778
|
-
pythonVersion: "3.12",
|
|
779
|
-
testCommand: "pytest --junitxml=report.xml --cov",
|
|
780
|
-
lintCommand: "ruff check .",
|
|
781
|
-
});
|
|
782
|
-
|
|
783
|
-
// Omit lint job
|
|
784
|
-
const { workflow: w, testJob: t } = PythonCI({ lintCommand: null });
|
|
785
|
-
|
|
786
|
-
// Poetry mode
|
|
787
|
-
const poetry = PythonCI({ usePoetry: true });
|
|
788
|
-
\`\`\`
|
|
789
|
-
|
|
790
|
-
**Props:** \`pythonVersion?\`, \`testCommand?\`, \`lintCommand?\` (null to omit), \`requirementsFile?\`, \`usePoetry?\`, \`runsOn?\`
|
|
791
|
-
|
|
792
|
-
## DockerBuild
|
|
793
|
-
|
|
794
|
-
Docker build and push using official Docker actions (login, setup-buildx, metadata, build-push). Configured for GitHub Container Registry by default.
|
|
795
|
-
|
|
796
|
-
\`\`\`typescript
|
|
797
|
-
import { DockerBuild } from "@intentius/chant-lexicon-github";
|
|
798
|
-
|
|
799
|
-
const { workflow, job } = DockerBuild({
|
|
800
|
-
registry: "ghcr.io",
|
|
801
|
-
imageName: "ghcr.io/my-org/my-app",
|
|
802
|
-
dockerfile: "Dockerfile",
|
|
803
|
-
platforms: ["linux/amd64", "linux/arm64"],
|
|
804
|
-
});
|
|
805
|
-
\`\`\`
|
|
806
|
-
|
|
807
|
-
**Props:** \`tag?\`, \`dockerfile?\`, \`context?\`, \`registry?\`, \`imageName?\`, \`tagLatest?\`, \`buildArgs?\`, \`push?\`, \`platforms?\`, \`runsOn?\`
|
|
808
|
-
|
|
809
|
-
## DeployEnvironment
|
|
810
|
-
|
|
811
|
-
Deploy and cleanup job pair using GitHub Environments with concurrency control.
|
|
812
|
-
|
|
813
|
-
\`\`\`typescript
|
|
814
|
-
import { DeployEnvironment } from "@intentius/chant-lexicon-github";
|
|
815
|
-
|
|
816
|
-
const { deployJob, cleanupJob } = DeployEnvironment({
|
|
817
|
-
name: "staging",
|
|
818
|
-
deployScript: ["npm run build", "npm run deploy"],
|
|
819
|
-
cleanupScript: "npm run teardown",
|
|
820
|
-
url: "https://staging.example.com",
|
|
821
|
-
});
|
|
822
|
-
\`\`\`
|
|
823
|
-
|
|
824
|
-
**Props:** \`name\` (required), \`deployScript\` (required), \`cleanupScript?\`, \`url?\`, \`concurrencyGroup?\`, \`cancelInProgress?\`, \`runsOn?\`
|
|
825
|
-
|
|
826
|
-
## GoCI
|
|
827
|
-
|
|
828
|
-
Go CI with build, test, and optional lint jobs. Uses \`golangci-lint-action\` for linting.
|
|
829
|
-
|
|
830
|
-
\`\`\`typescript
|
|
831
|
-
import { GoCI } from "@intentius/chant-lexicon-github";
|
|
832
|
-
|
|
833
|
-
const { workflow, buildJob, testJob, lintJob } = GoCI({
|
|
834
|
-
goVersion: "1.22",
|
|
835
|
-
buildCommand: "go build ./...",
|
|
836
|
-
testCommand: "go test ./... -v -race",
|
|
837
|
-
});
|
|
838
|
-
|
|
839
|
-
// Without lint
|
|
840
|
-
const noLint = GoCI({ lintCommand: null });
|
|
841
|
-
\`\`\`
|
|
842
|
-
|
|
843
|
-
**Props:** \`goVersion?\`, \`testCommand?\`, \`buildCommand?\`, \`lintCommand?\` (null to omit), \`runsOn?\`
|
|
844
|
-
|
|
845
|
-
## Dependabot
|
|
846
|
-
|
|
847
|
-
Models the repository's dependency-update configuration (\`.github/dependabot.yml\`) as a chant resource, so it is emitted and lintable like a workflow. The composite ships **safe defaults**: a cooldown window on every ecosystem (so a version published moments ago — including a compromised one — is not adopted before anyone can react) and external code execution explicitly denied.
|
|
848
|
-
|
|
849
|
-
\`\`\`typescript
|
|
850
|
-
import { Dependabot } from "@intentius/chant-lexicon-github";
|
|
851
|
-
|
|
852
|
-
export const dependabot = Dependabot({
|
|
853
|
-
ecosystems: [
|
|
854
|
-
{ packageEcosystem: "npm", directory: "/" },
|
|
855
|
-
{ packageEcosystem: "github-actions", directory: "/" },
|
|
856
|
-
],
|
|
857
|
-
// cooldownDays defaults to 7, openPullRequestsLimit to 5
|
|
858
|
-
});
|
|
859
|
-
\`\`\`
|
|
860
|
-
|
|
861
|
-
**Props:** \`ecosystems\` (required — each \`{ packageEcosystem, directory?, interval? }\`), \`cooldownDays?\` (default 7), \`openPullRequestsLimit?\` (default 5)
|
|
862
|
-
|
|
863
|
-
For full control, construct the \`DependabotConfig\` resource directly with raw \`updates:\` entries. Two post-synth checks validate the emitted config: **GHA057** (\`insecure-external-code-execution: allow\`) and **GHA058** (no cooldown). See [Lint Rules](/chant/lexicons/github/lint-rules/).`,
|
|
864
|
-
},
|
|
865
|
-
{
|
|
866
|
-
slug: "lint-rules",
|
|
867
|
-
title: "Lint Rules",
|
|
868
|
-
description: "Built-in lint rules and post-synth checks for GitHub Actions workflows",
|
|
869
|
-
content: `The GitHub Actions lexicon ships lint rules that run during \`chant lint\` and post-synth checks that validate the serialized YAML after \`chant build\`.
|
|
870
|
-
|
|
871
|
-
## Lint rules
|
|
872
|
-
|
|
873
|
-
Lint rules analyze your TypeScript source code before build.
|
|
874
|
-
|
|
875
|
-
### GHA001 — Use typed action composites
|
|
876
|
-
|
|
877
|
-
**Severity:** warning | **Category:** style
|
|
878
|
-
|
|
879
|
-
Flags raw \`uses:\` strings when a typed composite wrapper is available (e.g. \`actions/checkout@v4\` → \`Checkout({})\`). Typed composites provide better IDE support and catch configuration errors at compile time.
|
|
880
|
-
|
|
881
|
-
### GHA002 — Use Expression helpers
|
|
882
|
-
|
|
883
|
-
**Severity:** warning | **Category:** style
|
|
884
|
-
|
|
885
|
-
Flags raw \`\${{ }}\` strings in \`if:\` conditions. Use the typed Expression helpers (\`github.ref.eq(...)\`, \`branch("main")\`, \`failure()\`) instead for type safety and lint coverage.
|
|
886
|
-
|
|
887
|
-
### GHA003 — No hardcoded secrets
|
|
888
|
-
|
|
889
|
-
**Severity:** error | **Category:** security
|
|
890
|
-
|
|
891
|
-
Flags hardcoded GitHub tokens, AWS keys, and other secret patterns in source code. Use \`secrets("...")\` expressions instead.
|
|
892
|
-
|
|
893
|
-
{{file:docs-snippets/src/lint-gha003.ts}}
|
|
894
|
-
|
|
895
|
-
### GHA004 — Extract inline matrix
|
|
896
|
-
|
|
897
|
-
**Severity:** info | **Category:** style
|
|
898
|
-
|
|
899
|
-
Flags inline matrix objects and suggests extracting them to named constants for readability.
|
|
900
|
-
|
|
901
|
-
### GHA005 — Extract deeply nested objects
|
|
902
|
-
|
|
903
|
-
**Severity:** info | **Category:** style
|
|
904
|
-
|
|
905
|
-
Flags deeply nested inline objects and suggests extracting them to named constants.
|
|
906
|
-
|
|
907
|
-
### GHA007 — Too many jobs per file
|
|
908
|
-
|
|
909
|
-
**Severity:** warning | **Category:** style
|
|
910
|
-
|
|
911
|
-
Flags files with more than 10 job exports. Split large workflows into separate files for maintainability.
|
|
912
|
-
|
|
913
|
-
### GHA008 — Avoid raw expression strings
|
|
914
|
-
|
|
915
|
-
**Severity:** info | **Category:** style
|
|
916
|
-
|
|
917
|
-
Flags raw \`\${{ }}\` expression strings outside of \`if:\` fields. Use the typed expression helpers (\`github.*\`, \`secrets()\`, \`matrix()\`) for better type safety.
|
|
918
|
-
|
|
919
|
-
### GHA010 — Setup action missing version
|
|
920
|
-
|
|
921
|
-
**Severity:** warning | **Category:** correctness
|
|
922
|
-
|
|
923
|
-
Flags setup action composites (SetupNode, SetupGo, SetupPython) without a version input. Pinning the version ensures reproducible builds.
|
|
924
|
-
|
|
925
|
-
### GHA012 — Deprecated action version
|
|
926
|
-
|
|
927
|
-
**Severity:** warning | **Category:** correctness
|
|
928
|
-
|
|
929
|
-
Flags action \`uses:\` references that point to deprecated versions. Upgrade to the recommended version.
|
|
930
|
-
|
|
931
|
-
### GHA014 — Missing timeout
|
|
932
|
-
|
|
933
|
-
**Severity:** warning | **Category:** correctness
|
|
934
|
-
|
|
935
|
-
Flags jobs without \`timeoutMinutes\`. Jobs without a timeout default to 360 minutes (6 hours), which can waste runner minutes if stuck.
|
|
936
|
-
|
|
937
|
-
### GHA015 — Setup without cache
|
|
938
|
-
|
|
939
|
-
**Severity:** warning | **Category:** performance
|
|
940
|
-
|
|
941
|
-
Flags setup action composites (SetupNode, SetupGo, SetupPython) without a paired \`CacheAction\` or built-in \`cache\` option. Caching dependencies significantly speeds up builds.
|
|
942
|
-
|
|
943
|
-
### GHA016 — Concurrency missing group
|
|
944
|
-
|
|
945
|
-
**Severity:** warning | **Category:** correctness
|
|
946
|
-
|
|
947
|
-
Flags \`concurrency\` with \`cancel-in-progress: true\` but no \`group\` specified. Without a group, all runs of the workflow share a single concurrency slot.
|
|
948
|
-
|
|
949
|
-
### GHA020 — Potential secret detected
|
|
950
|
-
|
|
951
|
-
**Severity:** error | **Category:** security
|
|
952
|
-
|
|
953
|
-
Flags string literals that match common secret patterns (API keys, tokens, passwords). Use \`secrets()\` or environment variables instead.
|
|
954
|
-
|
|
955
|
-
## Post-synth checks
|
|
956
|
-
|
|
957
|
-
Post-synth checks run against the serialized YAML after build. They catch issues only visible in the final output.
|
|
958
|
-
|
|
959
|
-
### GHA006 — Duplicate workflow names
|
|
960
|
-
|
|
961
|
-
**Severity:** error
|
|
962
|
-
|
|
963
|
-
Flags multiple workflows that share the same \`name:\` value. Duplicate names cause confusion in the GitHub Actions UI.
|
|
964
|
-
|
|
965
|
-
### GHA009 — Empty matrix dimension
|
|
966
|
-
|
|
967
|
-
**Severity:** error
|
|
968
|
-
|
|
969
|
-
Flags matrix strategy dimensions with an empty values array. An empty dimension causes the job to be skipped entirely.
|
|
970
|
-
|
|
971
|
-
### GHA011 — Invalid needs target
|
|
972
|
-
|
|
973
|
-
**Severity:** error
|
|
974
|
-
|
|
975
|
-
Flags jobs whose \`needs:\` entries reference a job not defined in the workflow. This causes a workflow validation error on GitHub.
|
|
976
|
-
|
|
977
|
-
### GHA013 — Missing job-level permissions for sensitive triggers
|
|
978
|
-
|
|
979
|
-
**Severity:** warning
|
|
980
|
-
|
|
981
|
-
Flags jobs without an explicit \`permissions:\` block when the workflow uses a sensitive trigger (\`pull_request_target\` or \`workflow_dispatch\`). Declaring job-level permissions keeps least-privilege scope on workflows that run with elevated context.
|
|
982
|
-
|
|
983
|
-
### GHA017 — Missing permissions block
|
|
984
|
-
|
|
985
|
-
**Severity:** info
|
|
986
|
-
|
|
987
|
-
Flags workflows without an explicit \`permissions:\` block. Omitting permissions uses the repository default (often overly broad). Following least-privilege by declaring explicit permissions is a security best practice.
|
|
988
|
-
|
|
989
|
-
### GHA018 — pull_request_target with checkout
|
|
990
|
-
|
|
991
|
-
**Severity:** warning
|
|
992
|
-
|
|
993
|
-
Flags workflows triggered by \`pull_request_target\` that include \`actions/checkout\`. This combination can be a security risk because the workflow runs with write permissions in the context of the base branch while checking out potentially untrusted PR code.
|
|
994
|
-
|
|
995
|
-
### GHA019 — Circular needs chain
|
|
996
|
-
|
|
997
|
-
**Severity:** error
|
|
998
|
-
|
|
999
|
-
Detects cycles in the \`needs:\` dependency graph. If job A needs B and B needs A (directly or transitively), GitHub rejects the workflow. Reports the full cycle chain in the diagnostic message.
|
|
1000
|
-
|
|
1001
|
-
### GHA021 — Checkout action not pinned to a SHA
|
|
1002
|
-
|
|
1003
|
-
**Severity:** warning
|
|
1004
|
-
|
|
1005
|
-
Flags \`actions/checkout\` referenced by a tag (e.g. \`@v4\`) instead of a pinned commit SHA. The narrower precursor to GHA029, kept because checkout is the most common unpinned action.
|
|
1006
|
-
|
|
1007
|
-
### GHA022 — Job without timeout-minutes
|
|
1008
|
-
|
|
1009
|
-
**Severity:** info
|
|
1010
|
-
|
|
1011
|
-
Flags jobs that omit \`timeout-minutes\`. A hung step otherwise runs to the runner's default cap, burning minutes — set an explicit ceiling.
|
|
1012
|
-
|
|
1013
|
-
### GHA023 — Deprecated set-output command
|
|
1014
|
-
|
|
1015
|
-
**Severity:** warning
|
|
1016
|
-
|
|
1017
|
-
Flags \`::set-output\` in \`run:\` steps. The workflow command is deprecated and disabled on current runners — write to \`$GITHUB_OUTPUT\` instead.
|
|
1018
|
-
|
|
1019
|
-
### GHA024 — Missing concurrency for deploy workflows
|
|
1020
|
-
|
|
1021
|
-
**Severity:** info
|
|
1022
|
-
|
|
1023
|
-
Flags deploy workflows without a \`concurrency:\` block. Without one, two pushes can deploy concurrently and race — add a concurrency group to serialize them.
|
|
1024
|
-
|
|
1025
|
-
### GHA025 — pull_request_target without restrictions
|
|
1026
|
-
|
|
1027
|
-
**Severity:** warning
|
|
1028
|
-
|
|
1029
|
-
Flags \`pull_request_target\` used without a \`types:\` filter. The trigger runs with repository secrets in the base-branch context, so it should be scoped to the specific PR events that need it.
|
|
1030
|
-
|
|
1031
|
-
### GHA026 — Secret used without environment protection
|
|
1032
|
-
|
|
1033
|
-
**Severity:** info
|
|
1034
|
-
|
|
1035
|
-
Flags workflows that reference \`secrets.\` in steps but declare no \`environment:\` on any job, so the secret skips the approval and scoping rules an environment gate provides.
|
|
1036
|
-
|
|
1037
|
-
### GHA027 — Cleanup step missing if: always()
|
|
1038
|
-
|
|
1039
|
-
**Severity:** info
|
|
1040
|
-
|
|
1041
|
-
Flags steps named "cleanup" / "teardown" / "clean up" that lack an \`if:\` condition. Cleanup should run even when a prior step fails — add \`if: always()\`.
|
|
1042
|
-
|
|
1043
|
-
### GHA028 — Workflow with no on: triggers
|
|
1044
|
-
|
|
1045
|
-
**Severity:** error
|
|
1046
|
-
|
|
1047
|
-
Flags a workflow file with no top-level \`on:\` key. Without a trigger the workflow can never run.
|
|
1048
|
-
|
|
1049
|
-
## Supply-chain security pass (GHA029–058)
|
|
1050
|
-
|
|
1051
|
-
GHA029 onward are a CI/CD supply-chain security pass: pin & vet external references, enforce least-privilege token scopes, guard trust boundaries against untrusted input, contain secrets, reject unsound expressions, and keep artifacts/caches honest. They run statically on the emitted YAML — everything answerable without leaving the build.
|
|
1052
|
-
|
|
1053
|
-
The checks that need a *moving external truth* — whether a pinned SHA still maps to a real upstream tag, whether a ref still exists, whether a new advisory now covers an action in use — can't be deterministic, so they live in the operational layer instead. Schedule the [\`WorkflowAuditOp\`](/chant/guide/ops/#audit-supply-chain-drift) (temporal lexicon) for that live, always-fresh half; it reads the same emitted workflow references and reports drift via \`report | issue | pull-request\`.
|
|
1054
|
-
|
|
1055
|
-
### GHA029 — Action or reusable workflow not pinned to a commit SHA
|
|
1056
|
-
|
|
1057
|
-
**Severity:** warning
|
|
1058
|
-
|
|
1059
|
-
Flags any \`uses:\` — step action or job-level reusable workflow — pinned to a mutable tag or branch instead of a full commit SHA. Tags can be repointed to malicious code after review, so every external reference should be pinned. \`actions/checkout\` is covered by the more specific GHA021; local (\`./\`) and \`docker://\` references are out of scope. Owners in the vendored trusted allowlist are exempt.
|
|
1060
|
-
|
|
1061
|
-
### GHA030 — Container image not pinned to a digest
|
|
1062
|
-
|
|
1063
|
-
**Severity:** warning
|
|
1064
|
-
|
|
1065
|
-
Flags job \`container:\` images, \`services:\` images, and \`docker://\` step references that are not pinned to an immutable \`@sha256:\` digest. A mutable tag can be repointed to a different image after review.
|
|
1066
|
-
|
|
1067
|
-
### GHA031 — Action resembles a well-known action
|
|
1068
|
-
|
|
1069
|
-
**Severity:** warning
|
|
1070
|
-
|
|
1071
|
-
Flags a \`uses:\` slug that is a near-miss (edit distance 1–2) of a popular action but not an exact match — a likely typo or impersonation under different ownership. Advisory; backed by a vendored reference list.
|
|
1072
|
-
|
|
1073
|
-
### GHA032 — Archived or compromised action
|
|
1074
|
-
|
|
1075
|
-
**Severity:** warning
|
|
1076
|
-
|
|
1077
|
-
Flags a \`uses:\` slug that a vendored snapshot marks as archived/abandoned or carrying a disclosed security issue, with remediation. Advisory and necessarily incomplete.
|
|
1078
|
-
|
|
1079
|
-
### GHA033 — Blanket write-all permissions
|
|
1080
|
-
|
|
1081
|
-
**Severity:** warning
|
|
1082
|
-
|
|
1083
|
-
Flags \`permissions: write-all\` at the workflow or job level. It grants the \`GITHUB_TOKEN\` every write scope regardless of need — replace it with the specific scopes the job uses.
|
|
1084
|
-
|
|
1085
|
-
### GHA034 — Write permissions granted workflow-wide
|
|
1086
|
-
|
|
1087
|
-
**Severity:** warning
|
|
1088
|
-
|
|
1089
|
-
Flags individual write scopes declared at the workflow level, which apply to every job even when only one needs them. Move each write scope onto the specific job that uses it. (The \`write-all\` preset is covered by GHA033.)
|
|
1090
|
-
|
|
1091
|
-
### GHA035 — Elevated scope on an untrusted-code trigger
|
|
1092
|
-
|
|
1093
|
-
**Severity:** error
|
|
1094
|
-
|
|
1095
|
-
Flags a workflow that grants the token write access while using a trigger that can run untrusted code (\`pull_request_target\`, \`workflow_run\`). An injected step would run with standing write credentials — drop the write scope or isolate the privileged work in a separate trusted workflow.
|
|
1096
|
-
|
|
1097
|
-
### GHA036 — Untrusted input in a run: command
|
|
1098
|
-
|
|
1099
|
-
**Severity:** error
|
|
1100
|
-
|
|
1101
|
-
Flags an attacker-controllable expression context (PR title, branch name, issue/comment body, commit message) interpolated directly into a \`run:\` script — a script-injection sink. Pass the value through an \`env:\` variable and reference it quoted instead.
|
|
1102
|
-
|
|
1103
|
-
### GHA037 — Untrusted input written to GITHUB_ENV / GITHUB_PATH
|
|
1104
|
-
|
|
1105
|
-
**Severity:** error
|
|
1106
|
-
|
|
1107
|
-
Flags a \`run:\` step that writes untrusted input into \`$GITHUB_ENV\` or \`$GITHUB_PATH\`, which set environment/PATH state for later steps and can escalate into takeover of a subsequent privileged step.
|
|
1108
|
-
|
|
1109
|
-
### GHA038 — workflow_run trigger checking out untrusted code
|
|
1110
|
-
|
|
1111
|
-
**Severity:** warning
|
|
1112
|
-
|
|
1113
|
-
Generalizes GHA018 to the \`workflow_run\` trigger, which runs with repo write scope and secrets. Checking out the head/artifact of the triggering run pulls untrusted code into that privileged context.
|
|
1114
|
-
|
|
1115
|
-
### GHA039 — Authorization gate on a spoofable identity
|
|
1116
|
-
|
|
1117
|
-
**Severity:** warning
|
|
1118
|
-
|
|
1119
|
-
Flags an \`if:\` condition that gates on a commit-author identity field (\`author.name\` / \`author.email\`). Those come from git metadata the committer sets freely and can be spoofed — gate on a verified signal (environment protection, CODEOWNERS, verified actor).
|
|
1120
|
-
|
|
1121
|
-
### GHA040 — Self-hosted runner on an untrusted-code trigger
|
|
1122
|
-
|
|
1123
|
-
**Severity:** warning
|
|
1124
|
-
|
|
1125
|
-
Flags a job on a self-hosted runner under a trigger a fork can reach (\`pull_request\`, \`pull_request_target\`, \`workflow_run\`). Self-hosted runners are non-ephemeral and shared, so untrusted code can persist and compromise later jobs.
|
|
1126
|
-
|
|
1127
|
-
### GHA041 — Blanket secrets: inherit into a reusable workflow
|
|
1128
|
-
|
|
1129
|
-
**Severity:** warning
|
|
1130
|
-
|
|
1131
|
-
Flags a reusable-workflow call passing \`secrets: inherit\`, which hands the called workflow every caller secret. Pass through only the specific secrets it needs.
|
|
1132
|
-
|
|
1133
|
-
### GHA042 — Entire secrets context passed
|
|
1134
|
-
|
|
1135
|
-
**Severity:** warning
|
|
1136
|
-
|
|
1137
|
-
Flags \`toJSON(secrets)\` passed into a step or reusable workflow, serializing every secret where one or two specific references would do.
|
|
1138
|
-
|
|
1139
|
-
### GHA043 — Secret consumed without an environment gate
|
|
1140
|
-
|
|
1141
|
-
**Severity:** warning
|
|
1142
|
-
|
|
1143
|
-
Extends GHA026: when a workflow gates some jobs with an \`environment:\`, flags the specific secret-using jobs that have none — the inconsistent-gating case where a job skips the approval/scoping applied elsewhere.
|
|
1144
|
-
|
|
1145
|
-
### GHA044 — Hardcoded registry/container credential
|
|
1146
|
-
|
|
1147
|
-
**Severity:** error
|
|
1148
|
-
|
|
1149
|
-
Flags a \`password:\` / \`token:\` / \`registry-password:\` set to a literal rather than a \`\${{ secrets.* }}\` reference. Move the credential into a secret.
|
|
1150
|
-
|
|
1151
|
-
### GHA045 — Secret interpolated into a run: command
|
|
1152
|
-
|
|
1153
|
-
**Severity:** warning
|
|
1154
|
-
|
|
1155
|
-
Flags \`\${{ secrets.* }}\` expanded directly into a \`run:\` script, where a transform can defeat log masking and the raw value is exposed to argument injection. Pass it through an \`env:\` variable and reference \`"$VAR"\` quoted.
|
|
1156
|
-
|
|
1157
|
-
### GHA046 — Logically unsound guard condition
|
|
1158
|
-
|
|
1159
|
-
**Severity:** warning
|
|
1160
|
-
|
|
1161
|
-
Flags an \`if:\` condition that reads like a gate but evaluates to a constant — \`true\`/\`false\` literals, an \`X == X\` tautology, or a collapse via \`|| true\` / \`&& false\`. A gate that constrains nothing is misleading.
|
|
1162
|
-
|
|
1163
|
-
### GHA047 — Ineffective contains() guard
|
|
1164
|
-
|
|
1165
|
-
**Severity:** warning
|
|
1166
|
-
|
|
1167
|
-
Flags \`contains('literal', <dynamic>)\` — a constant haystack with a dynamic needle. \`contains(search, item)\` tests whether \`item\` is in \`search\`, so reversed arguments make the result depend on a fixed string. Swap them.
|
|
1168
|
-
|
|
1169
|
-
### GHA048 — Obfuscated guard condition
|
|
1170
|
-
|
|
1171
|
-
**Severity:** warning
|
|
1172
|
-
|
|
1173
|
-
Flags an \`if:\` gate whose compared operand is built through \`format()\` / \`join()\` / \`fromJSON()\` indirection. Constructing the operand at evaluation time hides what the gate checks — compare against the value directly.
|
|
1174
|
-
|
|
1175
|
-
### GHA049 — Persisted checkout credentials reachable by an artifact
|
|
1176
|
-
|
|
1177
|
-
**Severity:** warning
|
|
1178
|
-
|
|
1179
|
-
Flags a job that checks out with persisted credentials (the default) and uploads an artifact — the token in \`.git/config\` can be swept into the artifact. Set \`persist-credentials: false\` on the checkout.
|
|
1180
|
-
|
|
1181
|
-
### GHA050 — Cache populated in a privileged context
|
|
1182
|
-
|
|
1183
|
-
**Severity:** warning
|
|
1184
|
-
|
|
1185
|
-
Flags \`actions/cache\` under a privileged trigger (\`pull_request_target\`, \`workflow_run\`). A cache entry influenced by a fork can be restored and executed by a later trusted run (cache poisoning) — restrict caching to trusted triggers.
|
|
1186
|
-
|
|
1187
|
-
### GHA051 — Publish step using a long-lived token instead of OIDC
|
|
1188
|
-
|
|
1189
|
-
**Severity:** info
|
|
1190
|
-
|
|
1191
|
-
Flags a publish/release job that uses a long-lived token secret while requesting no \`id-token: write\`. If the registry supports OIDC, mint a short-lived federated credential per run instead of holding a standing token.
|
|
1192
|
-
|
|
1193
|
-
### GHA052 — Software fetched and piped to a shell
|
|
1194
|
-
|
|
1195
|
-
**Severity:** warning
|
|
1196
|
-
|
|
1197
|
-
Flags a \`run:\` step that pipes a network download straight into a shell (\`curl ... | bash\`). The fetched code is unpinned and unverified — download to a file, verify a checksum/signature, then run it.
|
|
1198
|
-
|
|
1199
|
-
### GHA053 — Unsafe set-env / add-path opt-in
|
|
1200
|
-
|
|
1201
|
-
**Severity:** error
|
|
1202
|
-
|
|
1203
|
-
Flags re-enabling the \`set-env\` / \`add-path\` workflow commands removed for security (CVE-2020-15228) via \`ACTIONS_ALLOW_UNSECURE_COMMANDS\` or direct \`::set-env::\` / \`::add-path::\`. Use the \`$GITHUB_ENV\` / \`$GITHUB_PATH\` files instead.
|
|
1204
|
-
|
|
1205
|
-
### GHA054 — Known-bad feature usage
|
|
1206
|
-
|
|
1207
|
-
**Severity:** warning
|
|
1208
|
-
|
|
1209
|
-
Catch-all, data-driven check flagging emitted content matching a vendored snapshot of risky features (deprecated workflow commands, unsafe runtime opt-ins). Advisory and necessarily incomplete.
|
|
1210
|
-
|
|
1211
|
-
### GHA055 — Redundant runtime tool install
|
|
1212
|
-
|
|
1213
|
-
**Severity:** info
|
|
1214
|
-
|
|
1215
|
-
Flags a \`run:\` step that installs a tool GitHub-hosted runners already ship. The redundant install adds supply-chain surface for no benefit (irrelevant on self-hosted runners that may lack the tool).
|
|
1216
|
-
|
|
1217
|
-
### GHA056 — Workflow without a name
|
|
1218
|
-
|
|
1219
|
-
**Severity:** info
|
|
1220
|
-
|
|
1221
|
-
Flags a workflow with no top-level \`name:\`. Without one, GitHub falls back to the file path in the UI and audit logs, making runs harder to identify.
|
|
1222
|
-
|
|
1223
|
-
> Two items from issue #295 are intentionally not implemented at the post-synth layer: over-broad/unrevoked app-installation tokens (whether a minted token is scoped wider than used cannot be determined from emitted YAML) and a reference allowlist/denylist policy (configuration, overlapping the GHA029 trusted-owner allowlist).
|
|
1224
|
-
|
|
1225
|
-
### GHA057 — Dependency update executes untrusted code
|
|
1226
|
-
|
|
1227
|
-
**Severity:** error
|
|
1228
|
-
|
|
1229
|
-
Flags a Dependabot \`updates:\` entry with \`insecure-external-code-execution: allow\`, which runs a freshly-pulled dependency's lifecycle scripts during the update itself — a compromised release executes before any review. Set it to \`deny\`. Requires the \`Dependabot\` resource so the config is emitted (\`.github/dependabot.yml\`).
|
|
1230
|
-
|
|
1231
|
-
### GHA058 — Dependency update without a cooldown
|
|
1232
|
-
|
|
1233
|
-
**Severity:** warning
|
|
1234
|
-
|
|
1235
|
-
Flags a Dependabot \`updates:\` entry with no cooldown — a version published moments ago (including a compromised one) is adopted immediately. Configure a \`cooldown:\` window. The \`Dependabot\` composite ships a 7-day default.
|
|
1236
|
-
|
|
1237
|
-
## Running lint
|
|
1238
|
-
|
|
1239
|
-
\`\`\`bash
|
|
1240
|
-
# Lint your chant project
|
|
1241
|
-
chant lint src/
|
|
1242
|
-
|
|
1243
|
-
# Lint with auto-fix where supported
|
|
1244
|
-
chant lint --fix src/
|
|
1245
|
-
\`\`\`
|
|
1246
|
-
|
|
1247
|
-
To suppress a rule on a specific line:
|
|
1248
|
-
|
|
1249
|
-
\`\`\`typescript
|
|
1250
|
-
// chant-disable-next-line GHA001
|
|
1251
|
-
new Step({ uses: "actions/checkout@v4" });
|
|
1252
|
-
\`\`\`
|
|
1253
|
-
|
|
1254
|
-
To suppress globally in \`chant.config.ts\`:
|
|
1255
|
-
|
|
1256
|
-
\`\`\`typescript
|
|
1257
|
-
export default {
|
|
1258
|
-
lint: {
|
|
1259
|
-
rules: {
|
|
1260
|
-
GHA014: "off",
|
|
1261
|
-
},
|
|
1262
|
-
},
|
|
1263
|
-
};
|
|
1264
|
-
\`\`\``,
|
|
1265
|
-
},
|
|
1266
|
-
{
|
|
1267
|
-
slug: "examples",
|
|
1268
|
-
title: "Examples",
|
|
1269
|
-
description: "Walkthrough of GitHub Actions examples — workflows, composites, and patterns",
|
|
1270
|
-
content: `Runnable examples live in the lexicon's \`examples/\` directory. Clone the repo and try them:
|
|
1271
|
-
|
|
1272
|
-
\`\`\`bash
|
|
1273
|
-
cd examples/getting-started
|
|
1274
|
-
npm install
|
|
1275
|
-
chant build # produces .github/workflows/ci.yml
|
|
1276
|
-
chant lint # runs lint rules
|
|
1277
|
-
npx vitest run # run the tests
|
|
1278
|
-
\`\`\`
|
|
1279
|
-
|
|
1280
|
-
## Getting Started
|
|
1281
|
-
|
|
1282
|
-
\`examples/getting-started/\` — a CI workflow with build and test steps for a Node.js project.
|
|
1283
|
-
|
|
1284
|
-
\`\`\`
|
|
1285
|
-
src/
|
|
1286
|
-
└── ci.ts # Workflow + Job definitions
|
|
1287
|
-
\`\`\`
|
|
1288
|
-
|
|
1289
|
-
### Source
|
|
1290
|
-
|
|
1291
|
-
{{file:getting-started/src/ci.ts}}
|
|
1292
|
-
|
|
1293
|
-
### Generated output
|
|
1294
|
-
|
|
1295
|
-
\`chant build\` produces \`.github/workflows/ci.yml\`:
|
|
1296
|
-
|
|
1297
|
-
\`\`\`yaml
|
|
1298
|
-
name: CI
|
|
1299
|
-
on:
|
|
1300
|
-
push:
|
|
1301
|
-
branches:
|
|
1302
|
-
- main
|
|
1303
|
-
pull_request:
|
|
1304
|
-
branches:
|
|
1305
|
-
- main
|
|
1306
|
-
permissions:
|
|
1307
|
-
contents: read
|
|
1308
|
-
jobs:
|
|
1309
|
-
build:
|
|
1310
|
-
runs-on: ubuntu-latest
|
|
1311
|
-
timeout-minutes: 15
|
|
1312
|
-
steps:
|
|
1313
|
-
- name: Checkout
|
|
1314
|
-
uses: actions/checkout@v4
|
|
1315
|
-
- name: Setup Node.js
|
|
1316
|
-
uses: actions/setup-node@v4
|
|
1317
|
-
with:
|
|
1318
|
-
node-version: '22'
|
|
1319
|
-
cache: npm
|
|
1320
|
-
- name: Install
|
|
1321
|
-
run: npm ci
|
|
1322
|
-
- name: Build
|
|
1323
|
-
run: npm run build
|
|
1324
|
-
- name: Test
|
|
1325
|
-
run: npm test
|
|
1326
|
-
\`\`\`
|
|
1327
|
-
|
|
1328
|
-
**Patterns demonstrated:**
|
|
1329
|
-
|
|
1330
|
-
1. **Typed composites** — \`Checkout({})\` and \`SetupNode({...})\` instead of raw \`uses:\` strings
|
|
1331
|
-
2. **Permissions** — explicit \`contents: read\` following least-privilege
|
|
1332
|
-
3. **Timeout** — \`timeoutMinutes: 15\` prevents runaway jobs
|
|
1333
|
-
4. **Trigger scoping** — push and PR on \`main\` only`,
|
|
1334
|
-
},
|
|
1335
|
-
{
|
|
1336
|
-
slug: "skills",
|
|
1337
|
-
title: "AI Skills",
|
|
1338
|
-
description: "AI agent skills bundled with the GitHub Actions lexicon",
|
|
1339
|
-
content: `The GitHub Actions lexicon ships AI skills that teach AI coding agents (like Claude Code) how to build, validate, and deploy GitHub Actions workflows from a chant project.
|
|
1340
|
-
|
|
1341
|
-
## What are skills?
|
|
1342
|
-
|
|
1343
|
-
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.
|
|
1344
|
-
|
|
1345
|
-
## Installation
|
|
1346
|
-
|
|
1347
|
-
When you scaffold a new project with \`chant init --lexicon github\`, skills are installed to \`.claude/skills/\` for automatic discovery by Claude Code.
|
|
1348
|
-
|
|
1349
|
-
For existing projects, create the files manually:
|
|
1350
|
-
|
|
1351
|
-
\`\`\`
|
|
1352
|
-
.claude/
|
|
1353
|
-
skills/
|
|
1354
|
-
chant-github/
|
|
1355
|
-
SKILL.md # skill content
|
|
1356
|
-
\`\`\`
|
|
1357
|
-
|
|
1358
|
-
## Skill: chant-github
|
|
1359
|
-
|
|
1360
|
-
The inline \`chant-github\` skill covers the full workflow lifecycle:
|
|
1361
|
-
|
|
1362
|
-
- **Build** — \`chant build src/ --output .github/workflows/ci.yml\`
|
|
1363
|
-
- **Validate** — \`chant lint src/\`
|
|
1364
|
-
- **Deploy** — commit and push the generated YAML
|
|
1365
|
-
- **Status** — GitHub Actions UI or \`gh run list\`
|
|
1366
|
-
- **Troubleshooting** — lint rule codes (GHA001–GHA020), post-synth checks (GHA006–GHA058)
|
|
1367
|
-
|
|
1368
|
-
The skill is invocable as a slash command: \`/chant-github\`
|
|
1369
|
-
|
|
1370
|
-
## Skill: github-actions-patterns
|
|
1371
|
-
|
|
1372
|
-
A file-based skill loaded from \`src/skills/github-actions-patterns.md\`. It provides pattern knowledge for:
|
|
1373
|
-
|
|
1374
|
-
- **Workflow structure** — name, on, permissions, jobs
|
|
1375
|
-
- **Trigger patterns** — push, pull_request, schedule, workflow_dispatch
|
|
1376
|
-
- **Matrix strategy** — multi-OS, multi-version builds
|
|
1377
|
-
- **Caching** — SetupNode cache option, CacheAction composite
|
|
1378
|
-
- **Permissions** — least-privilege patterns
|
|
1379
|
-
- **Reusable workflows** — ReusableWorkflowCallJob
|
|
1380
|
-
- **Artifacts** — upload/download between jobs
|
|
1381
|
-
- **Concurrency** — group + cancel-in-progress
|
|
1382
|
-
|
|
1383
|
-
## MCP integration
|
|
1384
|
-
|
|
1385
|
-
The lexicon provides MCP (Model Context Protocol) tools and resources that AI agents can use programmatically:
|
|
1386
|
-
|
|
1387
|
-
| MCP tool | Description |
|
|
1388
|
-
|----------|-------------|
|
|
1389
|
-
| \`diff\` | Compare current build output against previous output |
|
|
1390
|
-
| \`github:checks\` | Build the workflow and return its security findings (the GHA checks) |
|
|
1391
|
-
| \`github:workflow\` | Triggers and jobs as written — name, run order, step count |
|
|
1392
|
-
| \`github:references\` | Actions and images pulled in, and whether each is pinned to a commit SHA |
|
|
1393
|
-
| \`github:affected\` | Given a job, the jobs that would re-run because they depend on it |
|
|
1394
|
-
| \`github:workflow-yaml\` | The generated workflow YAML |
|
|
1395
|
-
|
|
1396
|
-
The \`github:*\` tools are **read-only context tools** (#327): each builds from your source and returns what chant already computes — before the workflow runs or merges. None touch the live GitHub instance, run history, or write anything.
|
|
1397
|
-
|
|
1398
|
-
| MCP resource | Description |
|
|
1399
|
-
|--------------|-------------|
|
|
1400
|
-
| \`resource-catalog\` | JSON list of all supported GitHub Actions entity types |
|
|
1401
|
-
| \`examples/basic-ci\` | Example CI workflow with TypeScript source |`,
|
|
1402
|
-
},
|
|
1403
|
-
],
|
|
1404
104
|
basePath: "/chant/lexicons/github/",
|
|
1405
|
-
// Hand-written pages under docs/src/content/docs/ that no sidebar entry
|
|
1406
|
-
// pointed at (#1312).
|
|
1407
|
-
sidebarExtra: [
|
|
1408
|
-
{ label: "Workflows", slug: "workflows" },
|
|
1409
|
-
{ label: "Actions & Composites", slug: "actions" },
|
|
1410
|
-
{ label: "Matrix Strategies", slug: "matrix" },
|
|
1411
|
-
{ label: "Multiple Workflows", slug: "multi-workflow" },
|
|
1412
|
-
],
|
|
1413
105
|
};
|
|
1414
106
|
|
|
1415
107
|
const result = await docsPipeline(config);
|