@7n/rules-ci-github 2.4.5 → 2.4.6
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/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/rules/ga/lint_ga/lint_ga.rego +31 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [2.4.6] - 2026-08-29
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- `ga/lint_ga`: `.github/workflows/lint-ga.yml` із джобою, названою НЕ `lint-ga`, більше не дає у wasm-порті (`crates/plugin-ci-github`) одну діагностику `rego-engine-error` замість набору deny. Причина — дві розбіжності `regorus` vs OPA на UNDEFINED-значеннях: shorthand-голова `job_uses_set contains job.steps[_].uses` (і та сама форма в `job_run_blob`) на undefined корені `jobs["lint-ga"]` кидала помилку `eval` замість того щоб дати undefined — переписано в longhand; а `not helper(gha_on.push.branches, …)` з undefined-аргументом у `regorus` давало `not undefined == true` (три зайві deny, коли гілки `on:` немає) — тепер значення звʼязується окремим позитивним виразом. Канон `conftest` НЕ змінився: вихід порту звірено з живим `conftest test` на 11 фікстурах біт-у-біт, набір deny пінить `lint_ga_test.rego` (`test_deny_missing_job`, `test_missing_on_hook_denies_only_pr_paths`) (§2.81)
|
|
8
|
+
|
|
3
9
|
## [2.4.5] - 2026-08-29
|
|
4
10
|
|
|
5
11
|
### Changed
|
package/package.json
CHANGED
|
@@ -14,10 +14,20 @@ gha_on := object.get(input, "on", object.get(input, "true", {}))
|
|
|
14
14
|
|
|
15
15
|
job := input.jobs["lint-ga"]
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
# LONGHAND-форма (`some step in job.steps`), а НЕ shorthand
|
|
18
|
+
# `job_uses_set contains job.steps[_].uses` / `run := job.steps[_].run`:
|
|
19
|
+
# під regorus (wasm-порт `crates/plugin-ci-github`) shorthand кидає помилку
|
|
20
|
+
# eval («item cannot be indexed»), коли `job` undefined — тобто саме тоді,
|
|
21
|
+
# коли `jobs["lint-ga"]` відсутній, — замість того щоб дати undefined і
|
|
22
|
+
# пропустити керування канонічній deny «jobs.lint-ga відсутній».
|
|
23
|
+
# Longhand під regorus дає ТУ САМУ семантику, що й OPA/conftest.
|
|
24
|
+
job_uses_set contains u if {
|
|
25
|
+
some step in job.steps
|
|
26
|
+
u := step.uses
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
job_run_blob := concat("\n", [step.run |
|
|
30
|
+
some step in job.steps
|
|
21
31
|
])
|
|
22
32
|
|
|
23
33
|
expected_name := data.template.snippet.name
|
|
@@ -46,9 +56,9 @@ expected_uses_set contains u if {
|
|
|
46
56
|
# Opt-in для runner-образу, у якому вже є uv та conftest. Мітка runner
|
|
47
57
|
# залишається `ubuntu-latest` для сумісності, але workflow явно декларує
|
|
48
58
|
# джерело tooling, щоб policy не приховувала залежність від custom image.
|
|
49
|
-
preinstalled_ci_tools if
|
|
59
|
+
preinstalled_ci_tools if job.env.NITRA_CI_TOOLS == true
|
|
50
60
|
|
|
51
|
-
preinstalled_ci_tools if
|
|
61
|
+
preinstalled_ci_tools if job.env.NITRA_CI_TOOLS == "true"
|
|
52
62
|
|
|
53
63
|
required_uses_set contains u if {
|
|
54
64
|
not preinstalled_ci_tools
|
|
@@ -70,23 +80,35 @@ expected_run_blob := concat("\n", [r |
|
|
|
70
80
|
|
|
71
81
|
# ── deny rules ─────────────────────────────────────────────────────────────
|
|
72
82
|
|
|
83
|
+
# Три deny нижче спершу ЗВʼЯЗУЮТЬ `actual := gha_on.<hook>.<key>` окремим
|
|
84
|
+
# позитивним виразом, а вже потім негують helper. Це не косметика: у формі
|
|
85
|
+
# `not helper(gha_on.push.branches, …)` undefined-аргумент (гілки `on:` немає)
|
|
86
|
+
# в OPA робить УВЕСЬ вираз undefined (deny мовчить), а в regorus дає
|
|
87
|
+
# `not undefined` == true (deny спрацьовує) — розбіжність порту. Позитивне
|
|
88
|
+
# звʼязування падає однаково в обох двигунах, тож канон і порт збігаються.
|
|
89
|
+
# (`actual_pr_paths` навмисно інший: `object.get(…, [])` — там канон САМЕ
|
|
90
|
+
# СИГНАЛИТЬ про відсутній ключ.)
|
|
91
|
+
|
|
73
92
|
deny contains msg if {
|
|
74
93
|
input.name != expected_name
|
|
75
94
|
msg := sprintf("lint-ga.yml: name має бути \"%v\" (ga.mdc)", [expected_name])
|
|
76
95
|
}
|
|
77
96
|
|
|
78
97
|
deny contains msg if {
|
|
79
|
-
|
|
98
|
+
actual := gha_on.push.branches
|
|
99
|
+
not branches_superset_of(actual, expected_push_branches)
|
|
80
100
|
msg := "lint-ga.yml: on.push.branches має містити dev і main (ga.mdc)"
|
|
81
101
|
}
|
|
82
102
|
|
|
83
103
|
deny contains msg if {
|
|
84
|
-
|
|
104
|
+
actual := gha_on.pull_request.branches
|
|
105
|
+
not branches_superset_of(actual, expected_pr_branches)
|
|
85
106
|
msg := "lint-ga.yml: on.pull_request.branches має містити dev і main (ga.mdc)"
|
|
86
107
|
}
|
|
87
108
|
|
|
88
109
|
deny contains msg if {
|
|
89
|
-
|
|
110
|
+
actual := gha_on.push.paths
|
|
111
|
+
not paths_superset_of(actual, expected_push_paths)
|
|
90
112
|
msg := "lint-ga.yml: on.push.paths має містити .github/actions/** і .github/workflows/** (ga.mdc)"
|
|
91
113
|
}
|
|
92
114
|
|