From 846091e2374300bc1df0993fa7a8edfe327fdd5e Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 18 Mar 2026 18:00:40 +0200 Subject: [PATCH 1/8] DEV3-4782: Generalize GitHub Action to support custom prompts and comment prefixes - Add prompt_override input to replace the default code review prompt - Add step_name input to customize the agent step display name - Add comment_prefix input to isolate bot comments per action invocation - Generalize action name/description to 'Tabnine PR Agent' - Harden jq cleanup filter using env.COMMENT_PREFIX instead of interpolation - Thread comment_prefix through all references in the default prompt --- action.yml | 54 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 15 deletions(-) diff --git a/action.yml b/action.yml index f2b0795..7d9eb74 100644 --- a/action.yml +++ b/action.yml @@ -1,7 +1,9 @@ # Tabnine PR Agent for GitHub # -# This composite action runs an AI-powered code review on pull requests -# using the Tabnine CLI Agent. +# This composite action runs a Tabnine CLI Agent task on pull requests. +# By default it performs an AI-powered code review, but the prompt can be +# overridden to run any custom task (e.g., enforcing conventions, generating +# summaries, or checking documentation). # # Required Inputs: # TABNINE_KEY - Tabnine authentication credentials (JSON). Store as a repository secret. @@ -14,9 +16,12 @@ # Optional Inputs: # tabnine_host - Tabnine host URL (default: https://console.tabnine.com) # model_id - Model ID for the Tabnine CLI agent. If omitted, falls back to DEFAULT_MODEL_ID below or the system default from the admin console. +# prompt_override - Custom prompt to replace the default code review prompt. When set, the agent runs your prompt instead. +# step_name - Display name for the agent step (default: 'Tabnine Agent'). +# comment_prefix - Prefix used to identify bot comments for cleanup (default: '#### Tabnine PR Bot'). Each action invocation should use a unique prefix to avoid interfering with other invocations. -name: 'Tabnine: Code Review' -description: 'AI-powered code review using Tabnine CLI Agent' +name: 'Tabnine PR Agent' +description: 'Run a Tabnine CLI Agent task on a pull request' inputs: TABNINE_KEY: @@ -45,6 +50,18 @@ inputs: base_sha: required: true description: 'PR base commit SHA' + prompt_override: + required: false + description: 'Custom prompt to replace the default code review prompt. When provided, this prompt is passed to the Tabnine CLI agent instead of the built-in code review prompt.' + default: '' + step_name: + required: false + description: 'Display name for the agent step.' + default: 'Tabnine Agent' + comment_prefix: + required: false + description: 'Prefix used to identify bot comments for cleanup. Use a unique value per action invocation to avoid cross-cleanup.' + default: '#### Tabnine PR Bot' runs: using: 'composite' @@ -116,11 +133,12 @@ runs: shell: bash env: GH_TOKEN: ${{ inputs.github_token }} + COMMENT_PREFIX: ${{ inputs.comment_prefix }} run: | - echo "Cleaning up previous Tabnine PR Bot summary comments..." + echo "Cleaning up previous bot summary comments (prefix: $COMMENT_PREFIX)..." - # Get all issue comments on the PR - COMMENTS=$(gh api "/repos/${{ inputs.repository }}/issues/${{ inputs.pull_request_number }}/comments" --jq '.[] | select(.body | startswith("#### Tabnine PR Bot")) | .id') + # Get all issue comments on the PR matching the configured prefix + COMMENTS=$(gh api "/repos/${{ inputs.repository }}/issues/${{ inputs.pull_request_number }}/comments" --jq '[.[] | select(.body | startswith(env.COMMENT_PREFIX)) | .id] | .[]') # Delete all bot summary comments to prevent duplicates # Note: DELETE endpoint is /repos/{owner}/{repo}/issues/comments/{comment_id} (no issue number) @@ -131,15 +149,21 @@ runs: echo "Cleanup complete." - - name: Code Review + - name: ${{ inputs.step_name }} shell: bash env: TABNINE_TOKEN: ${{ inputs.TABNINE_KEY }} + PROMPT_OVERRIDE: ${{ inputs.prompt_override }} run: | if [ -z "$TABNINE_TOKEN" ]; then echo "Error: TABNINE_KEY is required" exit 1 fi + + if [ -n "$PROMPT_OVERRIDE" ]; then + ~/.local/bin/tabnine -y -p "$PROMPT_OVERRIDE" + exit $? + fi ~/.local/bin/tabnine -y -p "## 1. Persona & Context You are a collaborative Staff Engineer acting as a second pair of eyes on a teammate's PR. @@ -182,9 +206,9 @@ runs: Determine the tier before proceeding. State the tier in your summary. ### Phase B: Clean Up Previous Inline Comments - Before posting new inline comments, delete all previous Tabnine PR Bot inline review comments: + Before posting new inline comments, delete all previous bot inline review comments: 1. List all review comments: 'gh api /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments' - 2. For each comment whose body starts with '#### Tabnine PR Bot', delete it using: 'gh api --method DELETE /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments/COMMENT_ID' + 2. For each comment whose body starts with '${{ inputs.comment_prefix }}', delete it using: 'gh api --method DELETE /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments/COMMENT_ID' Note: Summary comments are cleaned up automatically before this review runs, so you only need to handle inline comments here. ### Phase C: Engineering Audit @@ -353,17 +377,17 @@ runs: **FILE-LEVEL vs LINE-LEVEL comments**: If a comment applies to the entire file rather than specific lines (e.g., a deleted file, a file that should not exist, or a concern about the file as a whole), post a FILE-LEVEL comment using 'subject_type=file' instead of a multi-line comment spanning all lines. Never post a multi-line comment that covers all or most lines of a file -- this creates an excessively large comment. Use file-level comments for file-wide feedback. Submit inline comments using: - **IMPORTANT**: All comments MUST start with '#### Tabnine PR Bot' on the first line, followed by a blank line, then your formatted comment content. + **IMPORTANT**: All comments MUST start with '${{ inputs.comment_prefix }}' on the first line, followed by a blank line, then your formatted comment content. For FILE-LEVEL comments (when the comment applies to the entire file, not specific lines): - gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments -f body='#### Tabnine PR Bot + gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments -f body='${{ inputs.comment_prefix }} YOUR_COMMENT' -f commit_id='${{ inputs.head_sha }}' -f path='FILE_PATH' -f subject_type='file' For SINGLE-LINE comments: - gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments -f body='#### Tabnine PR Bot + gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments -f body='${{ inputs.comment_prefix }} YOUR_COMMENT' -f commit_id='${{ inputs.head_sha }}' -f path='FILE_PATH' -F line=LINE_NUMBER -f side='RIGHT' For MULTI-LINE comments: - gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments -f body='#### Tabnine PR Bot + gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments -f body='${{ inputs.comment_prefix }} YOUR_COMMENT' -f commit_id='${{ inputs.head_sha }}' -f path='FILE_PATH' -F start_line=START_LINE_NUMBER -f start_side='RIGHT' -F line=END_LINE_NUMBER -f side='RIGHT' **Code Suggestions**: Use GitHub's suggestion syntax ONLY when the fix is clear, unambiguous, and replaces 10 or fewer lines: @@ -376,7 +400,7 @@ runs: After submitting inline comments (or if zero comments were posted), post the holistic summary. The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary comment using: - gh api --method POST /repos/${{ inputs.repository }}/issues/${{ inputs.pull_request_number }}/comments -f body='#### Tabnine PR Bot + gh api --method POST /repos/${{ inputs.repository }}/issues/${{ inputs.pull_request_number }}/comments -f body='${{ inputs.comment_prefix }} YOUR_SUMMARY' From 860cb75787c34522db46fefd55e81d9f56cce836 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 29 Apr 2026 13:00:21 +0300 Subject: [PATCH 2/8] Clean up inline review comments deterministically instead of via AI prompt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move inline (PR review) comment cleanup from the AI prompt (Phase B) into the deterministic shell step that already handles summary comments. This ensures reliable cleanup regardless of agent behavior. Re-letter phases B→B, C→B2/B3/B4, D→C, E→D to fill the gap. --- action.yml | 51 +++++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/action.yml b/action.yml index 7d9eb74..dc9c89e 100644 --- a/action.yml +++ b/action.yml @@ -129,7 +129,7 @@ runs: # Use a different env var name to avoid conflict with GITHUB_TOKEN echo "$GH_TOKEN_INPUT" | gh auth login --with-token - - name: Clean Up Previous Bot Summary Comments + - name: Clean Up Previous Bot Comments shell: bash env: GH_TOKEN: ${{ inputs.github_token }} @@ -147,6 +147,15 @@ runs: gh api --method DELETE "/repos/${{ inputs.repository }}/issues/comments/$COMMENT_ID" || true done + # Get all pull-request review (inline) comments matching the configured prefix + PR_COMMENTS=$(gh api "/repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments" --jq '[.[] | select(.body | startswith(env.COMMENT_PREFIX)) | .id] | .[]') + + # Delete all bot inline review comments to prevent duplicates + for COMMENT_ID in $PR_COMMENTS; do + echo "Deleting bot inline review comment: $COMMENT_ID" + gh api --method DELETE "/repos/${{ inputs.repository }}/pulls/comments/$COMMENT_ID" || true + done + echo "Cleanup complete." - name: ${{ inputs.step_name }} @@ -190,28 +199,22 @@ runs: Based on Phase A, classify this PR into a risk tier: **Tier 1 - Low Risk** (docs, config, tests, typo fixes, dependency bumps with no code changes): - - Skip Phase C2 (cross-repo analysis) and Phase C3 (infra review) entirely. - - Post only the summary comment (Phase E) with a brief confirmation. + - Skip Phase B2 (cross-repo analysis) and Phase B3 (infra review) entirely. + - Post only the summary comment (Phase D) with a brief confirmation. - Maximum inline comments: 1 (only for genuine bugs). **Tier 2 - Standard** (feature work, refactors, most bug fixes): - - Run full Phase C audit. - - Run Phase C2 only if the diff touches public APIs, shared libraries, or interface definitions. + - Run full Phase B audit. + - Run Phase B2 only if the diff touches public APIs, shared libraries, or interface definitions. - Maximum inline comments: 5. **Tier 3 - High Risk** (security changes, auth/authz, data migrations, public API changes, infrastructure/deployment changes, shared library changes): - - Run all phases including full Phase C2 and Phase C3. + - Run all phases including full Phase B2 and Phase B3. - Maximum inline comments: 8. Determine the tier before proceeding. State the tier in your summary. - ### Phase B: Clean Up Previous Inline Comments - Before posting new inline comments, delete all previous bot inline review comments: - 1. List all review comments: 'gh api /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments' - 2. For each comment whose body starts with '${{ inputs.comment_prefix }}', delete it using: 'gh api --method DELETE /repos/${{ inputs.repository }}/pulls/${{ inputs.pull_request_number }}/comments/COMMENT_ID' - Note: Summary comments are cleaned up automatically before this review runs, so you only need to handle inline comments here. - - ### Phase C: Engineering Audit + ### Phase B: Engineering Audit Evaluate the code against these pillars IN PRIORITY ORDER. Spend the most effort on the highest-priority categories. **P0 - Correctness & Logic** (most critical): @@ -275,7 +278,7 @@ runs: - Are names self-explanatory? Are complex algorithms or non-obvious business rules documented? - Does the code follow existing project conventions? - ### Phase C2: Cross-Repository Impact Analysis (Skip for Tier 1) + ### Phase B2: Cross-Repository Impact Analysis (Skip for Tier 1) Use the Tabnine MCP context engine tools to analyze cross-repository impact of this PR: 1. **List repositories**: Call 'remote_repositories_list' to discover the organization's repository ecosystem. 2. **Find related services**: Call 'remote_search_assets' with queries derived from the changed files to find SERVICE_SUMMARY and OPENAPI_SPEC assets related to the code being modified. @@ -293,14 +296,14 @@ runs: - Services or repositories as nodes - Call or dependency relationships as directed edges - Use this diagram to reason about blast radius, layering violations, or unintended coupling. - 8. **Compile findings** for inclusion in the Phase E summary comment: + 8. **Compile findings** for inclusion in the Phase D summary comment: - Architecture violations or new inter-service dependencies introduced by this PR - Other repositories or services that consume the changed code (with file and line references where possible) - High-level architecture insight derived from SERVICE_SUMMARY / OPENAPI_SPEC assets - ASCII architecture diagram (only if it adds clarity; omit if trivial) - If no cross-repo impact is found, state 'No cross-repository impact detected' - ### Phase C3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) + ### Phase B3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) If the PR modifies infrastructure or configuration files, apply these checks: **Dockerfiles**: Are base images pinned (not 'latest')? Running as non-root? Secrets not in build args? **CI/CD Pipelines**: Are dependencies version-pinned? Could this break the pipeline for other branches? Secrets via secure stores? @@ -308,7 +311,7 @@ runs: **Terraform/IaC**: Any resource destruction? Blast radius limited? New resources tagged consistently? **Config/Env Vars**: New vars have safe defaults? Sensitive values from secret managers? App fails fast if required config missing? - ### Phase C4: Coaching Guidelines Compliance + ### Phase B4: Coaching Guidelines Compliance Use the Tabnine MCP 'get_guidelines' tool to retrieve the organization's coaching guidelines and validate the changed code against them: 1. **Identify languages**: Determine which programming languages are present in the diff (e.g., python, javascript, typescript, java, php, go, cpp, csharp, kotlin). 2. **Fetch guidelines**: Call 'get_guidelines' with the 'language' parameter for each language detected in the diff to retrieve applicable coaching guidelines. If changed files span multiple languages, call it once per language. @@ -317,7 +320,7 @@ runs: - Post an inline comment referencing the guideline ID and description. Coaching guideline violations are exempt from the tier comment budget -- every violation must be reported. - Use the guideline's severity to map to the inline comment severity: Critical -> [Critical], Error -> [Warning], Warning -> [Suggestion], Info -> [Suggestion]. - Include the guideline's recommended fix or best practice in the 'Suggested fix' section of the comment. - 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase E summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' + 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase D summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' ## 4. Comment Value Threshold (CRITICAL FILTER) @@ -332,7 +335,7 @@ runs: - Introduces a deployment risk (non-backward-compatible migration, missing feature flag for risky change) - Changes CI/CD configuration in a way that could break the build for other contributors - Violates critical project patterns (e.g., error handling, path handling) - - Violates any organization coaching guideline, regardless of severity (from Phase C4) + - Violates any organization coaching guideline, regardless of severity (from Phase B4) - Makes the code significantly harder to maintain or debug **DO NOT comment on:** @@ -355,9 +358,9 @@ runs: **Golden Rule**: If removing your comment would NOT increase the risk of bugs, security issues, or maintenance problems, DO NOT POST IT. - ### Phase D: Inline Comments + ### Phase C: Inline Comments - For each potential issue from Phase C: + For each potential issue from Phase B: 1. Apply the Comment Value Threshold filter above 2. Enforce the tier comment budget (Tier 1: max 1, Tier 2: max 5, Tier 3: max 8). If you have more findings than the budget, keep only the highest-severity ones. 3. Verify the file exists in the diff and the line number is within changed lines @@ -396,7 +399,7 @@ runs: \`\`\` For larger changes or context-dependent fixes, provide guidance as a regular comment without the suggestion block. - ### Phase E: Final Summary + ### Phase D: Final Summary After submitting inline comments (or if zero comments were posted), post the holistic summary. The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary comment using: @@ -409,8 +412,8 @@ runs: - **What This PR Does** (1-2 sentences): Demonstrate you understood the author's intent. This builds trust. - **Assessment** (1-3 sentences): Overall verdict. Is this good to merge? Any blockers? - **Key Findings** (only if findings exist): Group by severity -- [Critical] first, then [Warning], then [Suggestion]. List max 3-5 findings; if more, prioritize by severity. - - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase C2, or 'No cross-repository impact detected.' - - **Coaching Guidelines**: Findings from Phase C4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' + - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase B2, or 'No cross-repository impact detected.' + - **Coaching Guidelines**: Findings from Phase B4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' - **Deployment & Operations** (only if relevant): Migration safety, feature flag requirements, observability gaps, infrastructure concerns. Omit entirely if no operational concerns. - **What Looks Good** (1-3 bullet points): Specific things the author did well (good test coverage, clean error handling, thoughtful API design). Always find something positive. From 00180da2e768419137abaacbc06fe4bd6a6ba5d5 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 29 Apr 2026 13:08:12 +0300 Subject: [PATCH 3/8] Apply deterministic inline comment cleanup to GitLab and Bitbucket workflows Same pattern as the GitHub action: move inline comment cleanup from the AI prompt into the deterministic shell step. Re-letter phases accordingly. GitLab: add Discussions API cleanup for inline notes. Bitbucket: existing cleanup already covers both comment types. --- Bitbucket/bitbucket-pipelines.yml | 40 +++++++++++-------------- GitLab/.gitlab-ci.yml | 50 +++++++++++++++++-------------- 2 files changed, 44 insertions(+), 46 deletions(-) diff --git a/Bitbucket/bitbucket-pipelines.yml b/Bitbucket/bitbucket-pipelines.yml index b15970b..acc9cc5 100644 --- a/Bitbucket/bitbucket-pipelines.yml +++ b/Bitbucket/bitbucket-pipelines.yml @@ -139,28 +139,22 @@ pipelines: Based on Phase A, classify this PR into a risk tier: **Tier 1 - Low Risk** (docs, config, tests, typo fixes, dependency bumps with no code changes): - - Skip Phase C2 (cross-repo analysis) and Phase C3 (infra review) entirely. - - Post only the summary comment (Phase E) with a brief confirmation. + - Skip Phase B2 (cross-repo analysis) and Phase B3 (infra review) entirely. + - Post only the summary comment (Phase D) with a brief confirmation. - Maximum inline comments: 1 (only for genuine bugs). **Tier 2 - Standard** (feature work, refactors, most bug fixes): - - Run full Phase C audit. - - Run Phase C2 only if the diff touches public APIs, shared libraries, or interface definitions. + - Run full Phase B audit. + - Run Phase B2 only if the diff touches public APIs, shared libraries, or interface definitions. - Maximum inline comments: 5. **Tier 3 - High Risk** (security changes, auth/authz, data migrations, public API changes, infrastructure/deployment changes, shared library changes): - - Run all phases including full Phase C2 and Phase C3. + - Run all phases including full Phase B2 and Phase B3. - Maximum inline comments: 8. Determine the tier before proceeding. State the tier in your summary. - ### Phase B: Clean Up Previous Inline Comments - Before posting new inline comments, delete all previous Tabnine PR Bot inline review comments: - 1. List all PR comments: curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments?pagelen=100' - 2. For each comment whose content.raw starts with '#### Tabnine PR Bot' and has an 'inline' property (indicating it's an inline comment), delete it using: curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request DELETE '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments/COMMENT_ID' - Note: Summary comments are cleaned up automatically before this review runs, so you only need to handle inline comments here. - - ### Phase C: Engineering Audit + ### Phase B: Engineering Audit Evaluate the code against these pillars IN PRIORITY ORDER. Spend the most effort on the highest-priority categories. **P0 - Correctness & Logic** (most critical): @@ -224,7 +218,7 @@ pipelines: - Are names self-explanatory? Are complex algorithms or non-obvious business rules documented? - Does the code follow existing project conventions? - ### Phase C2: Cross-Repository Impact Analysis (Skip for Tier 1) + ### Phase B2: Cross-Repository Impact Analysis (Skip for Tier 1) Use the Tabnine MCP context engine tools to analyze cross-repository impact of this PR: 1. **List repositories**: Call 'remote_repositories_list' to discover the organization's repository ecosystem. 2. **Find related services**: Call 'remote_search_assets' with queries derived from the changed files to find SERVICE_SUMMARY and OPENAPI_SPEC assets related to the code being modified. @@ -242,14 +236,14 @@ pipelines: - Services or repositories as nodes - Call or dependency relationships as directed edges - Use this diagram to reason about blast radius, layering violations, or unintended coupling. - 8. **Compile findings** for inclusion in the Phase E summary comment: + 8. **Compile findings** for inclusion in the Phase D summary comment: - Architecture violations or new inter-service dependencies introduced by this PR - Other repositories or services that consume the changed code (with file and line references where possible) - High-level architecture insight derived from SERVICE_SUMMARY / OPENAPI_SPEC assets - ASCII architecture diagram (only if it adds clarity; omit if trivial) - If no cross-repo impact is found, state 'No cross-repository impact detected' - ### Phase C3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) + ### Phase B3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) If the PR modifies infrastructure or configuration files, apply these checks: **Dockerfiles**: Are base images pinned (not 'latest')? Running as non-root? Secrets not in build args? **CI/CD Pipelines**: Are dependencies version-pinned? Could this break the pipeline for other branches? Secrets via secure stores? @@ -257,7 +251,7 @@ pipelines: **Terraform/IaC**: Any resource destruction? Blast radius limited? New resources tagged consistently? **Config/Env Vars**: New vars have safe defaults? Sensitive values from secret managers? App fails fast if required config missing? - ### Phase C4: Coaching Guidelines Compliance + ### Phase B4: Coaching Guidelines Compliance Use the Tabnine MCP 'get_guidelines' tool to retrieve the organization's coaching guidelines and validate the changed code against them: 1. **Identify languages**: Determine which programming languages are present in the diff (e.g., python, javascript, typescript, java, php, go, cpp, csharp, kotlin). 2. **Fetch guidelines**: Call 'get_guidelines' with the 'language' parameter for each language detected in the diff to retrieve applicable coaching guidelines. If changed files span multiple languages, call it once per language. @@ -266,7 +260,7 @@ pipelines: - Post an inline comment referencing the guideline ID and description. Coaching guideline violations are exempt from the tier comment budget -- every violation must be reported. - Use the guideline's severity to map to the inline comment severity: Critical -> [Critical], Error -> [Warning], Warning -> [Suggestion], Info -> [Suggestion]. - Include the guideline's recommended fix or best practice in the 'Suggested fix' section of the comment. - 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase E summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' + 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase D summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' ## 4. Comment Value Threshold (CRITICAL FILTER) @@ -281,7 +275,7 @@ pipelines: - Introduces a deployment risk (non-backward-compatible migration, missing feature flag for risky change) - Changes CI/CD configuration in a way that could break the build for other contributors - Violates critical project patterns (e.g., error handling, path handling) - - Violates any organization coaching guideline, regardless of severity (from Phase C4) + - Violates any organization coaching guideline, regardless of severity (from Phase B4) - Makes the code significantly harder to maintain or debug **DO NOT comment on:** @@ -304,9 +298,9 @@ pipelines: **Golden Rule**: If removing your comment would NOT increase the risk of bugs, security issues, or maintenance problems, DO NOT POST IT. - ### Phase D: Inline Comments + ### Phase C: Inline Comments - For each potential issue from Phase C: + For each potential issue from Phase B: 1. Apply the Comment Value Threshold filter above 2. Enforce the tier comment budget (Tier 1: max 1, Tier 2: max 5, Tier 3: max 8). If you have more findings than the budget, keep only the highest-severity ones. 3. Verify the file exists in the diff and the line number is within changed lines @@ -328,7 +322,7 @@ pipelines: For inline comments on specific lines: curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request POST --header 'Content-Type: application/json' --data '{"content": {"raw": "#### Tabnine PR Bot\n\nYOUR_COMMENT"}, "inline": {"path": "FILE_PATH", "to": LINE_NUMBER}}' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments' - ### Phase E: Final Summary + ### Phase D: Final Summary After submitting inline comments (or if zero comments were posted), post the holistic summary. The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary comment using the Bitbucket PR Comments API: @@ -339,8 +333,8 @@ pipelines: - **What This PR Does** (1-2 sentences): Demonstrate you understood the author's intent. This builds trust. - **Assessment** (1-3 sentences): Overall verdict. Is this good to merge? Any blockers? - **Key Findings** (only if findings exist): Group by severity -- [Critical] first, then [Warning], then [Suggestion]. List max 3-5 findings; if more, prioritize by severity. - - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase C2, or 'No cross-repository impact detected.' - - **Coaching Guidelines**: Findings from Phase C4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' + - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase B2, or 'No cross-repository impact detected.' + - **Coaching Guidelines**: Findings from Phase B4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' - **Deployment & Operations** (only if relevant): Migration safety, feature flag requirements, observability gaps, infrastructure concerns. Omit entirely if no operational concerns. - **What Looks Good** (1-3 bullet points): Specific things the author did well (good test coverage, clean error handling, thoughtful API design). Always find something positive. diff --git a/GitLab/.gitlab-ci.yml b/GitLab/.gitlab-ci.yml index e12e59f..9dc0146 100644 --- a/GitLab/.gitlab-ci.yml +++ b/GitLab/.gitlab-ci.yml @@ -98,6 +98,16 @@ tabnine-code-review: curl -s --request DELETE --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ "$GITLAB_API_URL/projects/$PROJECT_ID/merge_requests/$MR_IID/notes/$NOTE_ID" || true done + + # Clean up previous bot inline comments (discussion notes) + echo "Cleaning up previous Tabnine PR Bot inline comments..." + DISCUSSIONS=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ + "$GITLAB_API_URL/projects/$PROJECT_ID/merge_requests/$MR_IID/discussions") + echo "$DISCUSSIONS" | jq -r '.[] | {did: .id, notes: [.notes[] | select(.body | startswith("#### Tabnine PR Bot")) | .id]} | select(.notes | length > 0) | .did as $did | .notes[] | "\($did) \(.)"' | while read DISCUSSION_ID NOTE_ID; do + echo "Deleting bot inline comment: discussion=$DISCUSSION_ID note=$NOTE_ID" + curl -s --request DELETE --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ + "$GITLAB_API_URL/projects/$PROJECT_ID/merge_requests/$MR_IID/discussions/$DISCUSSION_ID/notes/$NOTE_ID" || true + done echo "Cleanup complete." - | @@ -138,28 +148,22 @@ tabnine-code-review: Based on Phase A, classify this MR into a risk tier: **Tier 1 - Low Risk** (docs, config, tests, typo fixes, dependency bumps with no code changes): - - Skip Phase C2 (cross-repo analysis) and Phase C3 (infra review) entirely. - - Post only the summary comment (Phase E) with a brief confirmation. + - Skip Phase B2 (cross-repo analysis) and Phase B3 (infra review) entirely. + - Post only the summary comment (Phase D) with a brief confirmation. - Maximum inline comments: 1 (only for genuine bugs). **Tier 2 - Standard** (feature work, refactors, most bug fixes): - - Run full Phase C audit. - - Run Phase C2 only if the diff touches public APIs, shared libraries, or interface definitions. + - Run full Phase B audit. + - Run Phase B2 only if the diff touches public APIs, shared libraries, or interface definitions. - Maximum inline comments: 5. **Tier 3 - High Risk** (security changes, auth/authz, data migrations, public API changes, infrastructure/deployment changes, shared library changes): - - Run all phases including full Phase C2 and Phase C3. + - Run all phases including full Phase B2 and Phase B3. - Maximum inline comments: 8. Determine the tier before proceeding. State the tier in your summary. - ### Phase B: Clean Up Previous Inline Comments - Before posting new inline comments, delete all previous Tabnine PR Bot inline review comments: - 1. List all MR discussions: curl -s --header 'PRIVATE-TOKEN: \$GITLAB_API_TOKEN' '\$GITLAB_API_URL/projects/\$PROJECT_ID/merge_requests/\$MR_IID/discussions' - 2. For each discussion note whose body starts with '#### Tabnine PR Bot', delete it using: curl -s --request DELETE --header 'PRIVATE-TOKEN: \$GITLAB_API_TOKEN' '\$GITLAB_API_URL/projects/\$PROJECT_ID/merge_requests/\$MR_IID/discussions/DISCUSSION_ID/notes/NOTE_ID' - Note: Summary notes are cleaned up automatically before this review runs, so you only need to handle inline comments here. - - ### Phase C: Engineering Audit + ### Phase B: Engineering Audit Evaluate the code against these pillars IN PRIORITY ORDER. Spend the most effort on the highest-priority categories. **P0 - Correctness & Logic** (most critical): @@ -223,7 +227,7 @@ tabnine-code-review: - Are names self-explanatory? Are complex algorithms or non-obvious business rules documented? - Does the code follow existing project conventions? - ### Phase C2: Cross-Repository Impact Analysis (Skip for Tier 1) + ### Phase B2: Cross-Repository Impact Analysis (Skip for Tier 1) Use the Tabnine MCP context engine tools to analyze cross-repository impact of this MR: 1. **List repositories**: Call 'remote_repositories_list' to discover the organization's repository ecosystem. 2. **Find related services**: Call 'remote_search_assets' with queries derived from the changed files to find SERVICE_SUMMARY and OPENAPI_SPEC assets related to the code being modified. @@ -241,14 +245,14 @@ tabnine-code-review: - Services or repositories as nodes - Call or dependency relationships as directed edges - Use this diagram to reason about blast radius, layering violations, or unintended coupling. - 8. **Compile findings** for inclusion in the Phase E summary comment: + 8. **Compile findings** for inclusion in the Phase D summary comment: - Architecture violations or new inter-service dependencies introduced by this MR - Other repositories or services that consume the changed code (with file and line references where possible) - High-level architecture insight derived from SERVICE_SUMMARY / OPENAPI_SPEC assets - ASCII architecture diagram (only if it adds clarity; omit if trivial) - If no cross-repo impact is found, state 'No cross-repository impact detected' - ### Phase C3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) + ### Phase B3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) If the MR modifies infrastructure or configuration files, apply these checks: **Dockerfiles**: Are base images pinned (not 'latest')? Running as non-root? Secrets not in build args? **CI/CD Pipelines**: Are dependencies version-pinned? Could this break the pipeline for other branches? Secrets via secure stores? @@ -256,7 +260,7 @@ tabnine-code-review: **Terraform/IaC**: Any resource destruction? Blast radius limited? New resources tagged consistently? **Config/Env Vars**: New vars have safe defaults? Sensitive values from secret managers? App fails fast if required config missing? - ### Phase C4: Coaching Guidelines Compliance + ### Phase B4: Coaching Guidelines Compliance Use the Tabnine MCP 'get_guidelines' tool to retrieve the organization's coaching guidelines and validate the changed code against them: 1. **Identify languages**: Determine which programming languages are present in the diff (e.g., python, javascript, typescript, java, php, go, cpp, csharp, kotlin). 2. **Fetch guidelines**: Call 'get_guidelines' with the 'language' parameter for each language detected in the diff to retrieve applicable coaching guidelines. If changed files span multiple languages, call it once per language. @@ -265,7 +269,7 @@ tabnine-code-review: - Post an inline comment referencing the guideline ID and description. Coaching guideline violations are exempt from the tier comment budget -- every violation must be reported. - Use the guideline's severity to map to the inline comment severity: Critical -> [Critical], Error -> [Warning], Warning -> [Suggestion], Info -> [Suggestion]. - Include the guideline's recommended fix or best practice in the 'Suggested fix' section of the comment. - 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase E summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' + 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase D summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' ## 4. Comment Value Threshold (CRITICAL FILTER) @@ -280,7 +284,7 @@ tabnine-code-review: - Introduces a deployment risk (non-backward-compatible migration, missing feature flag for risky change) - Changes CI/CD configuration in a way that could break the build for other contributors - Violates critical project patterns (e.g., error handling, path handling) - - Violates any organization coaching guideline, regardless of severity (from Phase C4) + - Violates any organization coaching guideline, regardless of severity (from Phase B4) - Makes the code significantly harder to maintain or debug **DO NOT comment on:** @@ -303,9 +307,9 @@ tabnine-code-review: **Golden Rule**: If removing your comment would NOT increase the risk of bugs, security issues, or maintenance problems, DO NOT POST IT. - ### Phase D: Inline Comments + ### Phase C: Inline Comments - For each potential issue from Phase C: + For each potential issue from Phase B: 1. Apply the Comment Value Threshold filter above 2. Enforce the tier comment budget (Tier 1: max 1, Tier 2: max 5, Tier 3: max 8). If you have more findings than the budget, keep only the highest-severity ones. 3. Verify the file exists in the diff and the line number is within changed lines @@ -338,7 +342,7 @@ tabnine-code-review: \`\`\` For larger changes or context-dependent fixes, provide guidance as a regular comment without the suggestion block. - ### Phase E: Final Summary + ### Phase D: Final Summary After submitting inline comments (or if zero comments were posted), post the holistic summary. The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary note using the GitLab Notes API: @@ -351,8 +355,8 @@ tabnine-code-review: - **What This MR Does** (1-2 sentences): Demonstrate you understood the author's intent. This builds trust. - **Assessment** (1-3 sentences): Overall verdict. Is this good to merge? Any blockers? - **Key Findings** (only if findings exist): Group by severity -- [Critical] first, then [Warning], then [Suggestion]. List max 3-5 findings; if more, prioritize by severity. - - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase C2, or 'No cross-repository impact detected.' - - **Coaching Guidelines**: Findings from Phase C4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' + - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase B2, or 'No cross-repository impact detected.' + - **Coaching Guidelines**: Findings from Phase B4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' - **Deployment & Operations** (only if relevant): Migration safety, feature flag requirements, observability gaps, infrastructure concerns. Omit entirely if no operational concerns. - **What Looks Good** (1-3 bullet points): Specific things the author did well (good test coverage, clean error handling, thoughtful API design). Always find something positive. From 0c2ed5ebe2508c809173e4cabb95abdb93830547 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 29 Apr 2026 14:06:06 +0300 Subject: [PATCH 4/8] Apply deterministic inline cleanup to GitHub standalone workflow Remove Phase B from prompt, fix DELETE endpoint for review comments (was /issues/comments, now /pulls/comments), re-letter phases. --- GitHub/tabnine-review.yml | 50 +++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/GitHub/tabnine-review.yml b/GitHub/tabnine-review.yml index 432fdf1..0f2a6e2 100644 --- a/GitHub/tabnine-review.yml +++ b/GitHub/tabnine-review.yml @@ -105,12 +105,12 @@ jobs: # Use a different env var name to avoid conflict with GITHUB_TOKEN echo "$GH_TOKEN_INPUT" | gh auth login --with-token - - name: Clean Up Previous Bot Summary Comments + - name: Clean Up Previous Bot Comments shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - echo "Cleaning up previous Tabnine PR Bot summary comments..." + echo "Cleaning up previous Tabnine PR Bot comments..." # Get all issue comments on the PR COMMENTS=$(gh api "/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" --jq '.[] | select(.body | startswith("#### Tabnine PR Bot")) | .id') @@ -124,10 +124,10 @@ jobs: # Get all pull-request comments on the PR PR_COMMENTS=$(gh api "/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments" --jq '.[] | select(.body | startswith("#### Tabnine PR Bot")) | .id') - # Delete all bot pull request review comments to prevent duplicates + # Delete all bot inline review comments to prevent duplicates for COMMENT_ID in $PR_COMMENTS; do - echo "Deleting bot summary comment: $COMMENT_ID" - gh api --method DELETE "/repos/${{ github.repository }}/issues/comments/$COMMENT_ID" || true + echo "Deleting bot inline review comment: $COMMENT_ID" + gh api --method DELETE "/repos/${{ github.repository }}/pulls/comments/$COMMENT_ID" || true done echo "Cleanup complete." @@ -168,28 +168,22 @@ jobs: Based on Phase A, classify this PR into a risk tier: **Tier 1 - Low Risk** (docs, config, tests, typo fixes, dependency bumps with no code changes): - - Skip Phase C2 (cross-repo analysis) and Phase C3 (infra review) entirely. - - Post only the summary comment (Phase E) with a brief confirmation. + - Skip Phase B2 (cross-repo analysis) and Phase B3 (infra review) entirely. + - Post only the summary comment (Phase D) with a brief confirmation. - Maximum inline comments: 1 (only for genuine bugs). **Tier 2 - Standard** (feature work, refactors, most bug fixes): - - Run full Phase C audit. - - Run Phase C2 only if the diff touches public APIs, shared libraries, or interface definitions. + - Run full Phase B audit. + - Run Phase B2 only if the diff touches public APIs, shared libraries, or interface definitions. - Maximum inline comments: 5. **Tier 3 - High Risk** (security changes, auth/authz, data migrations, public API changes, infrastructure/deployment changes, shared library changes): - - Run all phases including full Phase C2 and Phase C3. + - Run all phases including full Phase B2 and Phase B3. - Maximum inline comments: 8. Determine the tier before proceeding. State the tier in your summary. - ### Phase B: Clean Up Previous Inline Comments - Before posting new inline comments, delete all previous Tabnine PR Bot inline review comments: - 1. List all review comments: 'gh api /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments' - 2. For each comment whose body starts with '#### Tabnine PR Bot', delete it using: 'gh api --method DELETE /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments/COMMENT_ID' - Note: Summary comments are cleaned up automatically before this review runs, so you only need to handle inline comments here. - - ### Phase C: Engineering Audit + ### Phase B: Engineering Audit Evaluate the code against these pillars IN PRIORITY ORDER. Spend the most effort on the highest-priority categories. **P0 - Correctness & Logic** (most critical): @@ -253,7 +247,7 @@ jobs: - Are names self-explanatory? Are complex algorithms or non-obvious business rules documented? - Does the code follow existing project conventions? - ### Phase C2: Cross-Repository Impact Analysis (Skip for Tier 1) + ### Phase B2: Cross-Repository Impact Analysis (Skip for Tier 1) Use the Tabnine MCP context engine tools to analyze cross-repository impact of this PR: 1. **List repositories**: Call 'remote_repositories_list' to discover the organization's repository ecosystem. 2. **Find related services**: Call 'remote_search_assets' with queries derived from the changed files to find SERVICE_SUMMARY and OPENAPI_SPEC assets related to the code being modified. @@ -271,14 +265,14 @@ jobs: - Services or repositories as nodes - Call or dependency relationships as directed edges - Use this diagram to reason about blast radius, layering violations, or unintended coupling. - 8. **Compile findings** for inclusion in the Phase E summary comment: + 8. **Compile findings** for inclusion in the Phase D summary comment: - Architecture violations or new inter-service dependencies introduced by this PR - Other repositories or services that consume the changed code (with file and line references where possible) - High-level architecture insight derived from SERVICE_SUMMARY / OPENAPI_SPEC assets - ASCII architecture diagram (only if it adds clarity; omit if trivial) - If no cross-repo impact is found, state 'No cross-repository impact detected' - ### Phase C3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) + ### Phase B3: Infrastructure & Configuration Review (Tier 3 only, skip if no infra files in diff) If the PR modifies infrastructure or configuration files, apply these checks: **Dockerfiles**: Are base images pinned (not 'latest')? Running as non-root? Secrets not in build args? **CI/CD Pipelines**: Are dependencies version-pinned? Could this break the pipeline for other branches? Secrets via secure stores? @@ -286,7 +280,7 @@ jobs: **Terraform/IaC**: Any resource destruction? Blast radius limited? New resources tagged consistently? **Config/Env Vars**: New vars have safe defaults? Sensitive values from secret managers? App fails fast if required config missing? - ### Phase C4: Coaching Guidelines Compliance + ### Phase B4: Coaching Guidelines Compliance Use the Tabnine MCP 'get_guidelines' tool to retrieve the organization's coaching guidelines and validate the changed code against them: 1. **Identify languages**: Determine which programming languages are present in the diff (e.g., python, javascript, typescript, java, php, go, cpp, csharp, kotlin). 2. **Fetch guidelines**: Call 'get_guidelines' with the 'language' parameter for each language detected in the diff to retrieve applicable coaching guidelines. If changed files span multiple languages, call it once per language. @@ -295,7 +289,7 @@ jobs: - Post an inline comment referencing the guideline ID and description. Coaching guideline violations are exempt from the tier comment budget -- every violation must be reported. - Use the guideline's severity to map to the inline comment severity: Critical -> [Critical], Error -> [Warning], Warning -> [Suggestion], Info -> [Suggestion]. - Include the guideline's recommended fix or best practice in the 'Suggested fix' section of the comment. - 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase E summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' + 5. **Include in summary**: Add a 'Coaching Guidelines' section to the Phase D summary if any violations were found. List violated guideline IDs grouped by severity. If no violations were found, state 'All changed code complies with coaching guidelines.' ## 4. Comment Value Threshold (CRITICAL FILTER) @@ -310,7 +304,7 @@ jobs: - Introduces a deployment risk (non-backward-compatible migration, missing feature flag for risky change) - Changes CI/CD configuration in a way that could break the build for other contributors - Violates critical project patterns (e.g., error handling, path handling) - - Violates any organization coaching guideline, regardless of severity (from Phase C4) + - Violates any organization coaching guideline, regardless of severity (from Phase B4) - Makes the code significantly harder to maintain or debug **DO NOT comment on:** @@ -333,9 +327,9 @@ jobs: **Golden Rule**: If removing your comment would NOT increase the risk of bugs, security issues, or maintenance problems, DO NOT POST IT. - ### Phase D: Inline Comments + ### Phase C: Inline Comments - For each potential issue from Phase C: + For each potential issue from Phase B: 1. Apply the Comment Value Threshold filter above 2. Enforce the tier comment budget (Tier 1: max 1, Tier 2: max 5, Tier 3: max 8). If you have more findings than the budget, keep only the highest-severity ones. 3. Verify the file exists in the diff and the line number is within changed lines @@ -368,7 +362,7 @@ jobs: ``` For larger changes or context-dependent fixes, provide guidance as a regular comment without the suggestion block. - ### Phase E: Final Summary + ### Phase D: Final Summary After submitting inline comments (or if zero comments were posted), post the holistic summary. The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary comment using: @@ -381,8 +375,8 @@ jobs: - **What This PR Does** (1-2 sentences): Demonstrate you understood the author's intent. This builds trust. - **Assessment** (1-3 sentences): Overall verdict. Is this good to merge? Any blockers? - **Key Findings** (only if findings exist): Group by severity -- [Critical] first, then [Warning], then [Suggestion]. List max 3-5 findings; if more, prioritize by severity. - - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase C2, or 'No cross-repository impact detected.' - - **Coaching Guidelines**: Findings from Phase C4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' + - **Cross-Repository Impact** (Tier 2-3 only): Findings from Phase B2, or 'No cross-repository impact detected.' + - **Coaching Guidelines**: Findings from Phase B4 -- list violated guideline IDs grouped by severity, or 'All changed code complies with coaching guidelines.' - **Deployment & Operations** (only if relevant): Migration safety, feature flag requirements, observability gaps, infrastructure concerns. Omit entirely if no operational concerns. - **What Looks Good** (1-3 bullet points): Specific things the author did well (good test coverage, clean error handling, thoughtful API design). Always find something positive. From b0aafb43b5b87393590d81fc9790d222e615af6d Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 29 Apr 2026 14:47:04 +0300 Subject: [PATCH 5/8] Add configurable COMMENT_PREFIX to standalone workflows for parity with action.yml --- Bitbucket/bitbucket-pipelines.yml | 12 +++++++----- GitHub/tabnine-review.yml | 17 ++++++++++------- GitLab/.gitlab-ci.yml | 18 ++++++++++-------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Bitbucket/bitbucket-pipelines.yml b/Bitbucket/bitbucket-pipelines.yml index acc9cc5..902e6c0 100644 --- a/Bitbucket/bitbucket-pipelines.yml +++ b/Bitbucket/bitbucket-pipelines.yml @@ -11,6 +11,7 @@ # TABNINE_HOST - Tabnine host URL (default: https://console.tabnine.com) # TABNINE_MODEL_ID - Model ID for the Tabnine CLI agent. If empty, falls back to DEFAULT_MODEL_ID below or the system default from the admin console. # TABNINE_CLEANUP - Set to "true" to delete settings.json after each run (default: "false"). Recommended for self-hosted runners. +# TABNINE_COMMENT_PREFIX - Prefix used to identify bot comments for cleanup (default: '#### Tabnine PR Bot'). image: node:20 @@ -30,6 +31,7 @@ pipelines: - export BB_PR_ID="${BITBUCKET_PR_ID}" - export BB_COMMIT="${BITBUCKET_COMMIT}" - export BB_PR_DEST_BRANCH="${BITBUCKET_PR_DESTINATION_BRANCH}" + - export COMMENT_PREFIX="${TABNINE_COMMENT_PREFIX:-#### Tabnine PR Bot}" # Input validation - | @@ -90,8 +92,8 @@ pipelines: # Clean up previous bot summary comments - | - echo "Cleaning up previous Tabnine PR Bot comments..." - COMMENTS=$(curl -s --header "Authorization: Bearer $BB_API_TOKEN" "$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments?pagelen=100" | jq -r '.values[] | select(.content.raw | startswith("#### Tabnine PR Bot")) | .id') + echo "Cleaning up previous bot comments (prefix: $COMMENT_PREFIX)..." + COMMENTS=$(curl -s --header "Authorization: Bearer $BB_API_TOKEN" "$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments?pagelen=100" | jq -r ".values[] | select(.content.raw | startswith(\"$COMMENT_PREFIX\")) | .id") for COMMENT_ID in $COMMENTS; do echo "Deleting bot comment: $COMMENT_ID" @@ -318,15 +320,15 @@ pipelines: - **[Suggestion]** -- Improvements to maintainability or clarity. Author's discretion. Submit inline comments using the Bitbucket PR Comments API: - **IMPORTANT**: All comments MUST start with '#### Tabnine PR Bot' on the first line, followed by a blank line, then your formatted comment content. + **IMPORTANT**: All comments MUST start with '$COMMENT_PREFIX' on the first line, followed by a blank line, then your formatted comment content. For inline comments on specific lines: - curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request POST --header 'Content-Type: application/json' --data '{"content": {"raw": "#### Tabnine PR Bot\n\nYOUR_COMMENT"}, "inline": {"path": "FILE_PATH", "to": LINE_NUMBER}}' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments' + curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request POST --header 'Content-Type: application/json' --data '{"content": {"raw": "$COMMENT_PREFIX\n\nYOUR_COMMENT"}, "inline": {"path": "FILE_PATH", "to": LINE_NUMBER}}' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments' ### Phase D: Final Summary After submitting inline comments (or if zero comments were posted), post the holistic summary. The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary comment using the Bitbucket PR Comments API: - curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request POST --header 'Content-Type: application/json' --data '{"content": {"raw": "#### Tabnine PR Bot\n\nYOUR_SUMMARY"}}' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments' + curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request POST --header 'Content-Type: application/json' --data '{"content": {"raw": "$COMMENT_PREFIX\n\nYOUR_SUMMARY"}}' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments' Structure your summary as follows: - **Line 1 - Risk Tier**: State the tier: [Low Risk], [Standard], or [HIGH RISK] diff --git a/GitHub/tabnine-review.yml b/GitHub/tabnine-review.yml index 0f2a6e2..4d27b7c 100644 --- a/GitHub/tabnine-review.yml +++ b/GitHub/tabnine-review.yml @@ -12,6 +12,7 @@ # TABNINE_HOST - Tabnine host URL (default: https://console.tabnine.com). Set this for self-hosted / EMT installations. # TABNINE_MODEL_ID - Model ID for the Tabnine CLI agent. If empty, falls back to DEFAULT_MODEL_ID below or the system default from the admin console. # TABNINE_CLEANUP - Set to "true" to delete settings.json after each run (default: "false"). Recommended for self-hosted runners. +# TABNINE_COMMENT_PREFIX - Prefix used to identify bot comments for cleanup (default: '#### Tabnine PR Bot'). name: "Tabnine PR Review Agent" @@ -109,11 +110,12 @@ jobs: shell: bash env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMMENT_PREFIX: ${{ vars.TABNINE_COMMENT_PREFIX || '#### Tabnine PR Bot' }} run: | - echo "Cleaning up previous Tabnine PR Bot comments..." + echo "Cleaning up previous bot comments (prefix: $COMMENT_PREFIX)..." # Get all issue comments on the PR - COMMENTS=$(gh api "/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" --jq '.[] | select(.body | startswith("#### Tabnine PR Bot")) | .id') + COMMENTS=$(gh api "/repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments" --jq '[.[] | select(.body | startswith(env.COMMENT_PREFIX)) | .id] | .[]') # Delete all bot summary comments to prevent duplicates for COMMENT_ID in $COMMENTS; do @@ -122,7 +124,7 @@ jobs: done # Get all pull-request comments on the PR - PR_COMMENTS=$(gh api "/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments" --jq '.[] | select(.body | startswith("#### Tabnine PR Bot")) | .id') + PR_COMMENTS=$(gh api "/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments" --jq '[.[] | select(.body | startswith(env.COMMENT_PREFIX)) | .id] | .[]') # Delete all bot inline review comments to prevent duplicates for COMMENT_ID in $PR_COMMENTS; do @@ -137,6 +139,7 @@ jobs: continue-on-error: true env: TABNINE_TOKEN: ${{ secrets.TABNINE_KEY }} + COMMENT_PREFIX: ${{ vars.TABNINE_COMMENT_PREFIX || '#### Tabnine PR Bot' }} run: | if [ -z "$TABNINE_TOKEN" ]; then echo "Error: TABNINE_KEY is required" @@ -347,13 +350,13 @@ jobs: - **[Suggestion]** -- Improvements to maintainability or clarity. Author's discretion. Submit inline comments using: - **IMPORTANT**: All comments MUST start with '#### Tabnine PR Bot' on the first line, followed by a blank line, then your formatted comment content. + **IMPORTANT**: All comments MUST start with '$COMMENT_PREFIX' on the first line, followed by a blank line, then your formatted comment content. For SINGLE-LINE comments: - gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments -f body='#### Tabnine PR Bot + gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments -f body='$COMMENT_PREFIX YOUR_COMMENT' -f commit_id='${{ github.event.pull_request.head.sha }}' -f path='FILE_PATH' -F line=LINE_NUMBER -f side='RIGHT' For MULTI-LINE comments: - gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments -f body='#### Tabnine PR Bot + gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments -f body='$COMMENT_PREFIX YOUR_COMMENT' -f commit_id='${{ github.event.pull_request.head.sha }}' -f path='FILE_PATH' -F start_line=START_LINE_NUMBER -f start_side='RIGHT' -F line=END_LINE_NUMBER -f side='RIGHT' **Code Suggestions**: Use GitHub's suggestion syntax ONLY when the fix is clear, unambiguous, and replaces 10 or fewer lines: @@ -366,7 +369,7 @@ jobs: After submitting inline comments (or if zero comments were posted), post the holistic summary. The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary comment using: - gh api --method POST /repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments -f body='#### Tabnine PR Bot + gh api --method POST /repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments -f body='$COMMENT_PREFIX YOUR_SUMMARY' diff --git a/GitLab/.gitlab-ci.yml b/GitLab/.gitlab-ci.yml index 9dc0146..c848786 100644 --- a/GitLab/.gitlab-ci.yml +++ b/GitLab/.gitlab-ci.yml @@ -11,6 +11,7 @@ # TABNINE_HOST - Tabnine host URL (default: https://console.tabnine.com) # TABNINE_MODEL_ID - Model ID for the Tabnine CLI agent # TABNINE_CLEANUP - Set to "true" to delete settings.json after each run. Recommended for self-hosted runners. +# TABNINE_COMMENT_PREFIX - Prefix used to identify bot comments for cleanup (default: '#### Tabnine PR Bot'). stages: - review @@ -86,12 +87,13 @@ tabnine-code-review: export HEAD_SHA="${CI_MERGE_REQUEST_DIFF_HEAD_SHA}" export BASE_SHA="${CI_MERGE_REQUEST_DIFF_BASE_SHA}" export PROJECT_PATH="${CI_PROJECT_PATH}" + export COMMENT_PREFIX="${TABNINE_COMMENT_PREFIX:-#### Tabnine PR Bot}" # Clean up previous bot summary notes - echo "Cleaning up previous Tabnine PR Bot notes..." + echo "Cleaning up previous bot comments (prefix: $COMMENT_PREFIX)..." NOTES=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ "$GITLAB_API_URL/projects/$PROJECT_ID/merge_requests/$MR_IID/notes" \ - | jq -r '.[] | select(.body | startswith("#### Tabnine PR Bot")) | .id') + | jq -r ".[] | select(.body | startswith(\"$COMMENT_PREFIX\")) | .id") for NOTE_ID in $NOTES; do echo "Deleting bot note: $NOTE_ID" @@ -100,10 +102,10 @@ tabnine-code-review: done # Clean up previous bot inline comments (discussion notes) - echo "Cleaning up previous Tabnine PR Bot inline comments..." + echo "Cleaning up previous bot inline comments (prefix: $COMMENT_PREFIX)..." DISCUSSIONS=$(curl -s --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ "$GITLAB_API_URL/projects/$PROJECT_ID/merge_requests/$MR_IID/discussions") - echo "$DISCUSSIONS" | jq -r '.[] | {did: .id, notes: [.notes[] | select(.body | startswith("#### Tabnine PR Bot")) | .id]} | select(.notes | length > 0) | .did as $did | .notes[] | "\($did) \(.)"' | while read DISCUSSION_ID NOTE_ID; do + echo "$DISCUSSIONS" | jq -r ".[] | {did: .id, notes: [.notes[] | select(.body | startswith(\"$COMMENT_PREFIX\")) | .id]} | select(.notes | length > 0) | .did as \$did | .notes[] | \"\\(\$did) \\(.)\"" | while read DISCUSSION_ID NOTE_ID; do echo "Deleting bot inline comment: discussion=$DISCUSSION_ID note=$NOTE_ID" curl -s --request DELETE --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ "$GITLAB_API_URL/projects/$PROJECT_ID/merge_requests/$MR_IID/discussions/$DISCUSSION_ID/notes/$NOTE_ID" || true @@ -327,14 +329,14 @@ tabnine-code-review: - **[Suggestion]** -- Improvements to maintainability or clarity. Author's discretion. Submit inline comments using the GitLab Discussions API: - **IMPORTANT**: All comments MUST start with '#### Tabnine PR Bot' on the first line, followed by a blank line, then your formatted comment content. + **IMPORTANT**: All comments MUST start with '$COMMENT_PREFIX' on the first line, followed by a blank line, then your formatted comment content. For inline comments on specific lines: curl -s --request POST --header 'PRIVATE-TOKEN: \$GITLAB_API_TOKEN' --header 'Content-Type: application/json' \\ - --data '{\"body\": \"#### Tabnine PR Bot\n\nYOUR_COMMENT\", \"position\": {\"base_sha\": \"\$BASE_SHA\", \"head_sha\": \"\$HEAD_SHA\", \"start_sha\": \"\$BASE_SHA\", \"position_type\": \"text\", \"new_path\": \"FILE_PATH\", \"new_line\": LINE_NUMBER}}' \\ + --data '{\"body\": \"$COMMENT_PREFIX\n\nYOUR_COMMENT\", \"position\": {\"base_sha\": \"\$BASE_SHA\", \"head_sha\": \"\$HEAD_SHA\", \"start_sha\": \"\$BASE_SHA\", \"position_type\": \"text\", \"new_path\": \"FILE_PATH\", \"new_line\": LINE_NUMBER}}' \\ '\$GITLAB_API_URL/projects/\$PROJECT_ID/merge_requests/\$MR_IID/discussions' For multi-line inline comments: curl -s --request POST --header 'PRIVATE-TOKEN: \$GITLAB_API_TOKEN' --header 'Content-Type: application/json' \\ - --data '{\"body\": \"#### Tabnine PR Bot\n\nYOUR_COMMENT\", \"position\": {\"base_sha\": \"\$BASE_SHA\", \"head_sha\": \"\$HEAD_SHA\", \"start_sha\": \"\$BASE_SHA\", \"position_type\": \"text\", \"new_path\": \"FILE_PATH\", \"new_line\": END_LINE_NUMBER, \"line_range\": {\"start\": {\"line_code\": \"START_LINE_CODE\", \"type\": \"new\"}, \"end\": {\"line_code\": \"END_LINE_CODE\", \"type\": \"new\"}}}}' \\ + --data '{\"body\": \"$COMMENT_PREFIX\n\nYOUR_COMMENT\", \"position\": {\"base_sha\": \"\$BASE_SHA\", \"head_sha\": \"\$HEAD_SHA\", \"start_sha\": \"\$BASE_SHA\", \"position_type\": \"text\", \"new_path\": \"FILE_PATH\", \"new_line\": END_LINE_NUMBER, \"line_range\": {\"start\": {\"line_code\": \"START_LINE_CODE\", \"type\": \"new\"}, \"end\": {\"line_code\": \"END_LINE_CODE\", \"type\": \"new\"}}}}' \\ '\$GITLAB_API_URL/projects/\$PROJECT_ID/merge_requests/\$MR_IID/discussions' **Code Suggestions**: Use GitLab's suggestion syntax ONLY when the fix is clear, unambiguous, and replaces 10 or fewer lines: \`\`\`suggestion:-0+0 @@ -347,7 +349,7 @@ tabnine-code-review: The summary is the MOST IMPORTANT output -- most developers read only this. Create the summary note using the GitLab Notes API: curl -s --request POST --header 'PRIVATE-TOKEN: \$GITLAB_API_TOKEN' --header 'Content-Type: application/json' \\ - --data '{\"body\": \"#### Tabnine PR Bot\n\nYOUR_SUMMARY\"}' \\ + --data '{\"body\": \"$COMMENT_PREFIX\n\nYOUR_SUMMARY\"}' \\ '\$GITLAB_API_URL/projects/\$PROJECT_ID/merge_requests/\$MR_IID/notes' Structure your summary as follows: From 630f19eb92221e312c924cbfff795d49e0998421 Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 29 Apr 2026 14:48:45 +0300 Subject: [PATCH 6/8] Update README with new inputs and variables for comment prefix, prompt override, and cleanup --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 6e00846..bc94556 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,20 @@ permissions: # Model ID for the Tabnine CLI agent (optional, overrides DEFAULT_MODEL_ID in action.yml) # model_id: "your-model-id" + + # Custom prompt to replace the default code review (optional) + # prompt_override: "Your custom prompt here" + + # Display name for the agent step (optional, default: 'Tabnine Agent') + # step_name: "Tabnine Agent" + + # Prefix used to identify bot comments for cleanup (optional, default: '#### Tabnine PR Bot') + # Use a unique value per action invocation to avoid cross-cleanup. + # comment_prefix: "#### Tabnine PR Bot" + + # Set to "true" to delete settings.json after each run (optional, default: "false") + # Recommended for self-hosted runners. + # cleanup: "true" ``` ### Inputs @@ -77,6 +91,10 @@ permissions: | `base_sha` | Yes | — | PR base commit SHA | | `tabnine_host` | No | `https://console.tabnine.com` | Tabnine host URL (for self-hosted / EMT installations) | | `model_id` | No | — | Model ID for the Tabnine CLI agent. If omitted, falls back to `DEFAULT_MODEL_ID` in `action.yml` or the system default from the admin console. | +| `prompt_override` | No | — | Custom prompt to replace the default code review prompt. When provided, the agent runs your prompt instead of the built-in review. | +| `step_name` | No | `Tabnine Agent` | Display name for the agent step. | +| `comment_prefix` | No | `#### Tabnine PR Bot` | Prefix used to identify bot comments for cleanup. Use a unique value per action invocation to avoid cross-cleanup. | +| `cleanup` | No | `false` | Set to `"true"` to delete `settings.json` after each run. Recommended for self-hosted runners. | ## Full Workflow Example @@ -129,6 +147,8 @@ Set the following CI/CD variables in **Settings > CI/CD > Variables**: | `GITLAB_API_TOKEN` | Yes | GitLab personal or project access token with `api` scope. Mark as **Masked**. | | `TABNINE_HOST` | No | Tabnine host URL for self-hosted / EMT installations (default: `https://console.tabnine.com`) | | `TABNINE_MODEL_ID` | No | Model ID for the Tabnine CLI agent. If empty, uses the system default from the admin console. | +| `TABNINE_CLEANUP` | No | Set to `"true"` to delete `settings.json` after each run. Recommended for self-hosted runners. | +| `TABNINE_COMMENT_PREFIX` | No | Prefix used to identify bot comments for cleanup (default: `#### Tabnine PR Bot`). | ## Usage @@ -166,6 +186,8 @@ Set the following repository variables in **Repository Settings > Pipelines > Re | `BB_API_TOKEN` | Yes | Bitbucket token with `pullrequest:write` and `repository:read` scopes. Mark as **Secured**. | | `TABNINE_HOST` | No | Tabnine host URL for self-hosted / EMT installations (default: `https://console.tabnine.com`) | | `TABNINE_MODEL_ID` | No | Model ID for the Tabnine CLI agent. If empty, falls back to `DEFAULT_MODEL_ID` in the pipeline yml or the system default from the admin console. | +| `TABNINE_CLEANUP` | No | Set to `"true"` to delete `settings.json` after each run. Recommended for self-hosted runners. | +| `TABNINE_COMMENT_PREFIX` | No | Prefix used to identify bot comments for cleanup (default: `#### Tabnine PR Bot`). | ## Usage From 1a5b39e9c1d282fa6273b0ae2b70b1f37215353e Mon Sep 17 00:00:00 2001 From: Pavel Date: Wed, 29 Apr 2026 15:00:23 +0300 Subject: [PATCH 7/8] Add FILE-LEVEL comment guidance to all standalone workflow prompts --- Bitbucket/bitbucket-pipelines.yml | 4 ++++ GitHub/tabnine-review.yml | 6 ++++++ GitLab/.gitlab-ci.yml | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/Bitbucket/bitbucket-pipelines.yml b/Bitbucket/bitbucket-pipelines.yml index 902e6c0..a64556d 100644 --- a/Bitbucket/bitbucket-pipelines.yml +++ b/Bitbucket/bitbucket-pipelines.yml @@ -319,8 +319,12 @@ pipelines: - **[Warning]** -- Logic issues, edge cases, performance concerns. Strongly recommended to fix. - **[Suggestion]** -- Improvements to maintainability or clarity. Author's discretion. + **FILE-LEVEL vs LINE-LEVEL comments**: If a comment applies to the entire file rather than specific lines (e.g., a deleted file, a file that should not exist, or a concern about the file as a whole), post a FILE-LEVEL comment using 'inline.path' without 'from'/'to' instead of a comment spanning all lines. Never post a comment that covers all or most lines of a file -- this creates an excessively large comment. Use file-level comments for file-wide feedback. + Submit inline comments using the Bitbucket PR Comments API: **IMPORTANT**: All comments MUST start with '$COMMENT_PREFIX' on the first line, followed by a blank line, then your formatted comment content. + For FILE-LEVEL comments (when the comment applies to the entire file, not specific lines): + curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request POST --header 'Content-Type: application/json' --data '{"content": {"raw": "$COMMENT_PREFIX\n\nYOUR_COMMENT"}, "inline": {"path": "FILE_PATH"}}' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments' For inline comments on specific lines: curl -s --header 'Authorization: Bearer \$BB_API_TOKEN' --request POST --header 'Content-Type: application/json' --data '{"content": {"raw": "$COMMENT_PREFIX\n\nYOUR_COMMENT"}, "inline": {"path": "FILE_PATH", "to": LINE_NUMBER}}' '$BB_API_BASE/repositories/$BB_WORKSPACE/$BB_REPO_SLUG/pullrequests/$BB_PR_ID/comments' diff --git a/GitHub/tabnine-review.yml b/GitHub/tabnine-review.yml index 4d27b7c..da202e9 100644 --- a/GitHub/tabnine-review.yml +++ b/GitHub/tabnine-review.yml @@ -349,8 +349,14 @@ jobs: - **[Warning]** -- Logic issues, edge cases, performance concerns. Strongly recommended to fix. - **[Suggestion]** -- Improvements to maintainability or clarity. Author's discretion. + **FILE-LEVEL vs LINE-LEVEL comments**: If a comment applies to the entire file rather than specific lines (e.g., a deleted file, a file that should not exist, or a concern about the file as a whole), post a FILE-LEVEL comment using 'subject_type=file' instead of a multi-line comment spanning all lines. Never post a multi-line comment that covers all or most lines of a file -- this creates an excessively large comment. Use file-level comments for file-wide feedback. + Submit inline comments using: **IMPORTANT**: All comments MUST start with '$COMMENT_PREFIX' on the first line, followed by a blank line, then your formatted comment content. + For FILE-LEVEL comments (when the comment applies to the entire file, not specific lines): + gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments -f body='$COMMENT_PREFIX + + YOUR_COMMENT' -f commit_id='${{ github.event.pull_request.head.sha }}' -f path='FILE_PATH' -f subject_type='file' For SINGLE-LINE comments: gh api --method POST -H 'Accept: application/vnd.github+json' /repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/comments -f body='$COMMENT_PREFIX diff --git a/GitLab/.gitlab-ci.yml b/GitLab/.gitlab-ci.yml index c848786..1e5db08 100644 --- a/GitLab/.gitlab-ci.yml +++ b/GitLab/.gitlab-ci.yml @@ -328,8 +328,14 @@ tabnine-code-review: - **[Warning]** -- Logic issues, edge cases, performance concerns. Strongly recommended to fix. - **[Suggestion]** -- Improvements to maintainability or clarity. Author's discretion. + **FILE-LEVEL vs LINE-LEVEL comments**: If a comment applies to the entire file rather than specific lines (e.g., a deleted file, a file that should not exist, or a concern about the file as a whole), post a general MR discussion (without the 'position' parameter) and mention the filename in the body. Never post an inline comment that covers all or most lines of a file -- this creates an excessively large comment. Use file-level comments for file-wide feedback. + Submit inline comments using the GitLab Discussions API: **IMPORTANT**: All comments MUST start with '$COMMENT_PREFIX' on the first line, followed by a blank line, then your formatted comment content. + For FILE-LEVEL comments (when the comment applies to the entire file, not specific lines -- post as a general discussion, not an inline comment): + curl -s --request POST --header 'PRIVATE-TOKEN: \$GITLAB_API_TOKEN' --header 'Content-Type: application/json' \\ + --data '{\"body\": \"$COMMENT_PREFIX\n\n**File: FILE_PATH**\n\nYOUR_COMMENT\"}' \\ + '\$GITLAB_API_URL/projects/\$PROJECT_ID/merge_requests/\$MR_IID/discussions' For inline comments on specific lines: curl -s --request POST --header 'PRIVATE-TOKEN: \$GITLAB_API_TOKEN' --header 'Content-Type: application/json' \\ --data '{\"body\": \"$COMMENT_PREFIX\n\nYOUR_COMMENT\", \"position\": {\"base_sha\": \"\$BASE_SHA\", \"head_sha\": \"\$HEAD_SHA\", \"start_sha\": \"\$BASE_SHA\", \"position_type\": \"text\", \"new_path\": \"FILE_PATH\", \"new_line\": LINE_NUMBER}}' \\ From 593c518eea9dc9491ce20233805d58228f712fb2 Mon Sep 17 00:00:00 2001 From: Pavel-tabnine Date: Wed, 29 Apr 2026 15:45:08 +0300 Subject: [PATCH 8/8] Update Tabnine PR agent version to v2 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bc94556..0804488 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ permissions: ```yaml - name: Review PR - uses: codota/tabnine-pr-agent@v1 + uses: codota/tabnine-pr-agent@v2 continue-on-error: true with: # Tabnine authentication token — required @@ -120,7 +120,7 @@ jobs: fetch-depth: 0 - name: Review PR - uses: codota/tabnine-pr-agent@v1 + uses: codota/tabnine-pr-agent@v2 continue-on-error: true with: TABNINE_KEY: ${{ secrets.TABNINE_KEY }}