@nitra/cursor 1.8.7 → 1.8.9
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/bin/n-cursor.js +1 -4
- package/mdc/ga.mdc +23 -0
- package/mdc/k8s.mdc +1 -0
- package/package.json +1 -1
- package/scripts/check-ga.mjs +39 -12
package/bin/n-cursor.js
CHANGED
|
@@ -424,10 +424,7 @@ async function removeOrphanManagedSkillDirs(skillsRoot, configSkills) {
|
|
|
424
424
|
* @returns {Promise<void>}
|
|
425
425
|
*/
|
|
426
426
|
async function syncClaudeMd(configRules, configSkills) {
|
|
427
|
-
const lines = [
|
|
428
|
-
`<!-- Цей файл генерується автоматично через \`npx ${PACKAGE_NAME}\`. Не редагуй вручну. -->`,
|
|
429
|
-
'',
|
|
430
|
-
]
|
|
427
|
+
const lines = [`<!-- Цей файл генерується автоматично через \`npx ${PACKAGE_NAME}\`. Не редагуй вручну. -->`, '']
|
|
431
428
|
|
|
432
429
|
for (const rule of configRules) {
|
|
433
430
|
const fileName = `${RULE_PREFIX}${normalizeRuleName(rule)}`
|
package/mdc/ga.mdc
CHANGED
|
@@ -116,6 +116,29 @@ jobs:
|
|
|
116
116
|
}
|
|
117
117
|
```
|
|
118
118
|
|
|
119
|
+
**ЗАБОРОНЕНО** дублювати кроки встановлення Bun та кешування безпосередньо у workflow файлах. Завжди використовуй локальний composite action.
|
|
120
|
+
|
|
121
|
+
### Приклад (НЕПРАВИЛЬНО)
|
|
122
|
+
|
|
123
|
+
```yaml
|
|
124
|
+
steps:
|
|
125
|
+
- uses: actions/checkout@v6
|
|
126
|
+
- uses: oven-sh/setup-bun@v2
|
|
127
|
+
- uses: actions/cache@v5
|
|
128
|
+
# ... багато рядків кешування ...
|
|
129
|
+
- run: bun install --frozen-lockfile
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Приклад (ПРАВИЛЬНО)
|
|
133
|
+
|
|
134
|
+
```yaml
|
|
135
|
+
steps:
|
|
136
|
+
- uses: actions/checkout@v6
|
|
137
|
+
with:
|
|
138
|
+
persist-credentials: false
|
|
139
|
+
- uses: ./.github/actions/setup-bun-deps
|
|
140
|
+
```
|
|
141
|
+
|
|
119
142
|
**Лінт:** [actionlint](https://github.com/rhysd/actionlint) через [node-actionlint](https://www.npmjs.com/package/node-actionlint); [zizmor](https://docs.zizmor.sh) — `uvx`, офлайн. Скрипт у корені:
|
|
120
143
|
|
|
121
144
|
```json title="package.json"
|
package/mdc/k8s.mdc
CHANGED
|
@@ -145,6 +145,7 @@ jobs:
|
|
|
145
145
|
```yaml
|
|
146
146
|
# yaml-language-server: $schema=https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/v1.33.9-standalone-strict/secret-v1.json
|
|
147
147
|
```
|
|
148
|
+
|
|
148
149
|
3. **`apiVersion: group/version`** і **group** у **`YANNH_GROUPS`** у скрипті → yannh:
|
|
149
150
|
`https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/<PIN>/<kind>-<group-з-крапками-як-дефіси>-<version>.json`
|
|
150
151
|
Приклади: `apps/v1` + `Deployment` → `deployment-apps-v1.json`; `networking.k8s.io/v1` + `Ingress` → `ingress-networking-k8s-io-v1.json`.
|
package/package.json
CHANGED
package/scripts/check-ga.mjs
CHANGED
|
@@ -3,8 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Workflows лише з розширенням `.yml`, наявність clean/lint workflow, конфіг zizmor з ref-pin,
|
|
5
5
|
* відсутність MegaLinter, коректний скрипт `lint-ga` у `package.json`, виклик у `lint-ga.yml`,
|
|
6
|
-
* наявність composite `.github/actions/setup-bun-deps/action.yml` (його записує `npx
|
|
6
|
+
* наявність composite `.github/actions/setup-bun-deps/action.yml` (його записує `npx @nitra/cursor`),
|
|
7
7
|
* перед `uses: ./…/setup-bun-deps` у workflow — `actions/checkout` (runner інакше не бачить локальний action).
|
|
8
|
+
*
|
|
9
|
+
* Заборонено дублювати кроки встановлення Bun та кешування безпосередньо у workflow файлах
|
|
10
|
+
* (oven-sh/setup-bun, actions/cache, bun install).
|
|
8
11
|
*/
|
|
9
12
|
import { existsSync } from 'node:fs'
|
|
10
13
|
import { readdir, readFile } from 'node:fs/promises'
|
|
@@ -48,6 +51,33 @@ function verifyCheckoutBeforeLocalSetupBunDeps(relPath, content, failFn, passFn)
|
|
|
48
51
|
passFn(`${relPath}: перед setup-bun-deps є checkout`)
|
|
49
52
|
}
|
|
50
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Перевіряє, чи не використовуються oven-sh/setup-bun або actions/cache безпосередньо у workflow.
|
|
56
|
+
* @param {string} relPath шлях для повідомлень
|
|
57
|
+
* @param {string} content вміст YAML
|
|
58
|
+
* @param {(msg: string) => void} failFn реєструє порушення (exit 1)
|
|
59
|
+
* @param {(msg: string) => void} passFn реєструє успішну перевірку
|
|
60
|
+
*/
|
|
61
|
+
function verifyNoDirectBunOrCache(relPath, content, failFn, passFn) {
|
|
62
|
+
const forbidden = [
|
|
63
|
+
{ pattern: 'oven-sh/setup-bun', msg: 'використовуй .github/actions/setup-bun-deps замість oven-sh/setup-bun' },
|
|
64
|
+
{ pattern: 'actions/cache', msg: 'використовуй .github/actions/setup-bun-deps замість actions/cache' },
|
|
65
|
+
{ pattern: 'bun install', msg: 'використовуй .github/actions/setup-bun-deps замість bun install' }
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
let foundForbidden = false
|
|
69
|
+
for (const { pattern, msg } of forbidden) {
|
|
70
|
+
if (content.includes(pattern)) {
|
|
71
|
+
failFn(`${relPath}: ${msg} (ga.mdc)`)
|
|
72
|
+
foundForbidden = true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (!foundForbidden) {
|
|
77
|
+
passFn(`${relPath}: не містить заборонених кроків setup-bun/cache/install`)
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
51
81
|
/**
|
|
52
82
|
* Перевіряє відповідність проєкту правилам ga.mdc
|
|
53
83
|
* @returns {Promise<number>} 0 — все OK, 1 — є проблеми
|
|
@@ -94,10 +124,10 @@ export async function check() {
|
|
|
94
124
|
|
|
95
125
|
if (files.includes('apply-k8s.yml')) {
|
|
96
126
|
const content = await readFile(`${wfDir}/apply-k8s.yml`, 'utf8')
|
|
97
|
-
if (content.includes('**/k8s
|
|
127
|
+
if (content.includes('**/k8s/**/*.yaml')) {
|
|
98
128
|
pass('apply-k8s.yml має правильний paths trigger')
|
|
99
129
|
} else {
|
|
100
|
-
fail('apply-k8s.yml не містить paths: **/k8s
|
|
130
|
+
fail('apply-k8s.yml не містить paths: **/k8s/**/*.yaml')
|
|
101
131
|
}
|
|
102
132
|
}
|
|
103
133
|
|
|
@@ -142,6 +172,12 @@ export async function check() {
|
|
|
142
172
|
pass('Залишків MegaLinter не виявлено')
|
|
143
173
|
}
|
|
144
174
|
|
|
175
|
+
for (const f of ymlWorkflows) {
|
|
176
|
+
const content = await readFile(join(wfDir, f), 'utf8')
|
|
177
|
+
verifyCheckoutBeforeLocalSetupBunDeps(`${wfDir}/${f}`, content, fail, pass)
|
|
178
|
+
verifyNoDirectBunOrCache(`${wfDir}/${f}`, content, fail, pass)
|
|
179
|
+
}
|
|
180
|
+
|
|
145
181
|
const zizmorPath = '.github/zizmor.yml'
|
|
146
182
|
if (existsSync(zizmorPath)) {
|
|
147
183
|
const z = await readFile(zizmorPath, 'utf8')
|
|
@@ -190,15 +226,6 @@ export async function check() {
|
|
|
190
226
|
} else {
|
|
191
227
|
fail('lint-ga.yml: додай astral-sh/setup-uv для uvx zizmor (ga.mdc)')
|
|
192
228
|
}
|
|
193
|
-
verifyCheckoutBeforeLocalSetupBunDeps(`${wfDir}/lint-ga.yml`, lgContent, fail, pass)
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
for (const wfName of ['lint-js.yml', 'lint-text.yml']) {
|
|
197
|
-
const p = join(wfDir, wfName)
|
|
198
|
-
if (existsSync(p)) {
|
|
199
|
-
const body = await readFile(p, 'utf8')
|
|
200
|
-
verifyCheckoutBeforeLocalSetupBunDeps(`${wfDir}/${wfName}`, body, fail, pass)
|
|
201
|
-
}
|
|
202
229
|
}
|
|
203
230
|
|
|
204
231
|
return exitCode
|