-
Notifications
You must be signed in to change notification settings - Fork 0
Cursor new oma req #11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
d34183c
e070bf4
e2d2a66
67acef2
e3391be
09185a3
1a8c094
1a22895
27fd877
67da9b4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| # https://docs.coderabbit.ai/guides/configuration-overview | ||
| # OMA monorepo: frontend (React/Vite), backend (Express/MySQL/Shopify/Socket.IO), desktop (Electron) | ||
| language: en-US | ||
|
|
||
| reviews: | ||
| profile: assertive | ||
| request_changes_workflow: true | ||
| review_details: true | ||
|
|
||
| path_instructions: | ||
| - path: "frontend/src/**/*.{js,jsx}" | ||
| instructions: | | ||
| This path is the React 18 + Vite UI for Order Management Automation (OMA). Treat these as strict blocking rules for changed lines: | ||
|
|
||
| - No ad-hoc `console.log` / `console.debug` / `console.info` in production paths; use an approved logger if the project adds one. | ||
| - No unused variables, imports, or parameters in new/changed code. | ||
| - React lists (`.map`, etc.) must use a stable, unique `key` on the top-level element in the list. | ||
| - No inline object styles on JSX: disallow `style={{ ... }}`; use `frontend/src/styles/` or other CSS files consistent with this repo. | ||
| - API calls go through `frontend/src/services/api.js` (or follow the same axios patterns); new calls must handle errors (`.catch`, user-visible error state, or equivalent)—not silent failures. | ||
| - Socket usage should follow `frontend/src/services/socket.js` / hooks patterns; connection and message errors must be handled or surfaced. | ||
| - No hardcoded secrets, API keys, or tokens; Vite env vars must use the `VITE_` prefix only for client-safe values. | ||
| - Prefer shared components under `frontend/src/components/` and hooks under `frontend/src/hooks/` instead of duplicating non-trivial UI logic. | ||
|
|
||
| If any of the above appears in the diff for this path, you MUST request changes and explain the fix. | ||
|
|
||
| - path: "backend/src/**/*.js" | ||
| instructions: | | ||
| This path is the Node.js + Express API, MySQL access, Shopify webhooks, PDF/print services, and Socket.IO server for OMA. Blocking rules for changed lines: | ||
|
|
||
| - Configuration must come from `backend/src/config/env.js` and environment variables—do not hardcode DB passwords, Shopify secrets, or deployment-specific hosts in source. | ||
| - Webhook and HMAC-sensitive routes must remain protected by the existing Shopify auth middleware (`shopifyAuth` / HMAC validation); do not bypass verification for convenience. | ||
| - Async route handlers and services must propagate errors to Express (`next(err)` or throw into async wrappers) or handle them explicitly—no empty `catch` blocks that hide failures. | ||
| - Database access must use parameterized queries / the existing models layer—no string-concatenated SQL with user-controlled input. | ||
| - New Socket.IO handlers must handle errors and avoid leaking internal stack traces to clients in production. | ||
| - No new dependencies on `eval`, `child_process` with untrusted input, or disabling security middleware without strong justification. | ||
| - Prefer `backend/src/services/` for business logic and keep controllers thin; avoid duplicating rule/PDF/print orchestration across files. | ||
|
|
||
| If any of the above appears in the diff for this path, you MUST request changes and explain the fix. | ||
|
|
||
| - path: "desktop/src/**/*.js" | ||
| instructions: | | ||
| This path is the Electron main process, preload, and renderer for the local print client. Blocking rules for changed lines: | ||
|
|
||
| - Preload must expose APIs only via `contextBridge` + `ipcRenderer` patterns consistent with `desktop/src/preload.js`—do not enable `nodeIntegration` in renderer or expose raw Node APIs widely. | ||
| - IPC channel names and payloads should stay explicit; avoid passing executable code or unsanitized shell commands from renderer to main. | ||
| - Printer and socket configuration must not embed secrets; use `desktop/src/main/config.js` (or env) patterns. | ||
| - Main-process network and printer operations should handle errors without crashing the app; log failures in a way operators can diagnose. | ||
| - No `eval` / `Function` constructor with remote or user-controlled strings. | ||
|
|
||
| If any of the above appears in the diff for this path, you MUST request changes and explain the fix. | ||
|
|
||
| pre_merge_checks: | ||
| custom_checks: | ||
| - name: "OMA monorepo quality (frontend, backend, desktop)" | ||
| mode: error | ||
| instructions: | | ||
| Pass/fail only from the PR diff and files touched in this PR. | ||
|
|
||
| Scope: classify each touched file under `frontend/src/`, `backend/src/`, or `desktop/src/` and apply the matching rules below. Ignore unrelated paths (e.g. docs only) unless they embed secrets. | ||
|
|
||
| **frontend/src (React / Vite)** — FAIL if changed code introduces or leaves: | ||
| 1) Ad-hoc `console.log` / `console.debug` / `console.info` as permanent logging (excluding clearly marked temporary dev scaffolding). | ||
| 2) Unused variables, imports, or parameters in modified files. | ||
| 3) List-rendered React elements without a proper `key` on the outermost element in that list. | ||
| 4) Inline JSX styles `style={{` ... `}}` (except where a third-party API requires it—call that out). | ||
| 5) New axios/fetch/socket flows without reachable error handling or user-visible failure behavior. | ||
| 6) Hardcoded secrets or long-lived tokens in client source. | ||
| 7) Obvious copy-paste duplication of non-trivial UI logic where a shared hook or component is appropriate. | ||
|
|
||
| **backend/src (Express / MySQL / Shopify / Socket.IO)** — FAIL if changed code introduces or leaves: | ||
| 1) Hardcoded credentials, Shopify webhook secrets, or DB passwords in source (must use env + `config/env.js` patterns). | ||
| 2) Webhook routes that skip or weaken HMAC / Shopify auth validation. | ||
| 3) SQL built by concatenating untrusted strings instead of parameters / ORM usage. | ||
| 4) Async routes or services that swallow errors (empty catch, no `next(err)`, no structured response). | ||
| 5) New sensitive operations without considering impact on print jobs, order state, or timeline consistency (call out risky partial updates). | ||
|
|
||
| **desktop/src (Electron)** — FAIL if changed code introduces or leaves: | ||
| 1) Unsafe renderer exposure (e.g. broad Node access from renderer contrary to preload `contextBridge` pattern). | ||
| 2) Secrets or API keys embedded in main/preload/renderer source. | ||
| 3) IPC or shell usage that passes unsanitized user/remote input into execution contexts. | ||
| 4) Printer/socket code paths with no error handling where failures would leave the app in a silent broken state. | ||
|
|
||
| PASS if none of the above apply to the changes in scope. | ||
|
|
||
| If information is insufficient to decide, respond Inconclusive and name the file or behavior needed. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| # CodeRabbit Auto-Fix – What You Need to Update | ||
|
|
||
| ## 1. Repository structure (done) | ||
|
|
||
| - Workflow file is in place: **`.github/workflows/coderabbit-auto-fix.yml`** | ||
|
|
||
| ## 2. Dynamic all branches (done) | ||
|
|
||
| - The workflow uses **no branch filter** under `on.pull_request_review_comment`. | ||
| - So it runs for **every new review comment on any PR, from any branch** (e.g. `main`, `develop`, `feature/*`, `ai/*`). | ||
| - There are **no fixed branches** like `branches: [main, develop]` – all branches are dynamic. | ||
|
|
||
| If you ever want to limit which branches can *target* PRs (e.g. only PRs into `main` or `develop`), you could add: | ||
|
|
||
| ```yaml | ||
| on: | ||
| pull_request_review_comment: | ||
| types: [created] | ||
| branches: ['**'] # or e.g. ['main', 'develop'] to restrict target branch | ||
| ``` | ||
|
|
||
| Leaving `branches` out (as now) means "all branches". | ||
|
|
||
| ## 3. Add Cursor API key in GitHub | ||
|
|
||
| 1. In your repo: **Settings → Secrets and variables → Actions**. | ||
| 2. **Add new secret**: name exactly **`CURSOR_API_KEY`**. | ||
| 3. Value: your Cursor API key. | ||
| 4. The workflow uses it with **HTTP Basic** auth (`curl -u "$CURSOR_API_KEY:"`) — API key as username, empty password, per [Cursor API](https://docs.cursor.com/account/api). | ||
|
|
||
| ## 4. Branch structure (recommended) | ||
|
|
||
| - **main** – production. | ||
| - **develop** – integration. | ||
| - **feature/*** – e.g. `feature/student-api`, `feature/new-login`. | ||
| - **ai/*** – e.g. `ai/add-student-page`, `ai/cart-discount`. | ||
|
|
||
| Cursor/AI-created branches should follow **`ai/<task-name>`**. The workflow does not depend on branch names; it runs on any branch that has a PR with a new review comment. | ||
|
|
||
| ## 5. Optional: apply fixes from Cursor | ||
|
|
||
| The workflow today: | ||
|
|
||
| 1. Detects a comment from **coderabbitai**. | ||
| 2. Checks out the PR branch. | ||
| 3. Sends the comment to **Cursor Cloud Agents** (`POST https://api.cursor.com/v0/agents` with Basic auth — see [Cursor API](https://docs.cursor.com/account/api)). | ||
| 4. Commits and pushes any **local** changes. | ||
|
|
||
| If Cursor returns the fix in the response (e.g. patch or file contents), you may need an **extra step** between "Send suggestion to Cursor AI" and "Commit fixes" that: | ||
|
|
||
| - Reads the API response. | ||
| - Writes or applies the fix in the repo (e.g. apply a patch or overwrite files). | ||
|
|
||
| Then the existing "Commit fixes" step will pick up those changes. If Cursor applies changes in another way (e.g. webhook that pushes to the repo), this step might not be needed. | ||
|
|
||
| ## 6. What you need – checklist (GitHub, CodeRabbit, ClickUp) | ||
|
|
||
| | System | Required? | What you need | | ||
| |------------|-----------|----------------| | ||
| | **GitHub** | Yes | Repo with this workflow file. One secret: **`CURSOR_API_KEY`**. | | ||
| | **CodeRabbit** | Yes | CodeRabbit app installed on the repo (reviews PRs and leaves comments). | | ||
| | **ClickUp** | No | Optional. Only if you want a comment posted to a ClickUp task: add **`CLICKUP_API_KEY`**. No need to set a task ID in secrets. | | ||
|
|
||
| Per-PR task resolution is optional; use **`process.md`** or **`process.md.example`** at the repo root (see below). | ||
|
|
||
| ### ClickUp (optional – task per branch / PR) | ||
|
|
||
| If you want the workflow to post a comment to a **ClickUp task**: | ||
|
|
||
| - Add secret **`CLICKUP_API_KEY`** (your ClickUp API token) in the repo. | ||
| - Put **`clickup_task`** (and optional **`branch`**) in **`process.md`** or **`process.md.example`**, in that order: the workflow uses **`process.md`** first, then **`process.md.example`** if needed. It does **not** read the PR title/body or **`CLICKUP_TASK_ID`** for resolution. | ||
| - The ClickUp comment text uses the **task link** and **branch** from that file only (no PR or commit URLs). | ||
|
|
||
| If you don't add `CLICKUP_API_KEY` or no `clickup_task` is found in either file, the workflow skips posting to ClickUp and still does CodeRabbit → Cursor → commit. | ||
|
|
||
| ## 7. Permissions | ||
|
|
||
| - The workflow has **`permissions: contents: write`** so it can push to the PR branch. | ||
| - It uses **`GITHUB_TOKEN`** for checkout and push; no extra token is required unless your repo rules need it. | ||
|
|
||
| --- | ||
|
|
||
| **Summary:** You only **must** set **`CURSOR_API_KEY`** in GitHub and have CodeRabbit installed. ClickUp is optional; if you use it, add **`CLICKUP_API_KEY`** and define **`clickup_task`** (and optional **`branch`**) in **`process.md`** or **`process.md.example`** on the branch. |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,213 @@ | ||||||||||||||||||||||||||||||||||
| name: CodeRabbit Auto Fix | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| concurrency: | ||||||||||||||||||||||||||||||||||
| group: coderabbit-fix-${{ github.event.pull_request.number }} | ||||||||||||||||||||||||||||||||||
| cancel-in-progress: true | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| on: | ||||||||||||||||||||||||||||||||||
| pull_request_review_comment: | ||||||||||||||||||||||||||||||||||
| types: [created] | ||||||||||||||||||||||||||||||||||
| pull_request_review: | ||||||||||||||||||||||||||||||||||
| types: [submitted] | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| jobs: | ||||||||||||||||||||||||||||||||||
| ai_fix: | ||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if: | | ||||||||||||||||||||||||||||||||||
| contains(github.event.comment.user.login, 'coderabbit') || | ||||||||||||||||||||||||||||||||||
| contains(github.event.review.user.login, 'coderabbit') | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| permissions: | ||||||||||||||||||||||||||||||||||
| contents: write | ||||||||||||||||||||||||||||||||||
| pull-requests: write | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| steps: | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Checkout PR branch | ||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | ||||||||||||||||||||||||||||||||||
| with: | ||||||||||||||||||||||||||||||||||
| ref: ${{ github.event.pull_request.head.ref }} | ||||||||||||||||||||||||||||||||||
| token: ${{ secrets.GITHUB_TOKEN }} | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Extract CodeRabbit comment | ||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||
| EVENT_NAME: ${{ github.event_name }} | ||||||||||||||||||||||||||||||||||
| COMMENT_JSON: ${{ toJSON(github.event.comment.body || '') }} | ||||||||||||||||||||||||||||||||||
| REVIEW_JSON: ${{ toJSON(github.event.review.body || '') }} | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| if [ "$EVENT_NAME" = "pull_request_review_comment" ]; then | ||||||||||||||||||||||||||||||||||
| COMMENT_BODY=$(echo "$COMMENT_JSON" | jq -r .) | ||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||
| COMMENT_BODY=$(echo "$REVIEW_JSON" | jq -r .) | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| echo "COMMENT_BODY<<EOF" >> $GITHUB_ENV | ||||||||||||||||||||||||||||||||||
| echo "$COMMENT_BODY" >> $GITHUB_ENV | ||||||||||||||||||||||||||||||||||
| echo "EOF" >> $GITHUB_ENV | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Debug comment | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| echo "Detected CodeRabbit suggestion:" | ||||||||||||||||||||||||||||||||||
| echo "$COMMENT_BODY" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Skip if comment empty | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| if [ -z "$COMMENT_BODY" ]; then | ||||||||||||||||||||||||||||||||||
| echo "No comment body found. Skipping." | ||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+54
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When the comment body is empty, 🛠️ Proposed fix: Fail the job or use an output to skip subsequent stepsOption 1 - Fail early: - name: Skip if comment empty
run: |
if [ -z "$COMMENT_BODY" ]; then
echo "No comment body found. Skipping."
- exit 0
+ exit 1
fiOption 2 - Set an output and add conditions to subsequent steps: - name: Skip if comment empty
+ id: check_comment
run: |
if [ -z "$COMMENT_BODY" ]; then
echo "No comment body found. Skipping."
- exit 0
+ echo "skip=true" >> $GITHUB_OUTPUT
+ else
+ echo "skip=false" >> $GITHUB_OUTPUT
fiThen add 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Resolve ClickUp task and validate branch | ||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| TASK_ID="" | ||||||||||||||||||||||||||||||||||
| PROC_BRANCH="" | ||||||||||||||||||||||||||||||||||
| PROC_TASK_URL="" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| proc_get() { | ||||||||||||||||||||||||||||||||||
| local key="$1" | ||||||||||||||||||||||||||||||||||
| local file="$2" | ||||||||||||||||||||||||||||||||||
| local line | ||||||||||||||||||||||||||||||||||
| line=$(grep -E "^[[:space:]]*${key}:[[:space:]]*" "$file" | head -1 || true) | ||||||||||||||||||||||||||||||||||
| [ -z "$line" ] && return 0 | ||||||||||||||||||||||||||||||||||
| echo "$line" | sed -E "s/^[[:space:]]*${key}:[[:space:]]*//;s/[[:space:]]*#.*$//;s/[[:space:]]*$//;s/^[\"']//;s/[\"']$//" | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| id_from_clickup_string() { | ||||||||||||||||||||||||||||||||||
| local s="$1" | ||||||||||||||||||||||||||||||||||
| local id | ||||||||||||||||||||||||||||||||||
| id=$(echo "$s" | grep -oEi '/t/[a-z0-9]+' | tail -1 | sed 's|^/t/||' || true) | ||||||||||||||||||||||||||||||||||
| if [ -z "$id" ]; then | ||||||||||||||||||||||||||||||||||
| id=$(echo "$s" | grep -oEi 'clickup\.com/t/[a-z0-9]+' | head -1 | sed 's|.*/t/||' || true) | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
| echo "$id" | ||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| for PROC_FILE in process.md process.md.example; do | ||||||||||||||||||||||||||||||||||
| [ -f "$PROC_FILE" ] || continue | ||||||||||||||||||||||||||||||||||
| echo "Parsing $PROC_FILE for clickup_task and branch." | ||||||||||||||||||||||||||||||||||
| PROC_BRANCH=$(proc_get branch "$PROC_FILE" || true) | ||||||||||||||||||||||||||||||||||
| PROC_TASK_RAW=$(proc_get clickup_task "$PROC_FILE" || true) | ||||||||||||||||||||||||||||||||||
| if [ -z "$PROC_TASK_RAW" ]; then | ||||||||||||||||||||||||||||||||||
| continue | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
| if echo "$PROC_TASK_RAW" | grep -qi 'clickup\.com'; then | ||||||||||||||||||||||||||||||||||
| TASK_ID=$(id_from_clickup_string "$PROC_TASK_RAW") | ||||||||||||||||||||||||||||||||||
| PROC_TASK_URL=$(echo "$PROC_TASK_RAW" | tr -d '\r' | sed 's/[[:space:]]*$//') | ||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||
| CLEAN=$(echo "$PROC_TASK_RAW" | tr -d '\r') | ||||||||||||||||||||||||||||||||||
| if echo "$CLEAN" | grep -qE '^[a-zA-Z0-9_-]+$'; then | ||||||||||||||||||||||||||||||||||
| TASK_ID="$CLEAN" | ||||||||||||||||||||||||||||||||||
| PROC_TASK_URL="https://app.clickup.com/t/${TASK_ID}" | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
| if [ -n "$TASK_ID" ]; then | ||||||||||||||||||||||||||||||||||
| echo "ClickUp task id from $PROC_FILE: $TASK_ID" | ||||||||||||||||||||||||||||||||||
| break | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if [ -z "$TASK_ID" ]; then | ||||||||||||||||||||||||||||||||||
| echo "No clickup_task in process.md or process.md.example; skipping ClickUp validation and comments." | ||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||
| if [ -z "$PROC_BRANCH" ]; then | ||||||||||||||||||||||||||||||||||
| echo "::error::When clickup_task is set, branch must be set in process.md or process.md.example (e.g. branch: cursor_new_oma_req) and must match the PR head branch." | ||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
| if [ "$PROC_BRANCH" != "$HEAD_REF" ]; then | ||||||||||||||||||||||||||||||||||
| echo "::error::branch in process file ('$PROC_BRANCH') must match PR head ref ('$HEAD_REF'). Update process.md or use a PR from the correct branch." | ||||||||||||||||||||||||||||||||||
| exit 1 | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
| echo "Branch validated: process branch matches PR head ($HEAD_REF)." | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| echo "TASK_ID=$TASK_ID" >> $GITHUB_ENV | ||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||
| echo "PROC_TASK_URL<<__PROC_EOF__" | ||||||||||||||||||||||||||||||||||
| echo "${PROC_TASK_URL:-}" | ||||||||||||||||||||||||||||||||||
| echo "__PROC_EOF__" | ||||||||||||||||||||||||||||||||||
| } >> $GITHUB_ENV | ||||||||||||||||||||||||||||||||||
| echo "PROC_BRANCH=$PROC_BRANCH" >> $GITHUB_ENV | ||||||||||||||||||||||||||||||||||
| echo "Final ClickUp task id: ${TASK_ID:-<empty>}" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Optional Cursor integration (Cursor Cloud Agents API — see https://docs.cursor.com/account/api) | ||||||||||||||||||||||||||||||||||
| - name: Send suggestion to Cursor AI | ||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||
| CURSOR_API_KEY: ${{ secrets.CURSOR_API_KEY }} | ||||||||||||||||||||||||||||||||||
| REPO_URL: ${{ github.server_url }}/${{ github.repository }} | ||||||||||||||||||||||||||||||||||
| HEAD_REF: ${{ github.event.pull_request.head.ref }} | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| if [ -z "$CURSOR_API_KEY" ]; then | ||||||||||||||||||||||||||||||||||
| echo "CURSOR_API_KEY not configured, skipping Cursor step." | ||||||||||||||||||||||||||||||||||
| exit 0 | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| echo "Launching Cursor Cloud Agent for PR head ref: $HEAD_REF" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| BODY=$(jq -n \ | ||||||||||||||||||||||||||||||||||
| --arg text "$COMMENT_BODY" \ | ||||||||||||||||||||||||||||||||||
| --arg repo "$REPO_URL" \ | ||||||||||||||||||||||||||||||||||
| --arg ref "$HEAD_REF" \ | ||||||||||||||||||||||||||||||||||
| '{prompt: {text: ("Address this CodeRabbit review feedback on branch " + $ref + ":\n\n" + $text)}, source: {repository: $repo, ref: $ref}, target: {autoCreatePr: false}}') | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| # Cursor API uses HTTP Basic auth (API key as username, empty password) | ||||||||||||||||||||||||||||||||||
| RESP=$(curl -s -w "\n%{http_code}" -X POST https://api.cursor.com/v0/agents \ | ||||||||||||||||||||||||||||||||||
| -u "$CURSOR_API_KEY:" \ | ||||||||||||||||||||||||||||||||||
| -H "Content-Type: application/json" \ | ||||||||||||||||||||||||||||||||||
| -d "$BODY" || true) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| echo "Cursor API response:" | ||||||||||||||||||||||||||||||||||
| echo "$RESP" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Commit fixes if AI modified files | ||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||
| PR_HEAD_REF: ${{ github.event.pull_request.head.ref }} | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| git config user.name "ai-bot" | ||||||||||||||||||||||||||||||||||
| git config user.email "ai@bot.com" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| git add . | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if git diff --staged --quiet; then | ||||||||||||||||||||||||||||||||||
| echo "No code changes detected." | ||||||||||||||||||||||||||||||||||
| else | ||||||||||||||||||||||||||||||||||
| git commit -m "fix: apply CodeRabbit suggestion" | ||||||||||||||||||||||||||||||||||
| git push origin "HEAD:${PR_HEAD_REF}" | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+171
to
+178
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Using 🔧 Suggested alternatives- git add .
+ git add -A # Or specify paths: git add frontend/ backend/ desktop/Or check what's being staged before committing: git status --porcelain
git add -A📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Post CodeRabbit suggestion to ClickUp | ||||||||||||||||||||||||||||||||||
| if: env.TASK_ID != '' | ||||||||||||||||||||||||||||||||||
| env: | ||||||||||||||||||||||||||||||||||
| CLICKUP_API_KEY: ${{ secrets.CLICKUP_API_KEY }} | ||||||||||||||||||||||||||||||||||
| run: | | ||||||||||||||||||||||||||||||||||
| SUMMARY="CodeRabbit Review Summary | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| $COMMENT_BODY" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| COMMENT="@Cursor | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| $SUMMARY | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| Task: ${{ env.PROC_TASK_URL }} | ||||||||||||||||||||||||||||||||||
| Branch: ${{ env.PROC_BRANCH }}" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| BODY=$(jq -n --arg text "$COMMENT" '{comment_text:$text, notify_all:false}') | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| RESP=$(curl -s -w "\n%{http_code}" -X POST "https://api.clickup.com/api/v2/task/${TASK_ID}/comment" \ | ||||||||||||||||||||||||||||||||||
| -H "Authorization: $CLICKUP_API_KEY" \ | ||||||||||||||||||||||||||||||||||
| -H "Content-Type: application/json" \ | ||||||||||||||||||||||||||||||||||
| -d "$BODY") | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| HTTP_CODE=$(echo "$RESP" | tail -n1) | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| echo "ClickUp response code: $HTTP_CODE" | ||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| if [ "$HTTP_CODE" != "200" ]; then | ||||||||||||||||||||||||||||||||||
| echo "ClickUp response:" | ||||||||||||||||||||||||||||||||||
| echo "$RESP" | ||||||||||||||||||||||||||||||||||
| fi | ||||||||||||||||||||||||||||||||||
|
Comment on lines
+207
to
+210
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ClickUp API response check may miss successful responses. The check 🔧 Suggested fix- if [ "$HTTP_CODE" != "200" ]; then
+ if [ "$HTTP_CODE" -lt 200 ] || [ "$HTTP_CODE" -ge 300 ]; then
echo "ClickUp response:"
echo "$RESP"
fi🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||
| - name: Finish | ||||||||||||||||||||||||||||||||||
| run: echo "Workflow completed successfully." | ||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| node_modules/ | ||
| .env | ||
| dist/ | ||
| generated-pdfs/ | ||
| *.log | ||
| .DS_Store |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actor check via
contains()is weak and potentially spoofable.Using
contains(github.event.comment.user.login, 'coderabbit')matches any username containing the substring "coderabbit" (e.g., "fakecoderabbit" or "mycoderabbittest"). This could allow unintended actors to trigger the workflow.🔒 Proposed fix: Use exact match
If CodeRabbit uses multiple bot accounts, consider an explicit allowlist check instead.
📝 Committable suggestion
🤖 Prompt for AI Agents