From 0486dff685618ee1db2f96a8e0e321b9486e90c2 Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Thu, 25 Jun 2026 14:19:01 -0700 Subject: [PATCH 1/3] feat(cursor-review): optional dedicated bot identity for review posting (BE-1812) Post the consolidated review + per-finding line comments under an optional dedicated GitHub App identity (e.g. cloud-code-bot[bot]) instead of the shared github-actions[bot], so the threads are distinct and queryable. - Declare optional workflow_call secrets BOT_APP_ID + BOT_APP_PRIVATE_KEY. - Conditionally mint an app token (actions/create-github-app-token@v2) when set. - Post review uses steps.bot_token.outputs.token || secrets.GITHUB_TOKEN. Red-safe: with no creds the mint step is skipped and posting stays github-actions[bot] -- zero behavior change for any consumer. Dedup keys on the review body marker and triggerer attribution already handles a bot actor, so no companion edits were needed. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/cursor-review.yml | 35 ++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cursor-review.yml b/.github/workflows/cursor-review.yml index 810421e..6c738e4 100644 --- a/.github/workflows/cursor-review.yml +++ b/.github/workflows/cursor-review.yml @@ -97,6 +97,17 @@ on: SLACK_BOT_TOKEN: description: Slack bot token for the start/complete DM notifications. Optional — DMs are skipped if absent. required: false + BOT_APP_ID: + description: >- + GitHub App ID. When set (with BOT_APP_PRIVATE_KEY), the consolidated + review + per-finding line comments post under that App's identity + (e.g. cloud-code-bot[bot]) instead of github-actions[bot], so its + threads are distinct and queryable. Optional — omit to post as + github-actions[bot] (default; unchanged for OSS consumers). + required: false + BOT_APP_PRIVATE_KEY: + description: PEM private key for BOT_APP_ID. Required only when BOT_APP_ID is set. + required: false # DIFF_SIZE_CAP / REVIEW_LABEL / JUDGE_MODEL / DIFF_EXCLUDES are mapped from # `inputs` here so the run steps below read them verbatim from the original @@ -573,9 +584,31 @@ jobs: echo "triggered_by=$GH_ACTOR" >> "$GITHUB_OUTPUT" fi + - name: Detect bot identity + id: bot_cfg + env: + BOT_APP_ID: ${{ secrets.BOT_APP_ID }} + run: | + # `secrets` can't be referenced in a step `if:`, so surface presence + # as a step output the mint step can gate on. + if [ -n "$BOT_APP_ID" ]; then + echo "enabled=true" >> "$GITHUB_OUTPUT" + else + echo "enabled=false" >> "$GITHUB_OUTPUT" + fi + + - name: Mint bot-identity token (optional) + id: bot_token + if: ${{ steps.bot_cfg.outputs.enabled == 'true' }} + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.BOT_APP_ID }} + private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} + - name: Post review env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Dedicated bot identity when configured (BOT_APP_ID), else github-actions[bot]. + GH_TOKEN: ${{ steps.bot_token.outputs.token || secrets.GITHUB_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} REPO: ${{ github.repository }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} From e600ea39b9a93d4d958336dcf28d3ebeaca78718 Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Thu, 25 Jun 2026 15:26:52 -0700 Subject: [PATCH 2/3] refactor(cursor-review): App ID as input (reuse cloud-code-bot), drop secrets-if workaround App IDs aren't secret, and the org already stores cloud-code-bot's as the APP_ID *variable* (+ CLOUD_CODE_BOT_PRIVATE_KEY secret), used by several cloud workflows. Make bot_app_id a workflow_call input instead of a secret; this also lets the mint step gate on 'if: inputs.bot_app_id != ""' directly, removing the detect-step that only existed because 'secrets' is not a valid step-if context. Bump create-github-app-token v2 -> v3 to match cloud's existing pin. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/cursor-review.yml | 47 +++++++++++++---------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/.github/workflows/cursor-review.yml b/.github/workflows/cursor-review.yml index 6c738e4..7655fcb 100644 --- a/.github/workflows/cursor-review.yml +++ b/.github/workflows/cursor-review.yml @@ -33,9 +33,14 @@ name: Cursor Review (reusable) # # Pin the assets ref to the same ref you pin `uses:` to for # # reproducibility (defaults to main). # workflows_ref: main +# # Optional dedicated review identity (else posts as github-actions[bot]). +# # Comfy: the shared Cloud Code Bot — its App ID lives in the APP_ID var. +# bot_app_id: ${{ vars.APP_ID }} # secrets: # CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} +# # Optional — pairs with bot_app_id. Comfy: CLOUD_CODE_BOT_PRIVATE_KEY. +# BOT_APP_PRIVATE_KEY: ${{ secrets.CLOUD_CODE_BOT_PRIVATE_KEY }} on: workflow_call: @@ -90,6 +95,17 @@ on: type: string required: false default: main + bot_app_id: + description: >- + GitHub App ID. When set (with the bot_app_private_key secret), the + consolidated review + per-finding line comments post under that App's + identity (e.g. Cloud Code Bot -> cloud-code-bot[bot]) instead of + github-actions[bot], so its threads are distinct and queryable. + Optional — omit to post as github-actions[bot] (default; unchanged for + OSS consumers). App IDs aren't secret, so this is an input, not a secret. + type: string + required: false + default: '' secrets: CURSOR_API_KEY: description: Cursor API key for cursor-agent (the panel + judge models bill through it). @@ -97,16 +113,8 @@ on: SLACK_BOT_TOKEN: description: Slack bot token for the start/complete DM notifications. Optional — DMs are skipped if absent. required: false - BOT_APP_ID: - description: >- - GitHub App ID. When set (with BOT_APP_PRIVATE_KEY), the consolidated - review + per-finding line comments post under that App's identity - (e.g. cloud-code-bot[bot]) instead of github-actions[bot], so its - threads are distinct and queryable. Optional — omit to post as - github-actions[bot] (default; unchanged for OSS consumers). - required: false BOT_APP_PRIVATE_KEY: - description: PEM private key for BOT_APP_ID. Required only when BOT_APP_ID is set. + description: PEM private key matching the bot_app_id input. Required only when bot_app_id is set. required: false # DIFF_SIZE_CAP / REVIEW_LABEL / JUDGE_MODEL / DIFF_EXCLUDES are mapped from @@ -584,30 +592,17 @@ jobs: echo "triggered_by=$GH_ACTOR" >> "$GITHUB_OUTPUT" fi - - name: Detect bot identity - id: bot_cfg - env: - BOT_APP_ID: ${{ secrets.BOT_APP_ID }} - run: | - # `secrets` can't be referenced in a step `if:`, so surface presence - # as a step output the mint step can gate on. - if [ -n "$BOT_APP_ID" ]; then - echo "enabled=true" >> "$GITHUB_OUTPUT" - else - echo "enabled=false" >> "$GITHUB_OUTPUT" - fi - - name: Mint bot-identity token (optional) id: bot_token - if: ${{ steps.bot_cfg.outputs.enabled == 'true' }} - uses: actions/create-github-app-token@v2 + if: ${{ inputs.bot_app_id != '' }} + uses: actions/create-github-app-token@v3 with: - app-id: ${{ secrets.BOT_APP_ID }} + app-id: ${{ inputs.bot_app_id }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} - name: Post review env: - # Dedicated bot identity when configured (BOT_APP_ID), else github-actions[bot]. + # Dedicated bot identity when configured (bot_app_id), else github-actions[bot]. GH_TOKEN: ${{ steps.bot_token.outputs.token || secrets.GITHUB_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} REPO: ${{ github.repository }} From f4427a4c813dd21ee0b732809b600754cd8fbaca Mon Sep 17 00:00:00 2001 From: Matt Miller Date: Thu, 25 Jun 2026 17:29:11 -0700 Subject: [PATCH 3/3] docs(cursor-review): genericize bot-identity example comments for OSS The reusable workflow is consumed open-source; the example caller comments named Comfy's specific bot + secret names. Swap them for generic placeholders (REVIEW_BOT_APP_ID / REVIEW_BOT_PRIVATE_KEY) so consumers plug in their own App. The interface (bot_app_id / BOT_APP_PRIVATE_KEY) was already identity-agnostic; this is comments only. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/cursor-review.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cursor-review.yml b/.github/workflows/cursor-review.yml index 7655fcb..5531a15 100644 --- a/.github/workflows/cursor-review.yml +++ b/.github/workflows/cursor-review.yml @@ -33,14 +33,15 @@ name: Cursor Review (reusable) # # Pin the assets ref to the same ref you pin `uses:` to for # # reproducibility (defaults to main). # workflows_ref: main -# # Optional dedicated review identity (else posts as github-actions[bot]). -# # Comfy: the shared Cloud Code Bot — its App ID lives in the APP_ID var. -# bot_app_id: ${{ vars.APP_ID }} +# # Optional: post the review under your own GitHub App so its threads are +# # a distinct, queryable identity instead of github-actions[bot]. Supply +# # your App's id + private key (App IDs aren't secret, so id is an input). +# bot_app_id: ${{ vars.REVIEW_BOT_APP_ID }} # secrets: # CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} # SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }} -# # Optional — pairs with bot_app_id. Comfy: CLOUD_CODE_BOT_PRIVATE_KEY. -# BOT_APP_PRIVATE_KEY: ${{ secrets.CLOUD_CODE_BOT_PRIVATE_KEY }} +# # Optional — the private key paired with bot_app_id. +# BOT_APP_PRIVATE_KEY: ${{ secrets.REVIEW_BOT_PRIVATE_KEY }} on: workflow_call: @@ -99,7 +100,7 @@ on: description: >- GitHub App ID. When set (with the bot_app_private_key secret), the consolidated review + per-finding line comments post under that App's - identity (e.g. Cloud Code Bot -> cloud-code-bot[bot]) instead of + identity (your App's "[bot]" login) instead of github-actions[bot], so its threads are distinct and queryable. Optional — omit to post as github-actions[bot] (default; unchanged for OSS consumers). App IDs aren't secret, so this is an input, not a secret.