@intentius/chant-lexicon-github 0.124.31 → 0.124.33
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/action-pins.js +53 -0
- package/dist/codegen/docs-cli.js +2 -0
- package/dist/codegen/docs.js +142 -0
- package/dist/codegen/generate-cli.js +26 -0
- package/dist/codegen/generate-lexicon.js +36 -0
- package/dist/codegen/generate-typescript.js +108 -0
- package/dist/codegen/generate.js +111 -0
- package/dist/codegen/naming.js +49 -0
- package/dist/codegen/package.js +40 -0
- package/dist/codegen/parse.js +595 -0
- package/dist/codegen/patches.js +36 -0
- package/dist/components/ci-jobs.d.ts +7 -0
- package/dist/components/ci-jobs.d.ts.map +1 -1
- package/dist/components/ci-jobs.js +98 -0
- package/dist/components/generate-op-pipeline.js +440 -0
- package/dist/components/generate-op-waves-pipeline.js +158 -0
- package/dist/components/generate-pipeline.d.ts.map +1 -1
- package/dist/components/generate-pipeline.js +481 -0
- package/dist/composites/cache.js +17 -0
- package/dist/composites/catalog.js +859 -0
- package/dist/composites/checkout.js +25 -0
- package/dist/composites/dependabot.js +43 -0
- package/dist/composites/deploy-environment.js +38 -0
- package/dist/composites/docker-build.js +70 -0
- package/dist/composites/download-artifact.js +18 -0
- package/dist/composites/go-ci.js +62 -0
- package/dist/composites/index.js +15 -0
- package/dist/composites/node-ci.js +44 -0
- package/dist/composites/node-pipeline.js +96 -0
- package/dist/composites/pr-plan-report.js +129 -0
- package/dist/composites/python-ci.js +60 -0
- package/dist/composites/setup-go.js +18 -0
- package/dist/composites/setup-node.js +21 -0
- package/dist/composites/setup-python.js +18 -0
- package/dist/composites/upload-artifact.js +19 -0
- package/dist/coverage.js +32 -0
- package/dist/expression.js +177 -0
- package/dist/generated/index.js +26 -0
- package/dist/generated/runtime.js +4 -0
- package/dist/graph-edges.js +174 -0
- package/dist/import/generator.js +108 -0
- package/dist/import/parser.js +69 -0
- package/dist/index.js +22 -0
- package/dist/integrity.json +2 -2
- package/dist/lint/audit-catalog.js +69 -0
- package/dist/lint/audit-lineage.js +168 -0
- package/dist/lint/post-synth/gha006.js +50 -0
- package/dist/lint/post-synth/gha009.js +35 -0
- package/dist/lint/post-synth/gha011.js +34 -0
- package/dist/lint/post-synth/gha013.js +40 -0
- package/dist/lint/post-synth/gha017.js +25 -0
- package/dist/lint/post-synth/gha018.js +33 -0
- package/dist/lint/post-synth/gha019.js +58 -0
- package/dist/lint/post-synth/gha021.js +42 -0
- package/dist/lint/post-synth/gha022.js +44 -0
- package/dist/lint/post-synth/gha023.js +37 -0
- package/dist/lint/post-synth/gha024.js +32 -0
- package/dist/lint/post-synth/gha025.js +33 -0
- package/dist/lint/post-synth/gha026.js +32 -0
- package/dist/lint/post-synth/gha027.js +46 -0
- package/dist/lint/post-synth/gha028.js +28 -0
- package/dist/lint/post-synth/gha029.js +56 -0
- package/dist/lint/post-synth/gha030.js +35 -0
- package/dist/lint/post-synth/gha031.js +75 -0
- package/dist/lint/post-synth/gha032.js +35 -0
- package/dist/lint/post-synth/gha033.js +39 -0
- package/dist/lint/post-synth/gha034.js +35 -0
- package/dist/lint/post-synth/gha035.js +50 -0
- package/dist/lint/post-synth/gha036.js +37 -0
- package/dist/lint/post-synth/gha037.js +41 -0
- package/dist/lint/post-synth/gha038.js +35 -0
- package/dist/lint/post-synth/gha039.js +34 -0
- package/dist/lint/post-synth/gha040.js +36 -0
- package/dist/lint/post-synth/gha041.js +32 -0
- package/dist/lint/post-synth/gha042.js +33 -0
- package/dist/lint/post-synth/gha043.js +35 -0
- package/dist/lint/post-synth/gha044.js +36 -0
- package/dist/lint/post-synth/gha045.js +33 -0
- package/dist/lint/post-synth/gha046.js +55 -0
- package/dist/lint/post-synth/gha047.js +44 -0
- package/dist/lint/post-synth/gha048.js +34 -0
- package/dist/lint/post-synth/gha049.js +36 -0
- package/dist/lint/post-synth/gha050.js +37 -0
- package/dist/lint/post-synth/gha051.js +38 -0
- package/dist/lint/post-synth/gha052.js +35 -0
- package/dist/lint/post-synth/gha053.js +34 -0
- package/dist/lint/post-synth/gha054.js +35 -0
- package/dist/lint/post-synth/gha055.js +44 -0
- package/dist/lint/post-synth/gha056.js +32 -0
- package/dist/lint/post-synth/gha057.js +35 -0
- package/dist/lint/post-synth/gha058.js +42 -0
- package/dist/lint/post-synth/gha059.js +119 -0
- package/dist/lint/post-synth/gha060.js +129 -0
- package/dist/lint/post-synth/gha061.js +78 -0
- package/dist/lint/post-synth/gha062.js +65 -0
- package/dist/lint/post-synth/gha063.js +56 -0
- package/dist/lint/post-synth/gha064.js +47 -0
- package/dist/lint/post-synth/gha065.js +125 -0
- package/dist/lint/post-synth/gha066.js +40 -0
- package/dist/lint/post-synth/gha067.js +75 -0
- package/dist/lint/post-synth/gha068.js +47 -0
- package/dist/lint/post-synth/gha069.js +99 -0
- package/dist/lint/post-synth/index.js +114 -0
- package/dist/lint/post-synth/yaml-helpers.js +465 -0
- package/dist/lint/rules/data/action-usage-policy.js +16 -0
- package/dist/lint/rules/data/advisory-feed.js +15 -0
- package/dist/lint/rules/data/deprecated-versions.js +14 -0
- package/dist/lint/rules/data/flagged-actions.js +18 -0
- package/dist/lint/rules/data/known-action-slugs.js +38 -0
- package/dist/lint/rules/data/known-actions.js +12 -0
- package/dist/lint/rules/data/preinstalled-tools.js +36 -0
- package/dist/lint/rules/data/recommended-inputs.js +9 -0
- package/dist/lint/rules/data/risky-features.js +22 -0
- package/dist/lint/rules/data/secret-patterns.js +30 -0
- package/dist/lint/rules/data/trusted-action-owners.js +12 -0
- package/dist/lint/rules/data/untrusted-contexts.js +44 -0
- package/dist/lint/rules/deprecated-action-version.js +44 -0
- package/dist/lint/rules/detect-secrets.js +45 -0
- package/dist/lint/rules/extract-inline-structs.js +55 -0
- package/dist/lint/rules/file-job-limit.js +43 -0
- package/dist/lint/rules/index.js +16 -0
- package/dist/lint/rules/job-timeout.js +53 -0
- package/dist/lint/rules/missing-recommended-inputs.js +51 -0
- package/dist/lint/rules/no-hardcoded-secrets.js +39 -0
- package/dist/lint/rules/no-raw-expressions.js +44 -0
- package/dist/lint/rules/suggest-cache.js +60 -0
- package/dist/lint/rules/use-condition-builders.js +37 -0
- package/dist/lint/rules/use-matrix-builder.js +36 -0
- package/dist/lint/rules/use-typed-actions.js +41 -0
- package/dist/lint/rules/validate-concurrency.js +59 -0
- package/dist/lsp/completions.d.ts.map +1 -1
- package/dist/lsp/completions.js +18 -0
- package/dist/lsp/hover.d.ts.map +1 -1
- package/dist/lsp/hover.js +33 -0
- package/dist/manifest.json +1 -1
- package/dist/mcp/context-tools.js +152 -0
- package/dist/package-cli.js +20 -0
- package/dist/plugin.js +344 -0
- package/dist/serializer.js +572 -0
- package/dist/spec/fetch.js +46 -0
- package/dist/validate-cli.js +16 -0
- package/dist/validate.js +38 -0
- package/dist/variables.js +41 -0
- package/package.json +6 -6
- package/src/codegen/package.ts +2 -2
- package/src/components/__fixtures__/pr-loop-build.github.golden.yml +6 -2
- package/src/components/__fixtures__/pr-loop-record.github.golden.yml +74 -0
- package/src/components/__fixtures__/pr-loop-waves.github.golden.yml +178 -0
- package/src/components/__fixtures__/pr-loop.github.golden.yml +6 -2
- package/src/components/ci-jobs.ts +16 -2
- package/src/components/generate-op-pipeline.test.ts +11 -0
- package/src/components/generate-op-pipeline.ts +3 -3
- package/src/components/generate-pipeline.ts +74 -31
- package/src/components/generate-pr-pipeline.test.ts +99 -29
- package/src/components/generate-pr-waves-pipeline.test.ts +117 -0
- package/src/lsp/completions.ts +2 -1
- package/src/lsp/hover.ts +2 -1
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Actions predefined context variable references.
|
|
3
|
+
*
|
|
4
|
+
* These provide type-safe access to GitHub and Runner context values
|
|
5
|
+
* that expand to `${{ context.property }}` expressions in YAML.
|
|
6
|
+
*/
|
|
7
|
+
import { Expression } from "./expression.js";
|
|
8
|
+
export const GitHub = {
|
|
9
|
+
Ref: /* @__PURE__ */ new Expression("github.ref"),
|
|
10
|
+
RefName: /* @__PURE__ */ new Expression("github.ref_name"),
|
|
11
|
+
RefType: /* @__PURE__ */ new Expression("github.ref_type"),
|
|
12
|
+
Sha: /* @__PURE__ */ new Expression("github.sha"),
|
|
13
|
+
Actor: /* @__PURE__ */ new Expression("github.actor"),
|
|
14
|
+
TriggeringActor: /* @__PURE__ */ new Expression("github.triggering_actor"),
|
|
15
|
+
Repository: /* @__PURE__ */ new Expression("github.repository"),
|
|
16
|
+
RepositoryOwner: /* @__PURE__ */ new Expression("github.repository_owner"),
|
|
17
|
+
EventName: /* @__PURE__ */ new Expression("github.event_name"),
|
|
18
|
+
Event: /* @__PURE__ */ new Expression("github.event"),
|
|
19
|
+
RunId: /* @__PURE__ */ new Expression("github.run_id"),
|
|
20
|
+
RunNumber: /* @__PURE__ */ new Expression("github.run_number"),
|
|
21
|
+
RunAttempt: /* @__PURE__ */ new Expression("github.run_attempt"),
|
|
22
|
+
Workflow: /* @__PURE__ */ new Expression("github.workflow"),
|
|
23
|
+
WorkflowRef: /* @__PURE__ */ new Expression("github.workflow_ref"),
|
|
24
|
+
Workspace: /* @__PURE__ */ new Expression("github.workspace"),
|
|
25
|
+
Token: /* @__PURE__ */ new Expression("github.token"),
|
|
26
|
+
Job: /* @__PURE__ */ new Expression("github.job"),
|
|
27
|
+
HeadRef: /* @__PURE__ */ new Expression("github.head_ref"),
|
|
28
|
+
BaseRef: /* @__PURE__ */ new Expression("github.base_ref"),
|
|
29
|
+
ServerUrl: /* @__PURE__ */ new Expression("github.server_url"),
|
|
30
|
+
ApiUrl: /* @__PURE__ */ new Expression("github.api_url"),
|
|
31
|
+
GraphqlUrl: /* @__PURE__ */ new Expression("github.graphql_url"),
|
|
32
|
+
Action: /* @__PURE__ */ new Expression("github.action"),
|
|
33
|
+
ActionPath: /* @__PURE__ */ new Expression("github.action_path"),
|
|
34
|
+
};
|
|
35
|
+
export const Runner = {
|
|
36
|
+
Os: /* @__PURE__ */ new Expression("runner.os"),
|
|
37
|
+
Arch: /* @__PURE__ */ new Expression("runner.arch"),
|
|
38
|
+
Name: /* @__PURE__ */ new Expression("runner.name"),
|
|
39
|
+
Temp: /* @__PURE__ */ new Expression("runner.temp"),
|
|
40
|
+
ToolCache: /* @__PURE__ */ new Expression("runner.tool_cache"),
|
|
41
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-github",
|
|
3
|
-
"version": "0.124.
|
|
3
|
+
"version": "0.124.33",
|
|
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",
|
|
@@ -32,17 +32,17 @@
|
|
|
32
32
|
".": {
|
|
33
33
|
"development": "./src/index.ts",
|
|
34
34
|
"types": "./dist/index.d.ts",
|
|
35
|
-
"default": "./
|
|
35
|
+
"default": "./dist/index.js"
|
|
36
36
|
},
|
|
37
37
|
"./*": {
|
|
38
38
|
"development": "./src/*.ts",
|
|
39
39
|
"types": "./dist/*.d.ts",
|
|
40
|
-
"default": "./
|
|
40
|
+
"default": "./dist/*.js"
|
|
41
41
|
},
|
|
42
42
|
"./lint/post-synth": {
|
|
43
43
|
"development": "./src/lint/post-synth/index.ts",
|
|
44
44
|
"types": "./dist/lint/post-synth/index.d.ts",
|
|
45
|
-
"default": "./
|
|
45
|
+
"default": "./dist/lint/post-synth/index.js"
|
|
46
46
|
},
|
|
47
47
|
"./manifest": "./dist/manifest.json",
|
|
48
48
|
"./meta": "./dist/meta.json",
|
|
@@ -54,13 +54,13 @@
|
|
|
54
54
|
"validate": "tsx src/validate-cli.ts",
|
|
55
55
|
"docs": "tsx src/codegen/docs-cli.ts",
|
|
56
56
|
"prepack": "npm run generate && npm run bundle && npm run validate && npm run build",
|
|
57
|
-
"build": "../../scripts/tsc7.sh -p tsconfig.build.json && tsc-alias -p tsconfig.build.json
|
|
57
|
+
"build": "../../scripts/tsc7.sh -p tsconfig.build.json --sourceMap false && tsc-alias -p tsconfig.build.json"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@intentius/chant": "*",
|
|
61
61
|
"typescript": "^5.9.3"
|
|
62
62
|
},
|
|
63
63
|
"peerDependencies": {
|
|
64
|
-
"@intentius/chant": "^0.124.
|
|
64
|
+
"@intentius/chant": "^0.124.33"
|
|
65
65
|
}
|
|
66
66
|
}
|
package/src/codegen/package.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { readFileSync } from "fs";
|
|
6
6
|
import { githubPlugin } from "../plugin";
|
|
7
7
|
import { join, dirname } from "path";
|
|
8
|
-
import {
|
|
8
|
+
import { moduleSourceDir } from "@intentius/chant/module-source";
|
|
9
9
|
import type { IntrinsicDef } from "@intentius/chant/lexicon";
|
|
10
10
|
import {
|
|
11
11
|
packagePipeline,
|
|
@@ -17,7 +17,7 @@ import { generate } from "./generate";
|
|
|
17
17
|
|
|
18
18
|
export type { PackageOptions, PackageResult };
|
|
19
19
|
|
|
20
|
-
const pkgDir = dirname(
|
|
20
|
+
const pkgDir = dirname(moduleSourceDir(import.meta.url));
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Package the GitHub Actions lexicon into a distributable BundleSpec.
|
|
@@ -34,7 +34,8 @@ jobs:
|
|
|
34
34
|
BASE_SHA: '${{ github.event.pull_request.base.sha }}'
|
|
35
35
|
PR_NUMBER: '${{ github.event.pull_request.number }}'
|
|
36
36
|
GITHUB_TOKEN: '${{ github.token }}'
|
|
37
|
-
|
|
37
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
38
|
+
run: chant ci run plan --in-place --no-push --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --forge github
|
|
38
39
|
- name: Keep the plan report
|
|
39
40
|
if: always()
|
|
40
41
|
uses: actions/upload-artifact@v4
|
|
@@ -73,7 +74,10 @@ jobs:
|
|
|
73
74
|
env:
|
|
74
75
|
BASE_SHA: '${{ github.event.before }}'
|
|
75
76
|
GITHUB_TOKEN: '${{ github.token }}'
|
|
76
|
-
|
|
77
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
78
|
+
run: |
|
|
79
|
+
if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then git fetch origin "main" && BASE_SHA="$(git merge-base FETCH_HEAD "$GITHUB_SHA")"; if [ "$BASE_SHA" = "$GITHUB_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$GITHUB_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; export BASE_SHA
|
|
80
|
+
chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge github
|
|
77
81
|
- name: Keep the record for a re-run
|
|
78
82
|
if: always()
|
|
79
83
|
uses: actions/cache/save@v4
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
name: chant-pr-prod
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
CHANT_ENV: prod
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
plan:
|
|
16
|
+
if: github.event_name == 'pull_request'
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
container: node:22
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
pull-requests: write
|
|
22
|
+
statuses: write
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0
|
|
27
|
+
- run: command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
|
|
28
|
+
- name: Plan the members this pull request reaches
|
|
29
|
+
env:
|
|
30
|
+
BASE_SHA: '${{ github.event.pull_request.base.sha }}'
|
|
31
|
+
PR_NUMBER: '${{ github.event.pull_request.number }}'
|
|
32
|
+
GITHUB_TOKEN: '${{ github.token }}'
|
|
33
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
34
|
+
run: chant ci run plan --in-place --no-push --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --forge github
|
|
35
|
+
- name: Keep the plan report
|
|
36
|
+
if: always()
|
|
37
|
+
uses: actions/upload-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: chant-pr-plan
|
|
40
|
+
path: .chant/pr
|
|
41
|
+
if-no-files-found: ignore
|
|
42
|
+
include-hidden-files: true
|
|
43
|
+
record:
|
|
44
|
+
if: github.event_name == 'push'
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
container: node:22
|
|
47
|
+
concurrency:
|
|
48
|
+
group: chant-record-prod
|
|
49
|
+
cancel-in-progress: false
|
|
50
|
+
permissions:
|
|
51
|
+
contents: write
|
|
52
|
+
pull-requests: write
|
|
53
|
+
statuses: write
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v7
|
|
56
|
+
with:
|
|
57
|
+
fetch-depth: 0
|
|
58
|
+
- run: command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
|
|
59
|
+
- name: Record the plan on the merged commit; nothing applies
|
|
60
|
+
env:
|
|
61
|
+
BASE_SHA: '${{ github.event.before }}'
|
|
62
|
+
GITHUB_TOKEN: '${{ github.token }}'
|
|
63
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
64
|
+
run: |
|
|
65
|
+
if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then git fetch origin "main" && BASE_SHA="$(git merge-base FETCH_HEAD "$GITHUB_SHA")"; if [ "$BASE_SHA" = "$GITHUB_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$GITHUB_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; export BASE_SHA
|
|
66
|
+
chant ci run record --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge github
|
|
67
|
+
- name: Keep the record report
|
|
68
|
+
if: always()
|
|
69
|
+
uses: actions/upload-artifact@v4
|
|
70
|
+
with:
|
|
71
|
+
name: chant-pr-record
|
|
72
|
+
path: .chant/pr
|
|
73
|
+
if-no-files-found: ignore
|
|
74
|
+
include-hidden-files: true
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
name: chant-pr-prod
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- main
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
CHANT_ENV: prod
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
plan:
|
|
16
|
+
if: github.event_name == 'pull_request'
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
container: node:22
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
pull-requests: write
|
|
22
|
+
statuses: write
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v7
|
|
25
|
+
with:
|
|
26
|
+
fetch-depth: 0
|
|
27
|
+
- run: command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
|
|
28
|
+
- name: Plan the members this pull request reaches
|
|
29
|
+
env:
|
|
30
|
+
BASE_SHA: '${{ github.event.pull_request.base.sha }}'
|
|
31
|
+
PR_NUMBER: '${{ github.event.pull_request.number }}'
|
|
32
|
+
GITHUB_TOKEN: '${{ github.token }}'
|
|
33
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
34
|
+
run: chant ci run plan --in-place --no-push --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --forge github --wave-gate release
|
|
35
|
+
- name: Keep the plan report
|
|
36
|
+
if: always()
|
|
37
|
+
uses: actions/upload-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: chant-pr-plan
|
|
40
|
+
path: .chant/pr
|
|
41
|
+
if-no-files-found: ignore
|
|
42
|
+
include-hidden-files: true
|
|
43
|
+
apply-wave-1:
|
|
44
|
+
if: github.event_name == 'push'
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
container: node:22
|
|
47
|
+
concurrency:
|
|
48
|
+
group: chant-apply-prod
|
|
49
|
+
cancel-in-progress: false
|
|
50
|
+
permissions:
|
|
51
|
+
contents: write
|
|
52
|
+
pull-requests: write
|
|
53
|
+
statuses: write
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v7
|
|
56
|
+
with:
|
|
57
|
+
fetch-depth: 0
|
|
58
|
+
- run: command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
|
|
59
|
+
- name: Restore the newest record of this commit's apply
|
|
60
|
+
uses: actions/cache/restore@v4
|
|
61
|
+
with:
|
|
62
|
+
path: .chant/pr-resume/pr-apply.json
|
|
63
|
+
key: chant-apply-prod-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}-wave-1
|
|
64
|
+
restore-keys: chant-apply-prod-${{ github.sha }}-
|
|
65
|
+
- name: Apply wave 1, under the approval its plan has
|
|
66
|
+
env:
|
|
67
|
+
BASE_SHA: '${{ github.event.before }}'
|
|
68
|
+
GITHUB_TOKEN: '${{ github.token }}'
|
|
69
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
70
|
+
run: |
|
|
71
|
+
if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then git fetch origin "main" && BASE_SHA="$(git merge-base FETCH_HEAD "$GITHUB_SHA")"; if [ "$BASE_SHA" = "$GITHUB_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$GITHUB_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; export BASE_SHA
|
|
72
|
+
chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge github --wave-gate release --wave 1
|
|
73
|
+
- name: Keep the record for the next wave and a re-run
|
|
74
|
+
if: always()
|
|
75
|
+
uses: actions/cache/save@v4
|
|
76
|
+
with:
|
|
77
|
+
path: .chant/pr-resume/pr-apply.json
|
|
78
|
+
key: chant-apply-prod-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}-wave-1
|
|
79
|
+
- name: Keep the wave 1 apply report
|
|
80
|
+
if: always()
|
|
81
|
+
uses: actions/upload-artifact@v4
|
|
82
|
+
with:
|
|
83
|
+
name: chant-pr-apply-wave-1
|
|
84
|
+
path: .chant/pr
|
|
85
|
+
if-no-files-found: ignore
|
|
86
|
+
include-hidden-files: true
|
|
87
|
+
apply-wave-2:
|
|
88
|
+
if: github.event_name == 'push'
|
|
89
|
+
runs-on: ubuntu-latest
|
|
90
|
+
needs:
|
|
91
|
+
- apply-wave-1
|
|
92
|
+
container: node:22
|
|
93
|
+
concurrency:
|
|
94
|
+
group: chant-apply-prod
|
|
95
|
+
cancel-in-progress: false
|
|
96
|
+
permissions:
|
|
97
|
+
contents: write
|
|
98
|
+
pull-requests: write
|
|
99
|
+
statuses: write
|
|
100
|
+
steps:
|
|
101
|
+
- uses: actions/checkout@v7
|
|
102
|
+
with:
|
|
103
|
+
fetch-depth: 0
|
|
104
|
+
- run: command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
|
|
105
|
+
- name: Restore the newest record of this commit's apply
|
|
106
|
+
uses: actions/cache/restore@v4
|
|
107
|
+
with:
|
|
108
|
+
path: .chant/pr-resume/pr-apply.json
|
|
109
|
+
key: chant-apply-prod-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}-wave-2
|
|
110
|
+
restore-keys: chant-apply-prod-${{ github.sha }}-
|
|
111
|
+
- name: Apply wave 2, under the approval its plan has
|
|
112
|
+
env:
|
|
113
|
+
BASE_SHA: '${{ github.event.before }}'
|
|
114
|
+
GITHUB_TOKEN: '${{ github.token }}'
|
|
115
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
116
|
+
run: |
|
|
117
|
+
if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then git fetch origin "main" && BASE_SHA="$(git merge-base FETCH_HEAD "$GITHUB_SHA")"; if [ "$BASE_SHA" = "$GITHUB_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$GITHUB_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; export BASE_SHA
|
|
118
|
+
chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge github --wave-gate release --wave 2
|
|
119
|
+
- name: Keep the record for the next wave and a re-run
|
|
120
|
+
if: always()
|
|
121
|
+
uses: actions/cache/save@v4
|
|
122
|
+
with:
|
|
123
|
+
path: .chant/pr-resume/pr-apply.json
|
|
124
|
+
key: chant-apply-prod-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}-wave-2
|
|
125
|
+
- name: Keep the wave 2 apply report
|
|
126
|
+
if: always()
|
|
127
|
+
uses: actions/upload-artifact@v4
|
|
128
|
+
with:
|
|
129
|
+
name: chant-pr-apply-wave-2
|
|
130
|
+
path: .chant/pr
|
|
131
|
+
if-no-files-found: ignore
|
|
132
|
+
include-hidden-files: true
|
|
133
|
+
apply-wave-3:
|
|
134
|
+
if: github.event_name == 'push'
|
|
135
|
+
runs-on: ubuntu-latest
|
|
136
|
+
needs:
|
|
137
|
+
- apply-wave-2
|
|
138
|
+
container: node:22
|
|
139
|
+
concurrency:
|
|
140
|
+
group: chant-apply-prod
|
|
141
|
+
cancel-in-progress: false
|
|
142
|
+
permissions:
|
|
143
|
+
contents: write
|
|
144
|
+
pull-requests: write
|
|
145
|
+
statuses: write
|
|
146
|
+
steps:
|
|
147
|
+
- uses: actions/checkout@v7
|
|
148
|
+
with:
|
|
149
|
+
fetch-depth: 0
|
|
150
|
+
- run: command -v tofu >/dev/null 2>&1 || (curl -fsSL https://get.opentofu.org/install-opentofu.sh -o /tmp/install-opentofu.sh && sh /tmp/install-opentofu.sh --install-method standalone)
|
|
151
|
+
- name: Restore the newest record of this commit's apply
|
|
152
|
+
uses: actions/cache/restore@v4
|
|
153
|
+
with:
|
|
154
|
+
path: .chant/pr-resume/pr-apply.json
|
|
155
|
+
key: chant-apply-prod-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}-wave-3
|
|
156
|
+
restore-keys: chant-apply-prod-${{ github.sha }}-
|
|
157
|
+
- name: Apply wave 3, under the approval its plan has
|
|
158
|
+
env:
|
|
159
|
+
BASE_SHA: '${{ github.event.before }}'
|
|
160
|
+
GITHUB_TOKEN: '${{ github.token }}'
|
|
161
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
162
|
+
run: |
|
|
163
|
+
if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then git fetch origin "main" && BASE_SHA="$(git merge-base FETCH_HEAD "$GITHUB_SHA")"; if [ "$BASE_SHA" = "$GITHUB_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$GITHUB_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; export BASE_SHA
|
|
164
|
+
chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge github --wave-gate release --wave 3
|
|
165
|
+
- name: Keep the record for the next wave and a re-run
|
|
166
|
+
if: always()
|
|
167
|
+
uses: actions/cache/save@v4
|
|
168
|
+
with:
|
|
169
|
+
path: .chant/pr-resume/pr-apply.json
|
|
170
|
+
key: chant-apply-prod-${{ github.sha }}-${{ github.run_id }}-${{ github.run_attempt }}-wave-3
|
|
171
|
+
- name: Keep the wave 3 apply report
|
|
172
|
+
if: always()
|
|
173
|
+
uses: actions/upload-artifact@v4
|
|
174
|
+
with:
|
|
175
|
+
name: chant-pr-apply-wave-3
|
|
176
|
+
path: .chant/pr
|
|
177
|
+
if-no-files-found: ignore
|
|
178
|
+
include-hidden-files: true
|
|
@@ -30,7 +30,8 @@ jobs:
|
|
|
30
30
|
BASE_SHA: '${{ github.event.pull_request.base.sha }}'
|
|
31
31
|
PR_NUMBER: '${{ github.event.pull_request.number }}'
|
|
32
32
|
GITHUB_TOKEN: '${{ github.token }}'
|
|
33
|
-
|
|
33
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
34
|
+
run: chant ci run plan --in-place --no-push --base "$BASE_SHA" --pr "$PR_NUMBER" --env prod --gate pr-apply --forge github
|
|
34
35
|
- name: Keep the plan report
|
|
35
36
|
if: always()
|
|
36
37
|
uses: actions/upload-artifact@v4
|
|
@@ -65,7 +66,10 @@ jobs:
|
|
|
65
66
|
env:
|
|
66
67
|
BASE_SHA: '${{ github.event.before }}'
|
|
67
68
|
GITHUB_TOKEN: '${{ github.token }}'
|
|
68
|
-
|
|
69
|
+
CHANT_RUNNER_KEY: '${{ secrets.CHANT_RUNNER_KEY }}'
|
|
70
|
+
run: |
|
|
71
|
+
if [ -z "$BASE_SHA" ] || [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then git fetch origin "main" && BASE_SHA="$(git merge-base FETCH_HEAD "$GITHUB_SHA")"; if [ "$BASE_SHA" = "$GITHUB_SHA" ]; then BASE_SHA="$(git rev-parse --verify --quiet "$GITHUB_SHA^" || echo 4b825dc642cb6eb9a060e54bf8d69288fbee4904)"; fi; fi; export BASE_SHA
|
|
72
|
+
chant ci run apply --in-place --base "$BASE_SHA" --env prod --gate pr-apply --forge github
|
|
69
73
|
- name: Keep the record for a re-run
|
|
70
74
|
if: always()
|
|
71
75
|
uses: actions/cache/save@v4
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { emitYAML, emitYAMLEntry } from "@intentius/chant/yaml";
|
|
12
|
-
import { GITHUB_JOB_TOKEN, pushBranches } from "@intentius/chant/ci-jobs";
|
|
12
|
+
import { BUILD_REQUEST_TAGS, GITHUB_JOB_TOKEN, pushBranches } from "@intentius/chant/ci-jobs";
|
|
13
13
|
import type { OpTrigger } from "@intentius/chant/lexicon";
|
|
14
14
|
import { actionRef } from "../action-pins";
|
|
15
15
|
|
|
@@ -70,10 +70,24 @@ export function onTrigger(trigger: OpTrigger): Record<string, unknown> {
|
|
|
70
70
|
case "pull_request":
|
|
71
71
|
return { pull_request: trigger.branches && trigger.branches.length > 0 ? { branches: trigger.branches } : {} };
|
|
72
72
|
case "push":
|
|
73
|
-
|
|
73
|
+
// #4169: a newest build runs at each build request's tag too, and by hand.
|
|
74
|
+
return trigger.build === "newest"
|
|
75
|
+
? { push: { branches: pushBranches(trigger.branches), tags: [BUILD_REQUEST_TAGS] }, workflow_dispatch: {} }
|
|
76
|
+
: { push: { branches: pushBranches(trigger.branches) } };
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
|
|
80
|
+
/**
|
|
81
|
+
* A push Op's concurrency group (#4169): one per commit under `build:
|
|
82
|
+
* "every"`, so no push cancels or replaces another's run; one per ref under
|
|
83
|
+
* `newest`, so the newest push waits and each build request's tag runs on its
|
|
84
|
+
* own; and the Op's own name otherwise, one run at a time.
|
|
85
|
+
*/
|
|
86
|
+
export function opConcurrencyGroup(jobName: string, trigger: OpTrigger): string {
|
|
87
|
+
if (trigger.kind !== "push" || !trigger.build) return jobName;
|
|
88
|
+
return trigger.build === "every" ? `${jobName}-\${{ github.sha }}` : `${jobName}-\${{ github.ref }}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
77
91
|
/**
|
|
78
92
|
* A workflow document before emission. Every generator's document is one of
|
|
79
93
|
* these; each leaves out the sections it has no use for.
|
|
@@ -208,6 +208,17 @@ describe("generateGithubOpPipeline: trigger kinds (#2084)", () => {
|
|
|
208
208
|
expect(result.jobs[0].trigger).toEqual({ kind: "push", branches: ["release"] });
|
|
209
209
|
});
|
|
210
210
|
|
|
211
|
+
test("a push trigger's build (#4169): newest runs at build request tags and by hand, one group per ref; every, one group per commit", () => {
|
|
212
|
+
const newest = parseFile(generateGithubOpPipeline([{ name: "suites", trigger: { kind: "push", build: "newest" } }]).files[0].yaml);
|
|
213
|
+
expect(newest.on).toEqual({ push: { branches: ["main"], tags: ["ci/build/**"] }, workflow_dispatch: {} });
|
|
214
|
+
expect(newest.concurrency).toEqual({ group: "suites-${{ github.ref }}", "cancel-in-progress": false });
|
|
215
|
+
const every = parseFile(generateGithubOpPipeline([{ name: "suites", trigger: { kind: "push", build: "every" } }]).files[0].yaml);
|
|
216
|
+
expect(every.on).toEqual({ push: { branches: ["main"] } });
|
|
217
|
+
expect(every.concurrency).toEqual({ group: "suites-${{ github.sha }}", "cancel-in-progress": false });
|
|
218
|
+
const plain = parseFile(generateGithubOpPipeline([{ name: "suites", trigger: { kind: "push" } }]).files[0].yaml);
|
|
219
|
+
expect(plain.concurrency).toEqual({ group: "suites", "cancel-in-progress": false });
|
|
220
|
+
});
|
|
221
|
+
|
|
211
222
|
test("push trigger defaults to the repository default branch (main) when branches is omitted", () => {
|
|
212
223
|
const result = generateGithubOpPipeline([{ name: "tf-apply", trigger: { kind: "push" } }]);
|
|
213
224
|
const doc = parseFile(result.files[0].yaml);
|
|
@@ -95,7 +95,7 @@ import type {
|
|
|
95
95
|
PipelineMember,
|
|
96
96
|
ScheduledOpSpec,
|
|
97
97
|
} from "@intentius/chant/lexicon";
|
|
98
|
-
import { checkoutStep, concurrency, emitWorkflowYAML, jobTokenEnv, onTrigger, runSteps } from "./ci-jobs";
|
|
98
|
+
import { checkoutStep, concurrency, emitWorkflowYAML, jobTokenEnv, onTrigger, opConcurrencyGroup, runSteps } from "./ci-jobs";
|
|
99
99
|
|
|
100
100
|
export type { GenerateGithubOpOptions, GenerateGithubOpResult };
|
|
101
101
|
|
|
@@ -455,8 +455,8 @@ export function buildGithubOpPipelineDocs(
|
|
|
455
455
|
on: onTrigger(trigger),
|
|
456
456
|
...nonEmpty("env", options.variables),
|
|
457
457
|
// One run at a time per Op — a slow audit must not overlap its own next
|
|
458
|
-
// scheduled trigger.
|
|
459
|
-
concurrency: concurrency(jobName),
|
|
458
|
+
// scheduled trigger. A push Op's `build` (#4169) widens the group.
|
|
459
|
+
concurrency: concurrency(opConcurrencyGroup(jobName, trigger)),
|
|
460
460
|
permissions: mergePermissions(
|
|
461
461
|
spec.name,
|
|
462
462
|
permissionsFor(findingMode, trigger),
|