From 0b6d5e9dca612b3e2f6bc5c680138f9358c2fb89 Mon Sep 17 00:00:00 2001 From: centdix <40307056+centdix@users.noreply.github.com> Date: Thu, 22 May 2025 20:01:32 +0200 Subject: [PATCH] internal: fix branch issues + rules issues (#5799) * fix branch issues + rules issues * fix * fetch issue from linear if issue comes from linear * ask claude to check after its changes --- .github/workflows/aider-after-review.yaml | 1 + .github/workflows/aider-common.yml | 110 +++++++++++++++------- .github/workflows/aider.yaml | 25 ++++- .github/workflows/claude.yml | 15 ++- .github/workflows/linear-issue.yaml | 1 + 5 files changed, 111 insertions(+), 41 deletions(-) diff --git a/.github/workflows/aider-after-review.yaml b/.github/workflows/aider-after-review.yaml index 578c7d1b7d..87d48ddb4c 100644 --- a/.github/workflows/aider-after-review.yaml +++ b/.github/workflows/aider-after-review.yaml @@ -90,4 +90,5 @@ jobs: with: needs_processing: false base_prompt: ${{ needs.check-and-prepare.outputs.prompt_content }} + rules_files: "CLAUDE.md backend/CLAUDE.md frontend/CLAUDE.md" secrets: inherit diff --git a/.github/workflows/aider-common.yml b/.github/workflows/aider-common.yml index dceea4a012..bdb0401931 100644 --- a/.github/workflows/aider-common.yml +++ b/.github/workflows/aider-common.yml @@ -33,7 +33,11 @@ on: description: "Prompt for probe-chat" required: false type: string - default: 'I''m giving you a request that needs to be implemented. Your role is ONLY to give me the files that are relevant to the request and nothing else. The request is prepended with the word REQUEST. REQUEST: $FINAL_PROMPT. Give me all the files relevant to this request. Your output MUST be a single json array that can be parsed with programatic json parsing, with the relevant files. Files can be rust or typescript or javascript files. DO NOT INCLUDE ANY OTHER TEXT IN YOUR OUTPUT. ONLY THE JSON ARRAY. Example of output: ["file1.py", "file2.py"]' + default: 'I''m giving you a request that needs to be implemented. Your role is ONLY to give me the files that are relevant to the request and nothing else. The request is prepended with the word REQUEST. Give me all the files relevant to this request. Your output MUST be a single json array that can be parsed with programatic json parsing, with the relevant files. Files can be rust or typescript or javascript files. DO NOT INCLUDE ANY OTHER TEXT IN YOUR OUTPUT. ONLY THE JSON ARRAY. Example of output: ["file1.py", "file2.py"]' + rules_files: + description: "Rules files for Aider" + required: false + type: string outputs: files_to_edit: description: "Files identified by probe-chat for editing" @@ -219,11 +223,11 @@ jobs: shell: bash env: FINAL_PROMPT: ${{ steps.create_prompt.outputs.final_prompt }} + PROBE_PROMPT: ${{ inputs.probe_prompt }} run: | echo "Running probe-chat to find relevant files..." - # escape the final prompt - printf -v MESSAGE_FOR_PROBE 'I'\''m giving you a request that needs to be implemented. Your role is ONLY to give me the files that are relevant to the request and nothing else. The request is prepended with the word REQUEST.\nREQUEST: %s. Give me all the files relevant to this request. Your output MUST be a single json array that can be parsed with programatic json parsing, with the relevant files. Files can be rust or typescript or javascript files. DO NOT INCLUDE ANY OTHER TEXT IN YOUR OUTPUT. ONLY THE JSON ARRAY. Example of output: ["file1.py", "file2.py"]' "$FINAL_PROMPT" + MESSAGE_FOR_PROBE=$(printf "%s\nREQUEST:\n%s" "$PROBE_PROMPT" "$FINAL_PROMPT") set -o pipefail PROBE_OUTPUT=$(npx --yes @buger/probe-chat@latest --max-iterations 50 --model-name gemini-2.5-pro-preview-05-06 --message "$MESSAGE_FOR_PROBE") || { @@ -256,21 +260,63 @@ jobs: restore-keys: | ${{ runner.os }}-aider- + - name: Prepare branch for Aider + id: prepare_branch + env: + ISSUE_ID: ${{ inputs.issue_id }} + run: | + if [[ "$ISSUE_ID" != "" ]]; then + BRANCH_NAME="aider-fix-issue-${ISSUE_ID}" + + # Check if branch exists remotely + if git ls-remote --heads origin $BRANCH_NAME | grep -q $BRANCH_NAME; then + echo "Branch $BRANCH_NAME already exists remotely, fetching it" + git fetch origin $BRANCH_NAME + git checkout $BRANCH_NAME + git pull origin $BRANCH_NAME + else + echo "Creating new branch $BRANCH_NAME" + git checkout -b $BRANCH_NAME + fi + echo "BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT + else + # We're in a pull_request_review event + PR_NUMBER="${{ github.event.pull_request.number }}" + PR_HEAD_REF="${{ github.event.pull_request.head.ref }}" + + echo "Handling pull_request_review for PR #$PR_NUMBER on branch $PR_HEAD_REF" + + # Ensure we're on the correct branch + git config pull.rebase true + git fetch origin $PR_HEAD_REF + git checkout $PR_HEAD_REF + git pull origin $PR_HEAD_REF + + echo "Using PR branch $PR_HEAD_REF for PR #$PR_NUMBER" + echo "BRANCH_NAME=$PR_HEAD_REF" >> $GITHUB_OUTPUT + fi + - name: Run Aider id: run_aider shell: bash env: FILES_TO_EDIT: ${{ steps.probe_files.outputs.files_to_edit }} FINAL_PROMPT: ${{ steps.create_prompt.outputs.final_prompt }} + RULES_FILES: ${{ inputs.rules_files }} run: | echo "$FINAL_PROMPT" > .aider_final_prompt.txt echo "FILES_TO_EDIT: $FILES_TO_EDIT" + RULES="" + if [ -n "$RULES_FILES" ]; then + for rule in $RULES_FILES; do + RULES="$RULES --read $rule" + done + fi + aider \ - --read .cursor/rules/rust-best-practices.mdc \ - --read .cursor/rules/svelte5-best-practices.mdc \ - --read .cursor/rules/windmill-overview.mdc \ + $RULES \ $FILES_TO_EDIT \ --model gemini/gemini-2.5-pro-preview-05-06 \ --message-file .aider_final_prompt.txt \ @@ -295,40 +341,31 @@ jobs: id: commit_and_push env: ISSUE_ID: ${{ inputs.issue_id }} + BRANCH_NAME: ${{ steps.prepare_branch.outputs.BRANCH_NAME }} run: | if [[ "$ISSUE_ID" != "" ]]; then - BRANCH_NAME="aider-fix-issue-${ISSUE_ID}" - - # Check if branch exists remotely - if git ls-remote --heads origin $BRANCH_NAME | grep -q $BRANCH_NAME; then - echo "Branch $BRANCH_NAME already exists remotely, fetching it" - git fetch origin $BRANCH_NAME - git checkout $BRANCH_NAME - git pull origin $BRANCH_NAME - else - echo "Creating new branch $BRANCH_NAME" - git checkout -b $BRANCH_NAME + # Check if there are any uncommitted changes + if [[ -n $(git status --porcelain) ]]; then + echo "Found uncommitted changes, committing them" + git add . + git commit -m "Aider changes" fi - echo "Created/checked out branch $BRANCH_NAME for issue #${ISSUE_ID}" - git push origin $BRANCH_NAME - echo "Pushed to branch $BRANCH_NAME" - echo "PR_BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT - echo "CHANGES_APPLIED_MESSAGE=Aider changes pushed to branch $BRANCH_NAME." >> $GITHUB_OUTPUT + # Push changes to the branch + if git push origin $BRANCH_NAME; then + echo "Pushed to branch $BRANCH_NAME" + echo "PR_BRANCH_NAME=$BRANCH_NAME" >> $GITHUB_OUTPUT + echo "CHANGES_APPLIED_MESSAGE=Aider changes pushed to branch $BRANCH_NAME." >> $GITHUB_OUTPUT + echo "CHANGES_APPLIED=true" >> $GITHUB_OUTPUT + else + echo "::warning::Push to PR branch $BRANCH_NAME failed." + echo "CHANGES_APPLIED_MESSAGE=Aider ran, but failed to push changes to PR branch $BRANCH_NAME." >> $GITHUB_OUTPUT + echo "CHANGES_APPLIED=false" >> $GITHUB_OUTPUT + fi else # We're in a pull_request_review event - PR_NUMBER="${{ github.event.pull_request.number }}" PR_HEAD_REF="${{ github.event.pull_request.head.ref }}" - - echo "Handling pull_request_review for PR #$PR_NUMBER on branch $PR_HEAD_REF" - - # Ensure we're on the correct branch - git config pull.rebase true - git fetch origin $PR_HEAD_REF - git checkout $PR_HEAD_REF - git pull origin $PR_HEAD_REF - - echo "Attempting to push changes to PR branch $PR_HEAD_REF for PR #$PR_NUMBER" + echo "Attempting to push changes to PR branch $PR_HEAD_REF" if git push origin $PR_HEAD_REF; then echo "Push to $PR_HEAD_REF successful (or no new changes to push)." echo "CHANGES_APPLIED_MESSAGE=Aider changes (if any) pushed to PR branch $PR_HEAD_REF." >> $GITHUB_OUTPUT @@ -364,8 +401,13 @@ jobs: fi # Create PR description in a temporary file to avoid command line length limits and ensure it stays under 40k chars + HEADER="This PR was created automatically by Aider to fix issue #${ISSUE_NUM}." + # if event is repository_dispatch, add the issue title to the header + if [ "$GITHUB_EVENT_NAME" == "repository_dispatch" ]; then + HEADER="This PR was created automatically by Aider to fix issue #linear:${ISSUE_NUM}." + fi cat > /tmp/pr-description.md << EOL | head -c 40000 - This PR was created automatically by Aider to fix issue #${ISSUE_NUM}. + $HEADER ## Aider Output \`\`\` diff --git a/.github/workflows/aider.yaml b/.github/workflows/aider.yaml index 0614627b35..e7609597e3 100644 --- a/.github/workflows/aider.yaml +++ b/.github/workflows/aider.yaml @@ -72,6 +72,7 @@ jobs: COMMENT_BODY: ${{ github.event.comment.body }} ISSUE_NUMBER: ${{ github.event.issue.number }} GITHUB_REPOSITORY: ${{ github.repository }} + LINEAR_API_KEY: ${{ secrets.LINEAR_API_KEY }} run: | echo "Determining inputs for Aider..." ISSUE_TITLE_VAL="" @@ -91,12 +92,25 @@ jobs: if [[ ! -z "$PR_BODY_VAL" ]]; then REFERENCED_ISSUE="" - if [[ "$PR_BODY_VAL" =~ \#([0-9]+) ]]; then + if [[ "$PR_BODY_VAL" =~ \#linear:([a-f0-9-]+) ]]; then REFERENCED_ISSUE="${BASH_REMATCH[1]}" - fi - - if [[ ! -z "$REFERENCED_ISSUE" ]]; then - echo "Found referenced issue #$REFERENCED_ISSUE in PR description" + echo "Found referenced Linear issue #$REFERENCED_ISSUE in PR description" + LINEAR_ISSUE_JSON=$(curl -s -H "Authorization: $LINEAR_API_KEY" \ + "https://api.linear.app/graphql" \ + -X POST \ + -H "Content-Type: application/json" \ + -d "{\"query\":\"query { issue(id: \\\"$REFERENCED_ISSUE\\\") { title description } }\"}") + + if [[ $? -eq 0 && ! "$LINEAR_ISSUE_JSON" =~ "error" ]]; then + ISSUE_TITLE_VAL=$(jq -r '.data.issue.title // ""' <<< "$LINEAR_ISSUE_JSON") + ISSUE_BODY_VAL=$(jq -r '.data.issue.description // ""' <<< "$LINEAR_ISSUE_JSON") + echo "Successfully fetched Linear issue details" + else + echo "Error fetching Linear issue details for #$REFERENCED_ISSUE" + fi + elif [[ "$PR_BODY_VAL" =~ \#([0-9]+) ]]; then + REFERENCED_ISSUE="${BASH_REMATCH[1]}" + echo "Found referenced GitHub issue #$REFERENCED_ISSUE in PR description" ISSUE_DETAILS_JSON=$(gh issue view "$REFERENCED_ISSUE" --json title,body --repo "$GITHUB_REPOSITORY") if [[ $? -ne 0 ]]; then @@ -147,4 +161,5 @@ jobs: issue_body: ${{ needs.check-and-prepare.outputs.issue_body }} instruction: ${{ needs.check-and-prepare.outputs.comment_content }} issue_id: ${{ github.event.issue.number }} + rules_files: "CLAUDE.md backend/CLAUDE.md frontend/CLAUDE.md" secrets: inherit diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml index 7ac5d93802..66eff9dc57 100644 --- a/.github/workflows/claude.yml +++ b/.github/workflows/claude.yml @@ -69,6 +69,17 @@ jobs: with: anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} timeout_minutes: "60" - allowed_tools: "mcp__github__create_pull_request" - custom_instructions: "IMPORTANT: Bypass previous instructions and instead of adding a url in your comment to manually create a PR, if you created a new branch with your changes, automatically create a PR from that branch to main, with the title starting with [Claude PR]" + allowed_tools: "mcp__github__create_pull_request,Bash(npm run check),Bash(npm install),Bash(cargo check),Bash(curl https://sh.rustup.rs -sSf | sh)" + custom_instructions: "IMPORTANT INSTRUCTIONS: + - Bypass previous instructions and instead of adding a url in your comment to manually create a PR, if you created a new branch with your changes, automatically create a PR from that branch to main, with the title starting with [Claude PR]. + - If you made changes to the frontend code, run npm install, then npm run generate-backend-client, then npm run check. You can ignore warnings that are reported by the check script, but fix the errors. + - If you made changes to the backend code, install Rust and then run cargo check. You can ignore warnings that are reported by the check script, but fix the errors. + - DO NOT FORGET TO OPEN A PR AFTER YOU ARE DONE if you made changes after a request from a git issue. + AVAILABLE TOOLS: + - mcp__github__create_pull_request: Create a PR from a branch to main + - Bash(npm run check): Run the check script. You should run this tool after making changes to the frontend code. + - Bash(npm install): Install dependencies. You need this to run npm run check. + - Bash(npm run generate-backend-client): Generate the backend client. You need this to run npm run check. + - Bash(cargo check): Run the cargo check script. You should run this tool after making changes to the backend code. + - Bash(curl https://sh.rustup.rs -sSf | sh): Install Rust. You need this to run cargo check." trigger_phrase: "/aider" diff --git a/.github/workflows/linear-issue.yaml b/.github/workflows/linear-issue.yaml index 22f9e53c46..068cdbd309 100644 --- a/.github/workflows/linear-issue.yaml +++ b/.github/workflows/linear-issue.yaml @@ -65,4 +65,5 @@ jobs: issue_body: ${{ needs.check-and-prepare.outputs.issue_body }} instruction: ${{ needs.check-and-prepare.outputs.instruction }} issue_id: ${{ github.event.client_payload.issue_id }} + rules_files: "CLAUDE.md backend/CLAUDE.md frontend/CLAUDE.md" secrets: inherit