qaify-playwright-reporter 0.9.1 → 0.9.4
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/fix.d.ts +9 -0
- package/dist/fix.js +39 -5
- package/package.json +1 -1
package/dist/fix.d.ts
CHANGED
|
@@ -136,12 +136,19 @@ export declare function fixContext(client: IngestClient, fixId: string, dir: str
|
|
|
136
136
|
* Advisory dependensi tanpa AI: update paket di lockfile saja (tanpa install / script), cek ulang dengan audit, lalu
|
|
137
137
|
* tulis hasilnya ke <dir>/.qaify/claude.json dalam bentuk keluaran `claude -p` (model qaify-deps, token 0) agar
|
|
138
138
|
* fix-diff / fix-submit tidak berubah. npm: npm update dulu, npm audit fix bila paket masih rentan.
|
|
139
|
+
* Paket yang sudah aman di ujung branch (mis. ikut naik lewat PR temuan lain) tidak di-update: already_fixed.
|
|
139
140
|
*/
|
|
140
141
|
export declare function fixDeps(dir: string, exec?: Exec): Promise<{
|
|
141
142
|
fixed: boolean;
|
|
142
143
|
summary: string;
|
|
143
144
|
reason?: string;
|
|
145
|
+
already_fixed?: boolean;
|
|
144
146
|
}>;
|
|
147
|
+
/**
|
|
148
|
+
* Paket di composer.lock yang me-require pkg secara langsung. `--with-all-dependencies` hanya memperbarui dependensi
|
|
149
|
+
* pkg; tanpa ini dependennya tertinggal di versi lama yang belum tentu cocok dengan pkg baru.
|
|
150
|
+
*/
|
|
151
|
+
export declare function composerDependents(repo: string, pkg: string): Promise<string[]>;
|
|
145
152
|
/** Masih ada advisory untuk paket ini? npm: hanya high / critical (sama dengan temuan audit-static). */
|
|
146
153
|
export declare function stillVulnerable(output: string, manager: 'composer' | 'npm', pkg: string): boolean;
|
|
147
154
|
/**
|
|
@@ -176,6 +183,8 @@ export interface ParsedFix {
|
|
|
176
183
|
summary: string;
|
|
177
184
|
reason: string | null;
|
|
178
185
|
tests_run: string | null;
|
|
186
|
+
/** fix-deps: paket sudah aman sebelum di-update (bukan dari Claude, FIX_SCHEMA tidak memuatnya). */
|
|
187
|
+
already_fixed: boolean;
|
|
179
188
|
usage: ClaudeUsage | null;
|
|
180
189
|
}
|
|
181
190
|
/** Output `claude -p --output-format json --json-schema FIX_SCHEMA`; null = tidak ada hasil terstruktur. */
|
package/dist/fix.js
CHANGED
|
@@ -191,6 +191,7 @@ export async function fixContext(client, fixId, dir, opts = {}) {
|
|
|
191
191
|
* Advisory dependensi tanpa AI: update paket di lockfile saja (tanpa install / script), cek ulang dengan audit, lalu
|
|
192
192
|
* tulis hasilnya ke <dir>/.qaify/claude.json dalam bentuk keluaran `claude -p` (model qaify-deps, token 0) agar
|
|
193
193
|
* fix-diff / fix-submit tidak berubah. npm: npm update dulu, npm audit fix bila paket masih rentan.
|
|
194
|
+
* Paket yang sudah aman di ujung branch (mis. ikut naik lewat PR temuan lain) tidak di-update: already_fixed.
|
|
194
195
|
*/
|
|
195
196
|
export async function fixDeps(dir, exec = defaultExec) {
|
|
196
197
|
const started = Date.now();
|
|
@@ -202,18 +203,31 @@ export async function fixDeps(dir, exec = defaultExec) {
|
|
|
202
203
|
const composer = target.manager === 'composer';
|
|
203
204
|
const manifest = composer ? 'composer.json' : 'package.json';
|
|
204
205
|
const auditCmd = composer ? 'composer audit --locked' : 'npm audit --package-lock-only';
|
|
206
|
+
const audit = () => composer
|
|
207
|
+
? report('composer', ['audit', '--locked', '--format=json', '--no-interaction', `--working-dir=${repo}`])
|
|
208
|
+
: report('npm', ['audit', '--json', '--package-lock-only', '--prefix', repo]);
|
|
205
209
|
const steps = [];
|
|
210
|
+
// tanpa cek ini update dependennya (mis. laravel/framework) tetap mengubah lockfile → PR yang tidak diperlukan
|
|
211
|
+
if (!stillVulnerable(await audit(), target.manager, pkg)) {
|
|
212
|
+
return writeDeps(dir, started, {
|
|
213
|
+
fixed: false,
|
|
214
|
+
already_fixed: true,
|
|
215
|
+
summary: `${pkg} sudah aman di branch ini.`,
|
|
216
|
+
reason: `${auditCmd} di ujung branch tidak lagi melaporkan advisory ${pkg} (kemungkinan ikut diperbarui lewat perubahan lain). Lockfile tidak diubah.`,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
206
219
|
let vulnerable;
|
|
207
220
|
try {
|
|
208
221
|
if (composer) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
222
|
+
// paket yang me-require pkg ikut naik: mis. laravel/framework baru butuh laravel/sanctum yang mengenal perubahannya
|
|
223
|
+
const packages = [pkg, ...(await composerDependents(repo, pkg))];
|
|
224
|
+
steps.push(`composer update ${packages.join(' ')} --with-all-dependencies --no-install`);
|
|
225
|
+
await exec('composer', ['update', ...packages, '--with-all-dependencies', '--no-install', '--no-scripts', '--no-interaction', '--no-progress', `--working-dir=${repo}`]);
|
|
226
|
+
vulnerable = stillVulnerable(await audit(), 'composer', pkg);
|
|
212
227
|
}
|
|
213
228
|
else {
|
|
214
229
|
steps.push(`npm update ${pkg} --package-lock-only`);
|
|
215
230
|
await exec('npm', ['update', pkg, '--package-lock-only', '--no-fund', '--no-audit', '--prefix', repo]);
|
|
216
|
-
const audit = () => report('npm', ['audit', '--json', '--package-lock-only', '--prefix', repo]);
|
|
217
231
|
vulnerable = stillVulnerable(await audit(), 'npm', pkg);
|
|
218
232
|
if (vulnerable) {
|
|
219
233
|
steps.push('npm audit fix --package-lock-only');
|
|
@@ -244,6 +258,22 @@ export async function fixDeps(dir, exec = defaultExec) {
|
|
|
244
258
|
tests_run: `${auditCmd}: ${pkg} bersih. Test aplikasi dijalankan CI repo pada PR ini.`,
|
|
245
259
|
});
|
|
246
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Paket di composer.lock yang me-require pkg secara langsung. `--with-all-dependencies` hanya memperbarui dependensi
|
|
263
|
+
* pkg; tanpa ini dependennya tertinggal di versi lama yang belum tentu cocok dengan pkg baru.
|
|
264
|
+
*/
|
|
265
|
+
export async function composerDependents(repo, pkg) {
|
|
266
|
+
let lock;
|
|
267
|
+
try {
|
|
268
|
+
lock = JSON.parse(await readFile(join(repo, 'composer.lock'), 'utf8'));
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return [];
|
|
272
|
+
}
|
|
273
|
+
return [...(lock.packages ?? []), ...(lock['packages-dev'] ?? [])]
|
|
274
|
+
.filter((p) => p.name !== pkg && p.require && pkg in p.require)
|
|
275
|
+
.map((p) => p.name);
|
|
276
|
+
}
|
|
247
277
|
/** Masih ada advisory untuk paket ini? npm: hanya high / critical (sama dengan temuan audit-static). */
|
|
248
278
|
export function stillVulnerable(output, manager, pkg) {
|
|
249
279
|
const start = output.search(/[[{]/);
|
|
@@ -351,6 +381,7 @@ export function parseFixOutput(raw) {
|
|
|
351
381
|
summary: out.summary,
|
|
352
382
|
reason: typeof out.reason === 'string' && out.reason ? out.reason : null,
|
|
353
383
|
tests_run: typeof out.tests_run === 'string' && out.tests_run ? out.tests_run : null,
|
|
384
|
+
already_fixed: out.already_fixed === true,
|
|
354
385
|
usage: parseClaudeUsage(parsed),
|
|
355
386
|
};
|
|
356
387
|
}
|
|
@@ -381,6 +412,9 @@ export async function fixSubmit(client, fixId, claudeOutput, patch, workDir, opt
|
|
|
381
412
|
const stats = patchStats(patch);
|
|
382
413
|
const usage = parsed.usage ? { ...parsed.usage, files_changed: stats.files.length, lines_changed: stats.changedLines } : undefined;
|
|
383
414
|
const summary = [parsed.summary, parsed.tests_run ? `Verifikasi: ${parsed.tests_run}` : null].filter(Boolean).join('\n\n');
|
|
415
|
+
// no_change + already_fixed: backend lama tetap menerimanya (gave_up), backend baru menutup temuannya
|
|
416
|
+
if (parsed.already_fixed)
|
|
417
|
+
return send({ status: 'no_change', already_fixed: true, summary, reason: parsed.reason ?? parsed.summary, usage });
|
|
384
418
|
if (!parsed.fixed)
|
|
385
419
|
return send({ status: 'failed', summary, reason: parsed.reason ?? parsed.summary, usage });
|
|
386
420
|
if (!patch.trim())
|
|
@@ -435,7 +469,7 @@ export async function fixSubmit(client, fixId, claudeOutput, patch, workDir, opt
|
|
|
435
469
|
step = 'di-commit';
|
|
436
470
|
await git(['commit', '-q', '--no-verify', '-m', `fix(qaify): ${grant.title}`.slice(0, 200), '-m', parsed.summary], commitEnv);
|
|
437
471
|
step = 'di-push';
|
|
438
|
-
await git(['push', '-q', '--no-verify', url,
|
|
472
|
+
await git(['push', '-q', '--no-verify', url, `${grant.force ? '+' : ''}HEAD:refs/heads/${grant.branch}`], auth);
|
|
439
473
|
}
|
|
440
474
|
catch (e) {
|
|
441
475
|
await revokeTokens([grant.token], opts.fetch);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "qaify-playwright-reporter",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "Reporter Playwright untuk QA Factory (Qaify): kirim hasil test dan artefak ke /api/ingest, tanpa pernah menggagalkan test.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ahmdkenz",
|