452d38e
commit 452d38e
3 files changed
+53 -14
Showing 3 changed files+53-14
▼.github/workflows/ci.yml
+36-1
| @@ -319,7 +319,7 @@ jobs: | ||
319 | 319 | docker: |
320 | 320 | name: Docker Build |
321 | 321 | runs-on: ubuntu-latest |
322 | - needs: [build, e2e, container-scan] | |
322 | + needs: [build, e2e, container-scan, performance] | |
323 | 323 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' |
324 | 324 | steps: |
325 | 325 | - uses: actions/checkout@v4 |
| @@ -353,6 +353,41 @@ jobs: | ||
353 | 353 | cache-from: type=gha |
354 | 354 | cache-to: type=gha,mode=max |
355 | 355 | |
356 | + # ────────────────────────────────────────────────── | |
357 | + # Stage 9: Publish CLI Package | |
358 | + # ────────────────────────────────────────────────── | |
359 | + cli-publish: | |
360 | + name: Publish CLI | |
361 | + runs-on: ubuntu-latest | |
362 | + needs: [build, e2e] | |
363 | + if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
364 | + steps: | |
365 | + - uses: actions/checkout@v4 | |
366 | + | |
367 | + - uses: oven-sh/setup-bun@v2 | |
368 | + with: | |
369 | + bun-version: latest | |
370 | + | |
371 | + - name: Set up Node.js | |
372 | + uses: actions/setup-node@v4 | |
373 | + with: | |
374 | + node-version: "20" | |
375 | + registry-url: "https://registry.npmjs.org" | |
376 | + | |
377 | + - name: Install dependencies | |
378 | + run: bun install --frozen-lockfile | |
379 | + working-directory: cli | |
380 | + | |
381 | + - name: Build CLI | |
382 | + run: bun run build | |
383 | + working-directory: cli | |
384 | + | |
385 | + - name: Publish to npm | |
386 | + run: bun npm publish --access public --provenance | |
387 | + working-directory: cli | |
388 | + env: | |
389 | + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
390 | + | |
356 | 391 | # ────────────────────────────────────────────────── |
357 | 392 | # Quality Gate Summary |
358 | 393 | # ────────────────────────────────────────────────── |
359 | 394 | |
▼scripts/worker.ts
+16-12
| @@ -1,4 +1,5 @@ | ||
1 | 1 | import { getDatabase, schema } from "@/db"; |
2 | +import type { NodePgDatabase } from "drizzle-orm/node-postgres"; | |
2 | 3 | import { cleanupAllRepos } from "@/lib/cron/cleanup-branches"; |
3 | 4 | import { logger } from "@/lib/logger"; |
4 | 5 | import { syncAllMirrors } from "@/lib/mirror-sync"; |
| @@ -38,19 +39,22 @@ async function runQueueProcessor() { | ||
38 | 39 | |
39 | 40 | try { |
40 | 41 | // 1. Reclaim stale jobs (stuck in "processing" too long) |
41 | - const staleThreshold = new Date(Date.now() - STALE_JOB_TIMEOUT_MS); | |
42 | 42 | try { |
43 | - await db | |
44 | - .update(schema.mergeQueueItems) | |
45 | - .set({ status: "queued" }) | |
46 | - .where( | |
47 | - and( | |
48 | - eq(schema.mergeQueueItems.status, "processing"), | |
49 | - lt(schema.mergeQueueItems.updatedAt, staleThreshold), | |
50 | - ), | |
51 | - ); | |
43 | + const staleThreshold = new Date(Date.now() - STALE_JOB_TIMEOUT_MS); | |
44 | + const staleItems = await db.query.mergeQueueItems.findMany({ | |
45 | + where: eq(schema.mergeQueueItems.status, "processing"), | |
46 | + columns: { id: true, startedAt: true }, | |
47 | + }); | |
48 | + for (const item of staleItems) { | |
49 | + if (item.startedAt && new Date(item.startedAt) < staleThreshold) { | |
50 | + await (db as NodePgDatabase<typeof schema>) | |
51 | + .update(schema.mergeQueueItems) | |
52 | + .set({ status: "queued" }) | |
53 | + .where(eq(schema.mergeQueueItems.id, item.id)); | |
54 | + } | |
55 | + } | |
52 | 56 | } catch { |
53 | - // retryCount/updatedAt columns may not exist yet — skip stale reclaim | |
57 | + // startedAt column may not exist yet — skip stale reclaim | |
54 | 58 | } |
55 | 59 | |
56 | 60 | // 2. Process pending items |
| @@ -208,7 +212,7 @@ async function startWorker() { | ||
208 | 212 | ), |
209 | 213 | runLoop( |
210 | 214 | "mirror-sync", |
211 | - () => syncAllMirrors(), | |
215 | + async () => { await syncAllMirrors(); }, | |
212 | 216 | MIRROR_SYNC_INTERVAL, |
213 | 217 | () => lastMirrorRun, |
214 | 218 | (t) => { |
215 | 219 | |
▼src/components/inbox/KeyboardReviewInbox.tsx
+1-1
| @@ -52,7 +52,7 @@ export const KeyboardReviewInbox: React.FC<{ initialPr: PRProps }> = ({ initialP | ||
52 | 52 | initialPr.diffs.map((diff, idx) => ( |
53 | 53 | <div |
54 | 54 | key={idx} |
55 | - className={\`p-4 rounded-md border transition-colors duration-150 \${idx === activeChunk ? 'border-blue-500 bg-slate-900' : 'border-slate-800'}\`} | |
55 | + className={`p-4 rounded-md border transition-colors duration-150 ${idx === activeChunk ? 'border-blue-500 bg-slate-900' : 'border-slate-800'}`} | |
56 | 56 | > |
57 | 57 | <pre className="text-sm">{JSON.stringify(diff, null, 2)}</pre> |
58 | 58 | </div> |
59 | 59 | |