@clearlydev/nx-archweave 0.2.1 → 0.2.2
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/bin/review-verdict.js +36 -20
- package/dist/generators/add-review/generator.js +248 -179
- package/dist/generators/doctor/generator.js +251 -181
- package/dist/generators/init/generator.js +248 -179
- package/package.json +1 -1
|
@@ -272,13 +272,14 @@ function renderConcurrencyBlock() {
|
|
|
272
272
|
" cancel-in-progress: false"
|
|
273
273
|
].join("\n");
|
|
274
274
|
}
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
var REVIEW_GATE_CONDITION = "steps.secret-gate.outputs.enabled == 'true' && steps.round-gate.outputs.allowed == 'true'";
|
|
276
|
+
function renderReviewPermissions(idToken) {
|
|
277
|
+
return ["permissions:", " contents: read", " pull-requests: write", ...idToken ? [" id-token: write"] : []].join("\n");
|
|
277
278
|
}
|
|
278
279
|
function renderCheckoutStep(gateCondition, extraWith = []) {
|
|
279
280
|
return [
|
|
280
281
|
"- name: Checkout repository",
|
|
281
|
-
` if: ${gateCondition}
|
|
282
|
+
...gateCondition === void 0 ? [] : [` if: ${gateCondition}`],
|
|
282
283
|
` uses: ${pinnedUses("actions/checkout")}`,
|
|
283
284
|
" with:",
|
|
284
285
|
...extraWith.map((line) => ` ${line}`),
|
|
@@ -320,10 +321,46 @@ function renderRoundGateStep(maxRounds) {
|
|
|
320
321
|
" fi"
|
|
321
322
|
].join("\n");
|
|
322
323
|
}
|
|
324
|
+
var JUDGE_CONDITION = "steps.ai-review-result.outputs.run == 'true'";
|
|
325
|
+
function renderAiReviewResultStep() {
|
|
326
|
+
return [
|
|
327
|
+
"- name: Check the AI review result",
|
|
328
|
+
" id: ai-review-result",
|
|
329
|
+
" env:",
|
|
330
|
+
" AI_REVIEW_RESULT: ${{ needs.ai-review.result }}",
|
|
331
|
+
" REVIEW_ENABLED: ${{ needs.ai-review.outputs.enabled }}",
|
|
332
|
+
" REVIEW_ALLOWED: ${{ needs.ai-review.outputs.allowed }}",
|
|
333
|
+
" LAST_COMMENT_ID: ${{ needs.ai-review.outputs.last-comment-id }}",
|
|
334
|
+
" run: |",
|
|
335
|
+
' if [ "$AI_REVIEW_RESULT" != success ]; then',
|
|
336
|
+
` echo "::error title=AI review did not succeed::The AI review job ended with '$AI_REVIEW_RESULT'."`,
|
|
337
|
+
" exit 1",
|
|
338
|
+
" fi",
|
|
339
|
+
' case "$REVIEW_ENABLED/$REVIEW_ALLOWED" in',
|
|
340
|
+
" false/* | true/false)",
|
|
341
|
+
' echo "The AI review did not run (no secret, or the round limit) - nothing to judge."',
|
|
342
|
+
' echo "run=false" >> "$GITHUB_OUTPUT"',
|
|
343
|
+
" exit 0",
|
|
344
|
+
" ;;",
|
|
345
|
+
" true/true)",
|
|
346
|
+
' case "$LAST_COMMENT_ID" in',
|
|
347
|
+
" '' | *[!0-9]*) ;;",
|
|
348
|
+
" *)",
|
|
349
|
+
' echo "run=true" >> "$GITHUB_OUTPUT"',
|
|
350
|
+
" exit 0",
|
|
351
|
+
" ;;",
|
|
352
|
+
" esac",
|
|
353
|
+
" ;;",
|
|
354
|
+
" esac",
|
|
355
|
+
` echo "::error title=Review verdict not computed::The AI review job's results did not reach this job, so no verdict can be computed. Re-run all jobs."`,
|
|
356
|
+
" exit 1"
|
|
357
|
+
].join("\n");
|
|
358
|
+
}
|
|
323
359
|
function renderVerdictGateStep(maxRounds, locale) {
|
|
324
360
|
return [
|
|
325
361
|
"- name: Compute review verdict",
|
|
326
|
-
"
|
|
362
|
+
" id: verdict",
|
|
363
|
+
` if: ${JUDGE_CONDITION}`,
|
|
327
364
|
" env:",
|
|
328
365
|
" GH_TOKEN: ${{ github.token }}",
|
|
329
366
|
" GITHUB_REPOSITORY: ${{ github.repository }}",
|
|
@@ -331,7 +368,8 @@ function renderVerdictGateStep(maxRounds, locale) {
|
|
|
331
368
|
` ARCHWEAVE_MAX_ROUNDS: '${maxRounds}'`,
|
|
332
369
|
` ARCHWEAVE_LOCALE: '${locale}'`,
|
|
333
370
|
" ARCHWEAVE_HEAD_SHA: ${{ github.event.pull_request.head.sha }}",
|
|
334
|
-
" ARCHWEAVE_ROUND_AFTER_ID: ${{
|
|
371
|
+
" ARCHWEAVE_ROUND_AFTER_ID: ${{ needs.ai-review.outputs.last-comment-id }}",
|
|
372
|
+
" ARCHWEAVE_VERDICT_OUTPUT: 'github-output'",
|
|
335
373
|
" run: |",
|
|
336
374
|
" if [ -x node_modules/.bin/archweave-review-verdict ]; then",
|
|
337
375
|
" node_modules/.bin/archweave-review-verdict",
|
|
@@ -340,16 +378,46 @@ function renderVerdictGateStep(maxRounds, locale) {
|
|
|
340
378
|
" fi"
|
|
341
379
|
].join("\n");
|
|
342
380
|
}
|
|
381
|
+
function renderBlockStep() {
|
|
382
|
+
return [
|
|
383
|
+
"- name: Fail on a blocking verdict",
|
|
384
|
+
" if: steps.verdict.outputs.blocked == 'true'",
|
|
385
|
+
" run: |",
|
|
386
|
+
' echo "The review verdict is BLOCK - see the verdict comment on this pull request."',
|
|
387
|
+
" exit 1"
|
|
388
|
+
].join("\n");
|
|
389
|
+
}
|
|
390
|
+
function renderVerdictCommentStep() {
|
|
391
|
+
return [
|
|
392
|
+
"- name: Post review verdict",
|
|
393
|
+
" env:",
|
|
394
|
+
" GH_TOKEN: ${{ github.token }}",
|
|
395
|
+
" REPOSITORY: ${{ github.repository }}",
|
|
396
|
+
" PR_NUMBER: ${{ github.event.pull_request.number }}",
|
|
397
|
+
" VERDICT_BODY: ${{ needs.review.outputs.comment-body }}",
|
|
398
|
+
" PREVIOUS_ID: ${{ needs.review.outputs.previous-comment-id }}",
|
|
399
|
+
" run: |",
|
|
400
|
+
` payload=$(jq -n --arg body "$VERDICT_BODY" '{body: $body}')`,
|
|
401
|
+
' case "$PREVIOUS_ID" in',
|
|
402
|
+
" ''|*[!0-9]*) PREVIOUS_ID= ;;",
|
|
403
|
+
" esac",
|
|
404
|
+
` if [ -n "$PREVIOUS_ID" ] && printf '%s' "$payload" | gh api -X PATCH "repos/$REPOSITORY/issues/comments/$PREVIOUS_ID" --input - > /dev/null; then`,
|
|
405
|
+
" exit 0",
|
|
406
|
+
" fi",
|
|
407
|
+
` printf '%s' "$payload" | gh api -X POST "repos/$REPOSITORY/issues/$PR_NUMBER/comments" --input - > /dev/null \\`,
|
|
408
|
+
' || echo "Could not post the verdict comment (continuing)."'
|
|
409
|
+
].join("\n");
|
|
410
|
+
}
|
|
343
411
|
var SETUP_NODE_VERSION = "22";
|
|
344
412
|
var FALLBACK_PNPM_VERSION = "10";
|
|
345
413
|
var INSTALL_LINES = {
|
|
346
|
-
pnpm: [" pnpm install --frozen-lockfile"],
|
|
347
|
-
npm: [" npm ci"],
|
|
414
|
+
pnpm: [" pnpm install --frozen-lockfile --ignore-scripts"],
|
|
415
|
+
npm: [" npm ci --ignore-scripts"],
|
|
348
416
|
yarn: [
|
|
349
417
|
" corepack enable yarn",
|
|
350
|
-
' if [ "$(yarn --version | cut -d. -f1)" -ge 2 ]; then yarn install --immutable; else yarn install --frozen-lockfile; fi'
|
|
418
|
+
' if [ "$(yarn --version | cut -d. -f1)" -ge 2 ]; then YARN_ENABLE_SCRIPTS=false yarn install --immutable --mode=skip-build; else yarn install --frozen-lockfile --ignore-scripts; fi'
|
|
351
419
|
],
|
|
352
|
-
bun: [" bun install --frozen-lockfile"]
|
|
420
|
+
bun: [" bun install --frozen-lockfile --ignore-scripts"]
|
|
353
421
|
};
|
|
354
422
|
function renderPnpmVersionStep(gate) {
|
|
355
423
|
return [
|
|
@@ -365,7 +433,7 @@ function renderPnpmVersionStep(gate) {
|
|
|
365
433
|
].join("\n");
|
|
366
434
|
}
|
|
367
435
|
function renderWorkspaceSetupSteps(packageManager) {
|
|
368
|
-
const gate =
|
|
436
|
+
const gate = ` if: ${JUDGE_CONDITION}`;
|
|
369
437
|
const steps = [];
|
|
370
438
|
if (packageManager === "pnpm") {
|
|
371
439
|
steps.push(renderPnpmVersionStep(gate));
|
|
@@ -400,6 +468,60 @@ function renderWorkspaceSetupSteps(packageManager) {
|
|
|
400
468
|
].join("\n"));
|
|
401
469
|
return steps.join("\n\n");
|
|
402
470
|
}
|
|
471
|
+
function renderReviewWorkflow(input, parts) {
|
|
472
|
+
const aiReviewSteps = [renderSecretGateStep(parts.secretName), renderRoundGateStep(input.maxRounds), ...parts.reviewSteps];
|
|
473
|
+
const reviewSteps = [
|
|
474
|
+
renderAiReviewResultStep(),
|
|
475
|
+
renderCheckoutStep(JUDGE_CONDITION),
|
|
476
|
+
renderWorkspaceSetupSteps(input.packageManager),
|
|
477
|
+
renderVerdictGateStep(input.maxRounds, input.locale),
|
|
478
|
+
renderBlockStep()
|
|
479
|
+
];
|
|
480
|
+
return [
|
|
481
|
+
`name: ${parts.name}`,
|
|
482
|
+
"",
|
|
483
|
+
renderTriggerBlock(),
|
|
484
|
+
"",
|
|
485
|
+
renderConcurrencyBlock(),
|
|
486
|
+
"",
|
|
487
|
+
"permissions: {}",
|
|
488
|
+
"",
|
|
489
|
+
"jobs:",
|
|
490
|
+
" ai-review:",
|
|
491
|
+
" runs-on: ubuntu-latest",
|
|
492
|
+
indentBlock(renderReviewPermissions(parts.idToken), 4),
|
|
493
|
+
" outputs:",
|
|
494
|
+
" enabled: ${{ steps.secret-gate.outputs.enabled }}",
|
|
495
|
+
" allowed: ${{ steps.round-gate.outputs.allowed }}",
|
|
496
|
+
" last-comment-id: ${{ steps.round-gate.outputs.last-comment-id }}",
|
|
497
|
+
" steps:",
|
|
498
|
+
indentBlock(aiReviewSteps.join("\n\n"), 6),
|
|
499
|
+
"",
|
|
500
|
+
" review:",
|
|
501
|
+
" needs: ai-review",
|
|
502
|
+
" if: always()",
|
|
503
|
+
" runs-on: ubuntu-latest",
|
|
504
|
+
" permissions:",
|
|
505
|
+
" contents: read",
|
|
506
|
+
" pull-requests: read",
|
|
507
|
+
" outputs:",
|
|
508
|
+
" comment-body: ${{ steps.verdict.outputs.comment-body }}",
|
|
509
|
+
" previous-comment-id: ${{ steps.verdict.outputs.previous-comment-id }}",
|
|
510
|
+
" steps:",
|
|
511
|
+
indentBlock(reviewSteps.join("\n\n"), 6),
|
|
512
|
+
"",
|
|
513
|
+
" review-comment:",
|
|
514
|
+
" needs: review",
|
|
515
|
+
// Runs after a BLOCK failed the review job, too: the comment explains the red check.
|
|
516
|
+
" if: ${{ !cancelled() && needs.review.outputs.comment-body != '' }}",
|
|
517
|
+
" runs-on: ubuntu-latest",
|
|
518
|
+
" permissions:",
|
|
519
|
+
" pull-requests: write",
|
|
520
|
+
" steps:",
|
|
521
|
+
indentBlock(renderVerdictCommentStep(), 6),
|
|
522
|
+
""
|
|
523
|
+
].join("\n");
|
|
524
|
+
}
|
|
403
525
|
|
|
404
526
|
// ../template-engine/dist/review/claude/claude-provider.js
|
|
405
527
|
var SECRET_NAME = "CLAUDE_CODE_OAUTH_TOKEN";
|
|
@@ -432,40 +554,26 @@ function composePrompt(input) {
|
|
|
432
554
|
return sections.join("\n\n---\n\n");
|
|
433
555
|
}
|
|
434
556
|
function buildWorkflowYaml(input) {
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
"",
|
|
456
|
-
renderTriggerBlock(),
|
|
457
|
-
"",
|
|
458
|
-
renderConcurrencyBlock(),
|
|
459
|
-
"",
|
|
460
|
-
renderPermissionsBlock(),
|
|
461
|
-
"",
|
|
462
|
-
"jobs:",
|
|
463
|
-
" review:",
|
|
464
|
-
" runs-on: ubuntu-latest",
|
|
465
|
-
" steps:",
|
|
466
|
-
indentBlock(steps.join("\n\n"), 6),
|
|
467
|
-
""
|
|
468
|
-
].join("\n");
|
|
557
|
+
return renderReviewWorkflow(input, {
|
|
558
|
+
name: "Claude Code Review",
|
|
559
|
+
secretName: SECRET_NAME,
|
|
560
|
+
// The Claude GitHub App signs in with the workflow's OIDC token (claude-code-action's FAQ).
|
|
561
|
+
idToken: true,
|
|
562
|
+
reviewSteps: [
|
|
563
|
+
renderCheckoutStep(REVIEW_GATE_CONDITION),
|
|
564
|
+
[
|
|
565
|
+
"- name: Run Claude review",
|
|
566
|
+
` if: ${REVIEW_GATE_CONDITION}`,
|
|
567
|
+
` uses: ${pinnedUses("anthropics/claude-code-action")}`,
|
|
568
|
+
" with:",
|
|
569
|
+
` claude_code_oauth_token: \${{ secrets.${SECRET_NAME} }}`,
|
|
570
|
+
" prompt: |",
|
|
571
|
+
indentBlock(composePrompt(input), 6),
|
|
572
|
+
" claude_args: |",
|
|
573
|
+
` --allowedTools "${ALLOWED_TOOLS}"`
|
|
574
|
+
].join("\n")
|
|
575
|
+
]
|
|
576
|
+
});
|
|
469
577
|
}
|
|
470
578
|
var claudeProvider = {
|
|
471
579
|
id: "claude",
|
|
@@ -505,49 +613,39 @@ function composePrompt2(input) {
|
|
|
505
613
|
return sections.join("\n\n---\n\n");
|
|
506
614
|
}
|
|
507
615
|
function buildWorkflowYaml2(input) {
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
[
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
"
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
"
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
"",
|
|
542
|
-
renderPermissionsBlock(),
|
|
543
|
-
"",
|
|
544
|
-
"jobs:",
|
|
545
|
-
" review:",
|
|
546
|
-
" runs-on: ubuntu-latest",
|
|
547
|
-
" steps:",
|
|
548
|
-
indentBlock(steps.join("\n\n"), 6),
|
|
549
|
-
""
|
|
550
|
-
].join("\n");
|
|
616
|
+
return renderReviewWorkflow(input, {
|
|
617
|
+
name: "Cursor Code Review",
|
|
618
|
+
secretName: SECRET_NAME2,
|
|
619
|
+
// An API key: the Cursor CLI needs no OIDC token.
|
|
620
|
+
idToken: false,
|
|
621
|
+
reviewSteps: [
|
|
622
|
+
renderCheckoutStep(REVIEW_GATE_CONDITION),
|
|
623
|
+
[
|
|
624
|
+
"- name: Install cursor-agent CLI",
|
|
625
|
+
` if: ${REVIEW_GATE_CONDITION}`,
|
|
626
|
+
" run: |",
|
|
627
|
+
// HTTPS only, TLS 1.2 or newer. Cursor publishes no pinned version or checksum for
|
|
628
|
+
// this installer; docs/pr-review.md states what that leaves open.
|
|
629
|
+
" curl --proto '=https' --tlsv1.2 -fsS https://cursor.com/install | bash",
|
|
630
|
+
// The docs name ~/.cursor/bin; the installer currently links `agent` into ~/.local/bin.
|
|
631
|
+
// Both go on the PATH, so the next step finds it wherever the installer puts it.
|
|
632
|
+
' echo "$HOME/.local/bin" >> "$GITHUB_PATH"',
|
|
633
|
+
' echo "$HOME/.cursor/bin" >> "$GITHUB_PATH"'
|
|
634
|
+
].join("\n"),
|
|
635
|
+
[
|
|
636
|
+
"- name: Run Cursor review",
|
|
637
|
+
` if: ${REVIEW_GATE_CONDITION}`,
|
|
638
|
+
" env:",
|
|
639
|
+
` CURSOR_API_KEY: \${{ secrets.${SECRET_NAME2} }}`,
|
|
640
|
+
" GH_TOKEN: ${{ github.token }}",
|
|
641
|
+
" run: |",
|
|
642
|
+
` agent -p "$(cat <<'${PROMPT_HEREDOC_DELIMITER}'`,
|
|
643
|
+
indentBlock(composePrompt2(input), 4),
|
|
644
|
+
` ${PROMPT_HEREDOC_DELIMITER}`,
|
|
645
|
+
' )"'
|
|
646
|
+
].join("\n")
|
|
647
|
+
]
|
|
648
|
+
});
|
|
551
649
|
}
|
|
552
650
|
var cursorProvider = {
|
|
553
651
|
id: "cursor",
|
|
@@ -586,40 +684,26 @@ function composePrompt3(input) {
|
|
|
586
684
|
return sections.join("\n\n---\n\n");
|
|
587
685
|
}
|
|
588
686
|
function buildWorkflowYaml3(input) {
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
"",
|
|
610
|
-
renderTriggerBlock(),
|
|
611
|
-
"",
|
|
612
|
-
renderConcurrencyBlock(),
|
|
613
|
-
"",
|
|
614
|
-
renderPermissionsBlock(),
|
|
615
|
-
"",
|
|
616
|
-
"jobs:",
|
|
617
|
-
" review:",
|
|
618
|
-
" runs-on: ubuntu-latest",
|
|
619
|
-
" steps:",
|
|
620
|
-
indentBlock(steps.join("\n\n"), 6),
|
|
621
|
-
""
|
|
622
|
-
].join("\n");
|
|
687
|
+
return renderReviewWorkflow(input, {
|
|
688
|
+
name: "Gemini Code Review",
|
|
689
|
+
secretName: SECRET_NAME3,
|
|
690
|
+
// An API key: run-gemini-cli uses OIDC only for Google Cloud workload identity federation.
|
|
691
|
+
idToken: false,
|
|
692
|
+
reviewSteps: [
|
|
693
|
+
renderCheckoutStep(REVIEW_GATE_CONDITION),
|
|
694
|
+
[
|
|
695
|
+
"- name: Run Gemini review",
|
|
696
|
+
` if: ${REVIEW_GATE_CONDITION}`,
|
|
697
|
+
` uses: ${pinnedUses("google-github-actions/run-gemini-cli")}`,
|
|
698
|
+
" env:",
|
|
699
|
+
" GITHUB_TOKEN: ${{ github.token }}",
|
|
700
|
+
" with:",
|
|
701
|
+
` gemini_api_key: \${{ secrets.${SECRET_NAME3} }}`,
|
|
702
|
+
" prompt: |",
|
|
703
|
+
indentBlock(composePrompt3(input), 6)
|
|
704
|
+
].join("\n")
|
|
705
|
+
]
|
|
706
|
+
});
|
|
623
707
|
}
|
|
624
708
|
var geminiProvider = {
|
|
625
709
|
id: "gemini",
|
|
@@ -658,64 +742,49 @@ function composePrompt4(input) {
|
|
|
658
742
|
return sections.join("\n\n---\n\n");
|
|
659
743
|
}
|
|
660
744
|
function buildWorkflowYaml4(input) {
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
[
|
|
667
|
-
"
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
"
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
"
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
"name: GPT Code Review",
|
|
705
|
-
"",
|
|
706
|
-
renderTriggerBlock(),
|
|
707
|
-
"",
|
|
708
|
-
renderConcurrencyBlock(),
|
|
709
|
-
"",
|
|
710
|
-
renderPermissionsBlock(),
|
|
711
|
-
"",
|
|
712
|
-
"jobs:",
|
|
713
|
-
" review:",
|
|
714
|
-
" runs-on: ubuntu-latest",
|
|
715
|
-
" steps:",
|
|
716
|
-
indentBlock(steps.join("\n\n"), 6),
|
|
717
|
-
""
|
|
718
|
-
].join("\n");
|
|
745
|
+
return renderReviewWorkflow(input, {
|
|
746
|
+
name: "GPT Code Review",
|
|
747
|
+
secretName: SECRET_NAME4,
|
|
748
|
+
// An API key: codex-action needs no OIDC token.
|
|
749
|
+
idToken: false,
|
|
750
|
+
reviewSteps: [
|
|
751
|
+
renderCheckoutStep(REVIEW_GATE_CONDITION, ["ref: refs/pull/${{ github.event.pull_request.number }}/merge"]),
|
|
752
|
+
[
|
|
753
|
+
"- name: Fetch base and head refs for the PR",
|
|
754
|
+
` if: ${REVIEW_GATE_CONDITION}`,
|
|
755
|
+
" env:",
|
|
756
|
+
" PR_BASE_REF: ${{ github.event.pull_request.base.ref }}",
|
|
757
|
+
" PR_NUMBER: ${{ github.event.pull_request.number }}",
|
|
758
|
+
" run: |",
|
|
759
|
+
" # Explicit destinations: the sandboxed review step has no network, so both sides",
|
|
760
|
+
" # of the diff must survive as stable local refs (FETCH_HEAD alone is ambiguous).",
|
|
761
|
+
" git fetch --no-tags origin \\",
|
|
762
|
+
' "+refs/heads/$PR_BASE_REF:refs/remotes/origin/pr-base" \\',
|
|
763
|
+
' "+refs/pull/$PR_NUMBER/head:refs/remotes/origin/pr-head"'
|
|
764
|
+
].join("\n"),
|
|
765
|
+
[
|
|
766
|
+
"- name: Run Codex review",
|
|
767
|
+
" id: codex-review",
|
|
768
|
+
` if: ${REVIEW_GATE_CONDITION}`,
|
|
769
|
+
` uses: ${pinnedUses("openai/codex-action")}`,
|
|
770
|
+
" with:",
|
|
771
|
+
` openai-api-key: \${{ secrets.${SECRET_NAME4} }}`,
|
|
772
|
+
' permission-profile: ":read-only"',
|
|
773
|
+
" prompt: |",
|
|
774
|
+
indentBlock(composePrompt4(input), 6)
|
|
775
|
+
].join("\n"),
|
|
776
|
+
[
|
|
777
|
+
"- name: Post review comment",
|
|
778
|
+
` if: ${REVIEW_GATE_CONDITION}`,
|
|
779
|
+
" env:",
|
|
780
|
+
" GH_TOKEN: ${{ github.token }}",
|
|
781
|
+
" PR_NUMBER: ${{ github.event.pull_request.number }}",
|
|
782
|
+
" REVIEW_BODY: ${{ steps.codex-review.outputs.final-message }}",
|
|
783
|
+
" run: |",
|
|
784
|
+
' printf %s "$REVIEW_BODY" | gh pr comment "$PR_NUMBER" --body-file -'
|
|
785
|
+
].join("\n")
|
|
786
|
+
]
|
|
787
|
+
});
|
|
719
788
|
}
|
|
720
789
|
var gptProvider = {
|
|
721
790
|
id: "gpt",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clearlydev/nx-archweave",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Nx generators that make a workspace ready to work on in one preset: FSD Lite structure with enforced module boundaries, AI agent rules, GitHub templates, and optional AI PR review (Claude, Gemini, GPT, Cursor)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "clearlydev (https://github.com/clearlydev)",
|