@intentius/chant-lexicon-github 0.46.0 → 0.49.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/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "f13c6d5badc99a05feb6c2f1172e984576192151b1a62a157d770efa5b1c541c",
|
|
5
5
|
"meta.json": "798c5f5f37b0174756d2451299acfdc95c014f11d06d32b9153bbdfa9f3a580c",
|
|
6
6
|
"types/index.d.ts": "39c0791f0e58025bcef82e0f7a92240508f899fc2771d5dd51b2369b4d330f13",
|
|
7
7
|
"rules/deprecated-action-version.ts": "d41e6e532ab7f623af1bee4ac5279fcb2baada7defa1c5d022a5bc71983e8797",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"rules/gha006.ts": "7e2977d34851ce2ed9f91c4dd78ecda8d4de099ceaac1cd9ab74960a193133a3",
|
|
21
21
|
"rules/gha009.ts": "0f9a261e886309679494da32b72a0d9ea20017e5da75a9d59a04846a0e4d78db",
|
|
22
22
|
"rules/gha011.ts": "53b7ca79b5bf56e5793a9b7a44ae0ac766eb5acf0669005e7810cb7762bab79c",
|
|
23
|
-
"rules/gha013.ts": "
|
|
23
|
+
"rules/gha013.ts": "cd9119154d7b9de94ae3f4d41ad5f09c5757e25a5effddd3d580ef5d1466a8fc",
|
|
24
24
|
"rules/gha017.ts": "ec62dac7f9d69f36978cb461c4ba391a7e445d410bbfa497cddcb1b12cfd5904",
|
|
25
25
|
"rules/gha018.ts": "2c71c5accb96bccfa01075e7f8f4ad66e6d9a68a81b86f89a68cabb9c144e140",
|
|
26
26
|
"rules/gha019.ts": "d0b33d63812c9cba2ebf9f2d85d8cf22068ea96460cd2143bdfb4d2a4d58fe2e",
|
|
@@ -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": "b77a589c318cd23862c320a4e9ba5459696b8192700a8f9a23ff49519149d90b"
|
|
71
71
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gha013.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/gha013.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"gha013.d.ts","sourceRoot":"","sources":["../../../src/lint/post-synth/gha013.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAyC,MAAM,kCAAkC,CAAC;AAG9G,eAAO,MAAM,MAAM,EAAE,cAoCpB,CAAC"}
|
package/dist/manifest.json
CHANGED
package/dist/rules/gha013.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
9
|
-
import { getPrimaryOutput, extractJobs, extractTriggers } from "./yaml-helpers";
|
|
9
|
+
import { getPrimaryOutput, extractJobs, extractTriggers, extractJobPermissions } from "./yaml-helpers";
|
|
10
10
|
|
|
11
11
|
export const gha013: PostSynthCheck = {
|
|
12
12
|
id: "GHA013",
|
|
@@ -21,9 +21,16 @@ export const gha013: PostSynthCheck = {
|
|
|
21
21
|
|
|
22
22
|
if (!triggers["pull_request_target"] && !triggers["workflow_dispatch"]) continue;
|
|
23
23
|
|
|
24
|
+
// chant #1544 — `extractJobs`' `ParsedJob.permissions` field is never
|
|
25
|
+
// populated (its regex-based per-job scan only fills `needs`/`steps`),
|
|
26
|
+
// so this rule read `job.permissions` as always undefined and warned
|
|
27
|
+
// on every job regardless of whether it declared one. `extractJobPermissions`
|
|
28
|
+
// (below) is the structural, `parseYAML`-backed extractor that other
|
|
29
|
+
// permissions-aware checks already use — it actually sees the block.
|
|
24
30
|
const jobs = extractJobs(yaml);
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
const jobPermissions = extractJobPermissions(yaml);
|
|
32
|
+
for (const [jobName] of jobs) {
|
|
33
|
+
if (!jobPermissions.has(jobName)) {
|
|
27
34
|
diagnostics.push({
|
|
28
35
|
checkId: "GHA013",
|
|
29
36
|
severity: "warning",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@intentius/chant-lexicon-github",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.49.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.49.0",
|
|
65
65
|
"typescript": "^5.9.3"
|
|
66
66
|
}
|
|
67
67
|
}
|
|
@@ -50,6 +50,23 @@ jobs:
|
|
|
50
50
|
expect(diags[0].message).toContain("deploy");
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
+
test("does not flag a job that declares job-level permissions (#1544)", () => {
|
|
54
|
+
const yaml = `name: Deploy
|
|
55
|
+
on:
|
|
56
|
+
workflow_dispatch:
|
|
57
|
+
jobs:
|
|
58
|
+
deploy:
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
permissions:
|
|
61
|
+
contents: read
|
|
62
|
+
id-token: write
|
|
63
|
+
steps:
|
|
64
|
+
- run: echo deploy
|
|
65
|
+
`;
|
|
66
|
+
const diags = gha013.check(makeCtx(yaml));
|
|
67
|
+
expect(diags).toHaveLength(0);
|
|
68
|
+
});
|
|
69
|
+
|
|
53
70
|
test("does not flag when trigger is not sensitive", () => {
|
|
54
71
|
const yaml = `name: CI
|
|
55
72
|
on:
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import type { PostSynthCheck, PostSynthContext, PostSynthDiagnostic } from "@intentius/chant/lint/post-synth";
|
|
9
|
-
import { getPrimaryOutput, extractJobs, extractTriggers } from "./yaml-helpers";
|
|
9
|
+
import { getPrimaryOutput, extractJobs, extractTriggers, extractJobPermissions } from "./yaml-helpers";
|
|
10
10
|
|
|
11
11
|
export const gha013: PostSynthCheck = {
|
|
12
12
|
id: "GHA013",
|
|
@@ -21,9 +21,16 @@ export const gha013: PostSynthCheck = {
|
|
|
21
21
|
|
|
22
22
|
if (!triggers["pull_request_target"] && !triggers["workflow_dispatch"]) continue;
|
|
23
23
|
|
|
24
|
+
// chant #1544 — `extractJobs`' `ParsedJob.permissions` field is never
|
|
25
|
+
// populated (its regex-based per-job scan only fills `needs`/`steps`),
|
|
26
|
+
// so this rule read `job.permissions` as always undefined and warned
|
|
27
|
+
// on every job regardless of whether it declared one. `extractJobPermissions`
|
|
28
|
+
// (below) is the structural, `parseYAML`-backed extractor that other
|
|
29
|
+
// permissions-aware checks already use — it actually sees the block.
|
|
24
30
|
const jobs = extractJobs(yaml);
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
const jobPermissions = extractJobPermissions(yaml);
|
|
32
|
+
for (const [jobName] of jobs) {
|
|
33
|
+
if (!jobPermissions.has(jobName)) {
|
|
27
34
|
diagnostics.push({
|
|
28
35
|
checkId: "GHA013",
|
|
29
36
|
severity: "warning",
|