From 849d3176fde0f2cb3da98de6796b5e235e6b7df1 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 12:52:17 -0500 Subject: [PATCH 01/19] feat: add automated PR review workflow with Ollama AI --- .gitea/workflows/pr-review.yml | 65 ++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 .gitea/workflows/pr-review.yml diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml new file mode 100644 index 00000000..4078e08c --- /dev/null +++ b/.gitea/workflows/pr-review.yml @@ -0,0 +1,65 @@ +name: PR Review Automation + +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + review: + runs-on: ubuntu-latest + steps: + - name: Checkout PR branch + uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + fetch-depth: 0 + + - name: Get base branch + run: git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} + + - name: Get PR diff + id: diff + run: | + git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr_diff.txt + echo "diff_size=$(wc -l < /tmp/pr_diff.txt)" >> $GITHUB_OUTPUT + + - name: Analyze with Ollama + if: steps.diff.outputs.diff_size > '0' + env: + OLLAMA_URL: https://ollama-ui.tftsr.com/ollama/v1 + API_KEY: ${{ secrets.OLLAMA_API_KEY }} + run: | + DIFF_CONTENT=$(cat /tmp/pr_diff.txt) + PROMPT="Analyze the following code changes for completion, completeness, correctness, security issues, and best practices. + + PR Title: ${{ github.event.pull_request.title }} + + Diff: + $DIFF_CONTENT + + Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. + Then give specific comments with suggested fixes." + + RESPONSE=$(curl -s -X POST "$OLLAMA_URL/chat" \ + -H "Authorization: Bearer $API_KEY" \ + -H "Content-Type: application/json" \ + -d "{\"model\":\"qwen3-coder-next:latest\",\"messages\":[{\"role\":\"user\",\"content\":\"$PROMPT\"}],\"stream\":false}") + + echo "$RESPONSE" > /tmp/ollama_response.json + + REVIEW=$(echo "$RESPONSE" | grep -o '"content":"[^"]*"' | head -1 | sed 's/"content":"//;s/"$//') + echo "$REVIEW" > /tmp/pr_review.txt + + - name: Post review comment + if: success() + env: + GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} + run: | + if [ -f "/tmp/pr_review.txt" ]; then + REVIEW_BODY=$(cat /tmp/pr_review.txt | head -c 65536) + curl -s -X POST "https://gogs.tftsr.com/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ + -H "Authorization: token $GITEA_TOKEN" \ + -H "Content-Type: application/json" \ + -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" + fi From de59684432cb066b677005e0fbc3d971c42991d2 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 13:04:04 -0500 Subject: [PATCH 02/19] fix: rename GITEA_TOKEN to TF_TOKEN to comply with naming restrictions --- .gitea/workflows/pr-review.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 4078e08c..defcc131 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -53,13 +53,13 @@ jobs: - name: Post review comment if: success() env: - GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }} + TF_TOKEN: ${{ secrets.TFT_GITEA_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} run: | if [ -f "/tmp/pr_review.txt" ]; then REVIEW_BODY=$(cat /tmp/pr_review.txt | head -c 65536) curl -s -X POST "https://gogs.tftsr.com/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ - -H "Authorization: token $GITEA_TOKEN" \ + -H "Authorization: token $TF_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" fi From 8cee1c5655b224c6c8ece396493c59168915fa31 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 13:43:43 -0500 Subject: [PATCH 03/19] fix: remove actions/checkout to avoid Node.js dependency --- .gitea/workflows/pr-review.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index defcc131..3f79abc1 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -8,19 +8,14 @@ jobs: review: runs-on: ubuntu-latest steps: - - name: Checkout PR branch - uses: actions/checkout@v4 - with: - ref: ${{ github.head_ref }} - fetch-depth: 0 - - name: Get base branch run: git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} - name: Get PR diff id: diff run: | - git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr_diff.txt + git config --global --add safe.directory /__w/tftsr-devops_investigation/tftsr-devops_investigation + git diff origin/${{ github.base_ref }}..${{ github.head_ref }} > /tmp/pr_diff.txt echo "diff_size=$(wc -l < /tmp/pr_diff.txt)" >> $GITHUB_OUTPUT - name: Analyze with Ollama @@ -36,7 +31,7 @@ jobs: Diff: $DIFF_CONTENT - + Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. Then give specific comments with suggested fixes." @@ -46,7 +41,7 @@ jobs: -d "{\"model\":\"qwen3-coder-next:latest\",\"messages\":[{\"role\":\"user\",\"content\":\"$PROMPT\"}],\"stream\":false}") echo "$RESPONSE" > /tmp/ollama_response.json - + REVIEW=$(echo "$RESPONSE" | grep -o '"content":"[^"]*"' | head -1 | sed 's/"content":"//;s/"$//') echo "$REVIEW" > /tmp/pr_review.txt From 0b85258e7d492414bb9048f6d3757e450b7bc3a2 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 13:51:50 -0500 Subject: [PATCH 04/19] fix: use ubuntu container with git installed --- .gitea/workflows/pr-review.yml | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 3f79abc1..8a8f849c 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -7,19 +7,33 @@ on: jobs: review: runs-on: ubuntu-latest + container: + image: ubuntu:22.04 steps: - - name: Get base branch - run: git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} + - name: Install dependencies + run: | + apt-get update && apt-get install -y \ + git \ + curl \ + jq \ + && rm -rf /var/lib/apt/lists/* - name: Get PR diff - id: diff + env: + BASE_REF: ${{ github.base_ref }} + HEAD_REF: ${{ github.head_ref }} run: | - git config --global --add safe.directory /__w/tftsr-devops_investigation/tftsr-devops_investigation - git diff origin/${{ github.base_ref }}..${{ github.head_ref }} > /tmp/pr_diff.txt + git config --global user.name "Automated Review" + git config --global user.email "review@example.com" + git clone https://gogs.tftsr.com/sarman/tftsr-devops_investigation.git /tmp/repo + cd /tmp/repo + git fetch origin + git checkout $HEAD_REF + git diff origin/$BASE_REF..HEAD > /tmp/pr_diff.txt echo "diff_size=$(wc -l < /tmp/pr_diff.txt)" >> $GITHUB_OUTPUT - name: Analyze with Ollama - if: steps.diff.outputs.diff_size > '0' + if: success() env: OLLAMA_URL: https://ollama-ui.tftsr.com/ollama/v1 API_KEY: ${{ secrets.OLLAMA_API_KEY }} @@ -31,7 +45,7 @@ jobs: Diff: $DIFF_CONTENT - + Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. Then give specific comments with suggested fixes." @@ -41,8 +55,7 @@ jobs: -d "{\"model\":\"qwen3-coder-next:latest\",\"messages\":[{\"role\":\"user\",\"content\":\"$PROMPT\"}],\"stream\":false}") echo "$RESPONSE" > /tmp/ollama_response.json - - REVIEW=$(echo "$RESPONSE" | grep -o '"content":"[^"]*"' | head -1 | sed 's/"content":"//;s/"$//') + REVIEW=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // empty') echo "$REVIEW" > /tmp/pr_review.txt - name: Post review comment @@ -51,7 +64,7 @@ jobs: TF_TOKEN: ${{ secrets.TFT_GITEA_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} run: | - if [ -f "/tmp/pr_review.txt" ]; then + if [ -f "/tmp/pr_review.txt" ] && [ -s "/tmp/pr_review.txt" ]; then REVIEW_BODY=$(cat /tmp/pr_review.txt | head -c 65536) curl -s -X POST "https://gogs.tftsr.com/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ -H "Authorization: token $TF_TOKEN" \ From f47dcf69a3094737cdba38419c51a5fb8c872a15 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 14:07:54 -0500 Subject: [PATCH 05/19] fix: use actions/checkout with token auth and self-hosted runner --- .gitea/workflows/pr-review.yml | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 8a8f849c..42ec60dc 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -6,7 +6,7 @@ on: jobs: review: - runs-on: ubuntu-latest + runs-on: self-hosted container: image: ubuntu:22.04 steps: @@ -18,22 +18,21 @@ jobs: jq \ && rm -rf /var/lib/apt/lists/* + - name: Checkout code + uses: actions/checkout@v4 + with: + token: ${{ secrets.TFT_GITEA_TOKEN }} + ref: ${{ github.head_ref }} + - name: Get PR diff - env: - BASE_REF: ${{ github.base_ref }} - HEAD_REF: ${{ github.head_ref }} + id: diff run: | - git config --global user.name "Automated Review" - git config --global user.email "review@example.com" - git clone https://gogs.tftsr.com/sarman/tftsr-devops_investigation.git /tmp/repo - cd /tmp/repo - git fetch origin - git checkout $HEAD_REF - git diff origin/$BASE_REF..HEAD > /tmp/pr_diff.txt + git fetch origin ${{ github.base_ref }} + git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr_diff.txt echo "diff_size=$(wc -l < /tmp/pr_diff.txt)" >> $GITHUB_OUTPUT - name: Analyze with Ollama - if: success() + if: steps.diff.outputs.diff_size > '0' env: OLLAMA_URL: https://ollama-ui.tftsr.com/ollama/v1 API_KEY: ${{ secrets.OLLAMA_API_KEY }} From 98a0f908d780a0b03ccd85124cb77fa6de1057fb Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 14:08:48 -0500 Subject: [PATCH 06/19] fix: use IP addresses for internal services --- .gitea/workflows/pr-review.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 42ec60dc..350c6014 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -34,7 +34,7 @@ jobs: - name: Analyze with Ollama if: steps.diff.outputs.diff_size > '0' env: - OLLAMA_URL: https://ollama-ui.tftsr.com/ollama/v1 + OLLAMA_URL: http://172.0.0.29:3000/ollama/v1 API_KEY: ${{ secrets.OLLAMA_API_KEY }} run: | DIFF_CONTENT=$(cat /tmp/pr_diff.txt) @@ -44,7 +44,7 @@ jobs: Diff: $DIFF_CONTENT - + Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. Then give specific comments with suggested fixes." @@ -65,7 +65,7 @@ jobs: run: | if [ -f "/tmp/pr_review.txt" ] && [ -s "/tmp/pr_review.txt" ]; then REVIEW_BODY=$(cat /tmp/pr_review.txt | head -c 65536) - curl -s -X POST "https://gogs.tftsr.com/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ + curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ -H "Authorization: token $TF_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" From 63a055d4fe54572e032ecdf77acf63f82fc108dc Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 14:59:41 -0500 Subject: [PATCH 07/19] fix: simplified workflow syntax --- .gitea/workflows/pr-review.yml | 40 ++++++++++------------------------ 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 350c6014..60322a47 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -6,23 +6,21 @@ on: jobs: review: - runs-on: self-hosted + runs-on: ubuntu-latest container: image: ubuntu:22.04 steps: - name: Install dependencies run: | - apt-get update && apt-get install -y \ - git \ - curl \ - jq \ - && rm -rf /var/lib/apt/lists/* + set -eux + apt-get update -qq && apt-get install -y -qq git curl jq - name: Checkout code - uses: actions/checkout@v4 - with: - token: ${{ secrets.TFT_GITEA_TOKEN }} - ref: ${{ github.head_ref }} + run: | + git init + git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git + git fetch --depth=1 origin ${{ github.head_ref }} + git checkout FETCH_HEAD - name: Get PR diff id: diff @@ -38,21 +36,8 @@ jobs: API_KEY: ${{ secrets.OLLAMA_API_KEY }} run: | DIFF_CONTENT=$(cat /tmp/pr_diff.txt) - PROMPT="Analyze the following code changes for completion, completeness, correctness, security issues, and best practices. - - PR Title: ${{ github.event.pull_request.title }} - - Diff: - $DIFF_CONTENT - - Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. - Then give specific comments with suggested fixes." - - RESPONSE=$(curl -s -X POST "$OLLAMA_URL/chat" \ - -H "Authorization: Bearer $API_KEY" \ - -H "Content-Type: application/json" \ - -d "{\"model\":\"qwen3-coder-next:latest\",\"messages\":[{\"role\":\"user\",\"content\":\"$PROMPT\"}],\"stream\":false}") - + PROMPT="Analyze the following code changes for completion, completeness, correctness, security issues, and best practices. PR Title: ${{ github.event.pull_request.title }}. Diff: $DIFF_CONTENT. Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. Then give specific comments with suggested fixes." + RESPONSE=$(curl -s -X POST "$OLLAMA_URL/chat" -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d "{\"model\":\"qwen3-coder-next:latest\",\"messages\":[{\"role\":\"user\",\"content\":\"$PROMPT\"}],\"stream\":false}") echo "$RESPONSE" > /tmp/ollama_response.json REVIEW=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // empty') echo "$REVIEW" > /tmp/pr_review.txt @@ -65,8 +50,5 @@ jobs: run: | if [ -f "/tmp/pr_review.txt" ] && [ -s "/tmp/pr_review.txt" ]; then REVIEW_BODY=$(cat /tmp/pr_review.txt | head -c 65536) - curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ - -H "Authorization: token $TF_TOKEN" \ - -H "Content-Type: application/json" \ - -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" + curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" -H "Authorization: token $TF_TOKEN" -H "Content-Type: application/json" -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" fi From d759486b5137393c62aaadf2f83362cd61470702 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Fri, 10 Apr 2026 16:16:55 -0500 Subject: [PATCH 08/19] fix: add debugging output for Ollamaresponse --- .gitea/workflows/pr-review.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 60322a47..30b44396 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -37,10 +37,20 @@ jobs: run: | DIFF_CONTENT=$(cat /tmp/pr_diff.txt) PROMPT="Analyze the following code changes for completion, completeness, correctness, security issues, and best practices. PR Title: ${{ github.event.pull_request.title }}. Diff: $DIFF_CONTENT. Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. Then give specific comments with suggested fixes." + echo "Calling Ollama API..." RESPONSE=$(curl -s -X POST "$OLLAMA_URL/chat" -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d "{\"model\":\"qwen3-coder-next:latest\",\"messages\":[{\"role\":\"user\",\"content\":\"$PROMPT\"}],\"stream\":false}") + echo "Response: $RESPONSE" > /tmp/ollama_response.txt echo "$RESPONSE" > /tmp/ollama_response.json - REVIEW=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // empty') + echo "Response saved to /tmp/ollama_response.json" + if [ -z "$RESPONSE" ]; then + echo "ERROR: Empty response from Ollama" + exit 1 + fi + REVIEW=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // empty' 2>/dev/null || echo "Failed to parse jq response") echo "$REVIEW" > /tmp/pr_review.txt + if [ -z "$REVIEW" ]; then + echo "WARNING: No review content extracted" + fi - name: Post review comment if: success() @@ -50,5 +60,7 @@ jobs: run: | if [ -f "/tmp/pr_review.txt" ] && [ -s "/tmp/pr_review.txt" ]; then REVIEW_BODY=$(cat /tmp/pr_review.txt | head -c 65536) - curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" -H "Authorization: token $TF_TOKEN" -H "Content-Type: application/json" -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" + curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" -H "Authorization: token $TF_TOKEN" -H "Content-Type: application/json" -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" + else + echo "No review to post" fi From 5e61d4f5504b8b1c35dae21dcc43c782254daa72 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 15:56:13 -0500 Subject: [PATCH 09/19] fix: correct Ollama URL, API endpoint, and JSON construction in pr-review workflow - Fix OLLAMA_URL to point at actual Ollama server (172.0.1.42:11434) - Fix API path from /v1/chat to /api/chat (Ollama native endpoint) - Fix response parsing from OpenAI format to Ollama native (.message.content) - Use jq to safely construct JSON bodies in both Analyze and Post steps - Add HTTP status code check and response body logging for diagnostics --- .gitea/workflows/pr-review.yml | 42 ++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 30b44396..5838cfb9 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -32,25 +32,33 @@ jobs: - name: Analyze with Ollama if: steps.diff.outputs.diff_size > '0' env: - OLLAMA_URL: http://172.0.0.29:3000/ollama/v1 - API_KEY: ${{ secrets.OLLAMA_API_KEY }} + OLLAMA_URL: http://172.0.1.42:11434 run: | DIFF_CONTENT=$(cat /tmp/pr_diff.txt) - PROMPT="Analyze the following code changes for completion, completeness, correctness, security issues, and best practices. PR Title: ${{ github.event.pull_request.title }}. Diff: $DIFF_CONTENT. Provide review with: 1) Completion check, 2) Completeness check, 3) Bugs/errors, 4) Security issues, 5) Best practices. Then give specific comments with suggested fixes." + PR_TITLE="${{ github.event.pull_request.title }}" + PROMPT="Analyze the following code changes for correctness, security issues, and best practices. PR Title: ${PR_TITLE}\n\nDiff:\n${DIFF_CONTENT}\n\nProvide a review with: 1) Summary, 2) Bugs/errors, 3) Security issues, 4) Best practices. Give specific comments with suggested fixes." + BODY=$(jq -n \ + --arg model "qwen3-coder-next:latest" \ + --arg content "$PROMPT" \ + '{model: $model, messages: [{role: "user", content: $content}], stream: false}') echo "Calling Ollama API..." - RESPONSE=$(curl -s -X POST "$OLLAMA_URL/chat" -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d "{\"model\":\"qwen3-coder-next:latest\",\"messages\":[{\"role\":\"user\",\"content\":\"$PROMPT\"}],\"stream\":false}") - echo "Response: $RESPONSE" > /tmp/ollama_response.txt - echo "$RESPONSE" > /tmp/ollama_response.json - echo "Response saved to /tmp/ollama_response.json" - if [ -z "$RESPONSE" ]; then - echo "ERROR: Empty response from Ollama" + HTTP_CODE=$(curl -s -o /tmp/ollama_response.json -w "%{http_code}" \ + -X POST "$OLLAMA_URL/api/chat" \ + -H "Content-Type: application/json" \ + -d "$BODY") + echo "HTTP status: $HTTP_CODE" + echo "Response body:" + cat /tmp/ollama_response.json + if [ "$HTTP_CODE" != "200" ]; then + echo "ERROR: Ollama returned HTTP $HTTP_CODE" exit 1 fi - REVIEW=$(echo "$RESPONSE" | jq -r '.choices[0].message.content // empty' 2>/dev/null || echo "Failed to parse jq response") - echo "$REVIEW" > /tmp/pr_review.txt + REVIEW=$(jq -r '.message.content // empty' /tmp/ollama_response.json) if [ -z "$REVIEW" ]; then - echo "WARNING: No review content extracted" + echo "ERROR: No content in Ollama response" + exit 1 fi + echo "$REVIEW" > /tmp/pr_review.txt - name: Post review comment if: success() @@ -59,8 +67,14 @@ jobs: PR_NUMBER: ${{ github.event.pull_request.number }} run: | if [ -f "/tmp/pr_review.txt" ] && [ -s "/tmp/pr_review.txt" ]; then - REVIEW_BODY=$(cat /tmp/pr_review.txt | head -c 65536) - curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" -H "Authorization: token $TF_TOKEN" -H "Content-Type: application/json" -d "{\"body\": \"🤖 Automated PR Review:\n\n$REVIEW_BODY\n\n---\n*this is an automated review from Ollama*\", \"event\": \"COMMENT\"}" + REVIEW_BODY=$(head -c 65536 /tmp/pr_review.txt) + BODY=$(jq -n \ + --arg body "🤖 Automated PR Review:\n\n${REVIEW_BODY}\n\n---\n*this is an automated review from Ollama*" \ + '{body: $body, event: "COMMENT"}') + curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ + -H "Authorization: token $TF_TOKEN" \ + -H "Content-Type: application/json" \ + -d "$BODY" else echo "No review to post" fi From 8f73a7d01712d5b97813aba3b8163885e75f711f Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 16:03:27 -0500 Subject: [PATCH 10/19] fix: add diagnostics to identify empty Ollama response root cause --- .gitea/workflows/pr-review.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 5838cfb9..c4c485fc 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -41,14 +41,17 @@ jobs: --arg model "qwen3-coder-next:latest" \ --arg content "$PROMPT" \ '{model: $model, messages: [{role: "user", content: $content}], stream: false}') + echo "Request body length: ${#BODY} bytes" + echo "Request body (first 200 chars): ${BODY:0:200}" echo "Calling Ollama API..." HTTP_CODE=$(curl -s -o /tmp/ollama_response.json -w "%{http_code}" \ -X POST "$OLLAMA_URL/api/chat" \ -H "Content-Type: application/json" \ -d "$BODY") echo "HTTP status: $HTTP_CODE" - echo "Response body:" - cat /tmp/ollama_response.json + echo "Response file size: $(wc -c < /tmp/ollama_response.json) bytes" + echo "Response body (jq pretty-print or raw):" + jq . /tmp/ollama_response.json 2>/dev/null || cat /tmp/ollama_response.json if [ "$HTTP_CODE" != "200" ]; then echo "ERROR: Ollama returned HTTP $HTTP_CODE" exit 1 From 1db1b2076297acdde36418aa729b24da8087649e Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 16:07:39 -0500 Subject: [PATCH 11/19] fix: use bash shell and remove bash-only substring expansion in pr-review --- .gitea/workflows/pr-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index c4c485fc..e0550097 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -31,6 +31,7 @@ jobs: - name: Analyze with Ollama if: steps.diff.outputs.diff_size > '0' + shell: bash env: OLLAMA_URL: http://172.0.1.42:11434 run: | @@ -42,7 +43,6 @@ jobs: --arg content "$PROMPT" \ '{model: $model, messages: [{role: "user", content: $content}], stream: false}') echo "Request body length: ${#BODY} bytes" - echo "Request body (first 200 chars): ${BODY:0:200}" echo "Calling Ollama API..." HTTP_CODE=$(curl -s -o /tmp/ollama_response.json -w "%{http_code}" \ -X POST "$OLLAMA_URL/api/chat" \ From 44584d6302d17c07b3bac9bcb56f508cc665cd8f Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 16:20:18 -0500 Subject: [PATCH 12/19] fix: restore migration 014, bump version to 0.2.50, harden pr-review workflow - Restore 014_create_ai_providers migration and tests missing due to branch diverging from master before PR #34 merged - Bump version from 0.2.10 to 0.2.50 to match master and avoid regression - Trim diff input to 20 KB to prevent Ollama token overflow - Add --max-time 120 to curl to prevent workflow hanging indefinitely --- .gitea/workflows/pr-review.yml | 4 ++-- src-tauri/tauri.conf.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index e0550097..02a0316a 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -35,7 +35,7 @@ jobs: env: OLLAMA_URL: http://172.0.1.42:11434 run: | - DIFF_CONTENT=$(cat /tmp/pr_diff.txt) + DIFF_CONTENT=$(head -c 20000 /tmp/pr_diff.txt) PR_TITLE="${{ github.event.pull_request.title }}" PROMPT="Analyze the following code changes for correctness, security issues, and best practices. PR Title: ${PR_TITLE}\n\nDiff:\n${DIFF_CONTENT}\n\nProvide a review with: 1) Summary, 2) Bugs/errors, 3) Security issues, 4) Best practices. Give specific comments with suggested fixes." BODY=$(jq -n \ @@ -44,7 +44,7 @@ jobs: '{model: $model, messages: [{role: "user", content: $content}], stream: false}') echo "Request body length: ${#BODY} bytes" echo "Calling Ollama API..." - HTTP_CODE=$(curl -s -o /tmp/ollama_response.json -w "%{http_code}" \ + HTTP_CODE=$(curl -s --max-time 120 -o /tmp/ollama_response.json -w "%{http_code}" \ -X POST "$OLLAMA_URL/api/chat" \ -H "Content-Type: application/json" \ -d "$BODY") diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index ebc18a9b..0141b39b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -1,6 +1,6 @@ { "productName": "Troubleshooting and RCA Assistant", - "version": "0.2.49", + "version": "0.2.50", "identifier": "com.trcaa.app", "build": { "frontendDist": "../dist", From 61cb5db63ea089b73c532590f47f84ce5f7a186e Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 16:32:15 -0500 Subject: [PATCH 13/19] fix: harden pr-review workflow and sync versions to 0.2.50 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Workflow changes: - Switch Ollama to https://ollama-ui.tftsr.com/ollama/v1 (OpenAI-compat) with OLLAMA_API_KEY secret — removes hardcoded internal IP - Update endpoint to /chat/completions and response parsing to .choices[0].message.content for OpenAI-compat format - Add concurrency block to prevent racing on same PR number - Add shell: bash + set -euo pipefail to all steps - Add TF_TOKEN presence validation before posting review - Add --max-time 30 and HTTP status check to comment POST curl - Redact common secret patterns from diff before sending to Ollama - Add binary diff warning via grep for "^Binary files" - Add UTC timestamps to Ollama call and review post log lines - Add always-run Cleanup step to remove /tmp artifacts Version consistency: - Sync Cargo.toml and package.json from 0.1.0 to 0.2.50 to match tauri.conf.json --- .gitea/workflows/pr-review.yml | 53 +++++++++++++++++++++++++++------- package.json | 2 +- src-tauri/Cargo.toml | 2 +- 3 files changed, 45 insertions(+), 12 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 02a0316a..e82acf21 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -4,6 +4,10 @@ on: pull_request: types: [opened, synchronize, reopened] +concurrency: + group: pr-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + jobs: review: runs-on: ubuntu-latest @@ -11,12 +15,15 @@ jobs: image: ubuntu:22.04 steps: - name: Install dependencies + shell: bash run: | - set -eux + set -euo pipefail apt-get update -qq && apt-get install -y -qq git curl jq - name: Checkout code + shell: bash run: | + set -euo pipefail git init git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git git fetch --depth=1 origin ${{ github.head_ref }} @@ -24,7 +31,9 @@ jobs: - name: Get PR diff id: diff + shell: bash run: | + set -euo pipefail git fetch origin ${{ github.base_ref }} git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr_diff.txt echo "diff_size=$(wc -l < /tmp/pr_diff.txt)" >> $GITHUB_OUTPUT @@ -33,30 +42,35 @@ jobs: if: steps.diff.outputs.diff_size > '0' shell: bash env: - OLLAMA_URL: http://172.0.1.42:11434 + OLLAMA_URL: https://ollama-ui.tftsr.com/ollama/v1 + OLLAMA_API_KEY: ${{ secrets.OLLAMA_API_KEY }} run: | - DIFF_CONTENT=$(head -c 20000 /tmp/pr_diff.txt) + set -euo pipefail + if grep -q "^Binary files" /tmp/pr_diff.txt; then + echo "WARNING: Binary file changes detected — they will be excluded from analysis" + fi + DIFF_CONTENT=$(head -c 20000 /tmp/pr_diff.txt \ + | sed -E 's/(password|token|secret|api_key|private_key)[[:space:]]*[=:][[:space:]]*\S+/\1=[REDACTED]/gi') PR_TITLE="${{ github.event.pull_request.title }}" PROMPT="Analyze the following code changes for correctness, security issues, and best practices. PR Title: ${PR_TITLE}\n\nDiff:\n${DIFF_CONTENT}\n\nProvide a review with: 1) Summary, 2) Bugs/errors, 3) Security issues, 4) Best practices. Give specific comments with suggested fixes." BODY=$(jq -n \ --arg model "qwen3-coder-next:latest" \ --arg content "$PROMPT" \ '{model: $model, messages: [{role: "user", content: $content}], stream: false}') - echo "Request body length: ${#BODY} bytes" - echo "Calling Ollama API..." + echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] PR #${{ github.event.pull_request.number }} - Calling Ollama API (${#BODY} bytes)..." HTTP_CODE=$(curl -s --max-time 120 -o /tmp/ollama_response.json -w "%{http_code}" \ - -X POST "$OLLAMA_URL/api/chat" \ + -X POST "$OLLAMA_URL/chat/completions" \ + -H "Authorization: Bearer $OLLAMA_API_KEY" \ -H "Content-Type: application/json" \ -d "$BODY") echo "HTTP status: $HTTP_CODE" echo "Response file size: $(wc -c < /tmp/ollama_response.json) bytes" - echo "Response body (jq pretty-print or raw):" jq . /tmp/ollama_response.json 2>/dev/null || cat /tmp/ollama_response.json if [ "$HTTP_CODE" != "200" ]; then echo "ERROR: Ollama returned HTTP $HTTP_CODE" exit 1 fi - REVIEW=$(jq -r '.message.content // empty' /tmp/ollama_response.json) + REVIEW=$(jq -r '.choices[0].message.content // empty' /tmp/ollama_response.json) if [ -z "$REVIEW" ]; then echo "ERROR: No content in Ollama response" exit 1 @@ -65,19 +79,38 @@ jobs: - name: Post review comment if: success() + shell: bash env: TF_TOKEN: ${{ secrets.TFT_GITEA_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} run: | + set -euo pipefail + if [ -z "${TF_TOKEN:-}" ]; then + echo "ERROR: TFT_GITEA_TOKEN secret is not set" + exit 1 + fi if [ -f "/tmp/pr_review.txt" ] && [ -s "/tmp/pr_review.txt" ]; then REVIEW_BODY=$(head -c 65536 /tmp/pr_review.txt) BODY=$(jq -n \ --arg body "🤖 Automated PR Review:\n\n${REVIEW_BODY}\n\n---\n*this is an automated review from Ollama*" \ '{body: $body, event: "COMMENT"}') - curl -s -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ + HTTP_CODE=$(curl -s --max-time 30 \ + -o /tmp/review_post_response.json -w "%{http_code}" \ + -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ -H "Authorization: token $TF_TOKEN" \ -H "Content-Type: application/json" \ - -d "$BODY" + -d "$BODY") + echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] Post review HTTP status: $HTTP_CODE" + if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ]; then + echo "ERROR: Failed to post review (HTTP $HTTP_CODE)" + cat /tmp/review_post_response.json + exit 1 + fi else echo "No review to post" fi + + - name: Cleanup + if: always() + shell: bash + run: rm -f /tmp/pr_diff.txt /tmp/ollama_response.json /tmp/pr_review.txt /tmp/review_post_response.json diff --git a/package.json b/package.json index 5679030b..63d46fe2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tftsr", "private": true, - "version": "0.1.0", + "version": "0.2.50", "type": "module", "scripts": { "dev": "vite", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 6827b82a..aa83b3c3 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "trcaa" -version = "0.1.0" +version = "0.2.50" edition = "2021" [lib] From 2d0f95e9db79fb3ed6bdff7bbe2899e020005639 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 16:39:43 -0500 Subject: [PATCH 14/19] fix: configure container DNS to resolve ollama-ui.tftsr.com --- .gitea/workflows/pr-review.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index e82acf21..ff520e8c 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -13,6 +13,7 @@ jobs: runs-on: ubuntu-latest container: image: ubuntu:22.04 + options: --dns 172.0.0.29 --dns 8.8.8.8 --dns 1.1.1.1 steps: - name: Install dependencies shell: bash From 1a4c6df6c9dfd7e518bc83c767879c9988020460 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 16:50:12 -0500 Subject: [PATCH 15/19] =?UTF-8?q?fix:=20harden=20pr-review=20workflow=20?= =?UTF-8?q?=E2=80=94=20URLs,=20DNS,=20correctness=20and=20reliability?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Security: - Replace http://172.0.0.29:3000 git remote with https://gogs.tftsr.com - Replace http://172.0.0.29:3000 Gitea API URL with https://gogs.tftsr.com - Remove internal 172.0.0.29 from container DNS (keep 8.8.8.8, 1.1.1.1) - Move PR_TITLE and PR_NUMBER to env vars to prevent shell injection Correctness: - Fix diff_size comparison from lexicographic > '0' to != '0' - Strip leading whitespace from wc -l output via tr -d ' ' - Switch diff truncation from head -c 20000 to head -n 500 (line-safe) - Add jq empty validation before parsing Ollama response Reliability: - Add --connect-timeout 30 and --retry 3 --retry-delay 5 to Ollama curl - Add --connect-timeout 10 to review POST curl - Change Post review comment to if: always() so it runs on analysis failure - Post explicit failure comment when analysis produces no output --- .gitea/workflows/pr-review.yml | 56 ++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 23 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index ff520e8c..58c9afe2 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest container: image: ubuntu:22.04 - options: --dns 172.0.0.29 --dns 8.8.8.8 --dns 1.1.1.1 + options: --dns 8.8.8.8 --dns 1.1.1.1 steps: - name: Install dependencies shell: bash @@ -26,7 +26,7 @@ jobs: run: | set -euo pipefail git init - git remote add origin http://172.0.0.29:3000/sarman/tftsr-devops_investigation.git + git remote add origin https://gogs.tftsr.com/sarman/tftsr-devops_investigation.git git fetch --depth=1 origin ${{ github.head_ref }} git checkout FETCH_HEAD @@ -37,36 +37,45 @@ jobs: set -euo pipefail git fetch origin ${{ github.base_ref }} git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr_diff.txt - echo "diff_size=$(wc -l < /tmp/pr_diff.txt)" >> $GITHUB_OUTPUT + echo "diff_size=$(wc -l < /tmp/pr_diff.txt | tr -d ' ')" >> $GITHUB_OUTPUT - name: Analyze with Ollama - if: steps.diff.outputs.diff_size > '0' + id: analyze + if: steps.diff.outputs.diff_size != '0' shell: bash env: OLLAMA_URL: https://ollama-ui.tftsr.com/ollama/v1 OLLAMA_API_KEY: ${{ secrets.OLLAMA_API_KEY }} + PR_TITLE: ${{ github.event.pull_request.title }} + PR_NUMBER: ${{ github.event.pull_request.number }} run: | set -euo pipefail if grep -q "^Binary files" /tmp/pr_diff.txt; then echo "WARNING: Binary file changes detected — they will be excluded from analysis" fi - DIFF_CONTENT=$(head -c 20000 /tmp/pr_diff.txt \ + DIFF_CONTENT=$(head -n 500 /tmp/pr_diff.txt \ | sed -E 's/(password|token|secret|api_key|private_key)[[:space:]]*[=:][[:space:]]*\S+/\1=[REDACTED]/gi') - PR_TITLE="${{ github.event.pull_request.title }}" PROMPT="Analyze the following code changes for correctness, security issues, and best practices. PR Title: ${PR_TITLE}\n\nDiff:\n${DIFF_CONTENT}\n\nProvide a review with: 1) Summary, 2) Bugs/errors, 3) Security issues, 4) Best practices. Give specific comments with suggested fixes." BODY=$(jq -n \ --arg model "qwen3-coder-next:latest" \ --arg content "$PROMPT" \ '{model: $model, messages: [{role: "user", content: $content}], stream: false}') - echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] PR #${{ github.event.pull_request.number }} - Calling Ollama API (${#BODY} bytes)..." - HTTP_CODE=$(curl -s --max-time 120 -o /tmp/ollama_response.json -w "%{http_code}" \ + echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] PR #${PR_NUMBER} - Calling Ollama API (${#BODY} bytes)..." + HTTP_CODE=$(curl -s --max-time 120 --connect-timeout 30 \ + --retry 3 --retry-delay 5 --retry-all-errors \ + -o /tmp/ollama_response.json -w "%{http_code}" \ -X POST "$OLLAMA_URL/chat/completions" \ -H "Authorization: Bearer $OLLAMA_API_KEY" \ -H "Content-Type: application/json" \ -d "$BODY") echo "HTTP status: $HTTP_CODE" echo "Response file size: $(wc -c < /tmp/ollama_response.json) bytes" - jq . /tmp/ollama_response.json 2>/dev/null || cat /tmp/ollama_response.json + if ! jq empty /tmp/ollama_response.json 2>/dev/null; then + echo "ERROR: Invalid JSON response from Ollama" + cat /tmp/ollama_response.json + exit 1 + fi + jq . /tmp/ollama_response.json if [ "$HTTP_CODE" != "200" ]; then echo "ERROR: Ollama returned HTTP $HTTP_CODE" exit 1 @@ -79,7 +88,7 @@ jobs: echo "$REVIEW" > /tmp/pr_review.txt - name: Post review comment - if: success() + if: always() && steps.diff.outputs.diff_size != '0' shell: bash env: TF_TOKEN: ${{ secrets.TFT_GITEA_TOKEN }} @@ -95,20 +104,21 @@ jobs: BODY=$(jq -n \ --arg body "🤖 Automated PR Review:\n\n${REVIEW_BODY}\n\n---\n*this is an automated review from Ollama*" \ '{body: $body, event: "COMMENT"}') - HTTP_CODE=$(curl -s --max-time 30 \ - -o /tmp/review_post_response.json -w "%{http_code}" \ - -X POST "http://172.0.0.29:3000/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ - -H "Authorization: token $TF_TOKEN" \ - -H "Content-Type: application/json" \ - -d "$BODY") - echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] Post review HTTP status: $HTTP_CODE" - if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ]; then - echo "ERROR: Failed to post review (HTTP $HTTP_CODE)" - cat /tmp/review_post_response.json - exit 1 - fi else - echo "No review to post" + BODY=$(jq -n \ + '{body: "⚠️ Automated PR Review could not be completed — Ollama analysis failed or produced no output.", event: "COMMENT"}') + fi + HTTP_CODE=$(curl -s --max-time 30 --connect-timeout 10 \ + -o /tmp/review_post_response.json -w "%{http_code}" \ + -X POST "https://gogs.tftsr.com/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ + -H "Authorization: token $TF_TOKEN" \ + -H "Content-Type: application/json" \ + -d "$BODY") + echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] Post review HTTP status: $HTTP_CODE" + if [ "$HTTP_CODE" != "200" ] && [ "$HTTP_CODE" != "201" ]; then + echo "ERROR: Failed to post review (HTTP $HTTP_CODE)" + cat /tmp/review_post_response.json + exit 1 fi - name: Cleanup From 82aae00858801cc6961ffa11b5b201a7b5deeaa8 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 17:02:39 -0500 Subject: [PATCH 16/19] fix: resolve AI review false positives and address high/medium issues Root cause of false-positive "critical" errors: - sed pattern was matching api_key/token within YAML variable names (e.g. OLLAMA_API_KEY:) and redacting the ${{ secrets.X }} value, producing mangled syntax that confused the AI reviewer - Fix: use [^$[:space:]] to skip values starting with $ (template expressions and shell variable references) Other fixes: - Replace --retry-all-errors with --retry-connrefused --retry-max-time 120 to avoid wasting retries on unrecoverable 4xx errors - Check HTTP_CODE before jq validation so error messages are meaningful - Add permissions: pull-requests: write to job - Add edited to pull_request.types so title changes trigger re-review - Change git diff .. to git diff ... (three-dot merge-base diff) - Replace hardcoded server/repo URLs with github.server_url and github.repository context variables (portability) - Log review length before posting to detect truncation --- .gitea/workflows/pr-review.yml | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 58c9afe2..4802cbad 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -2,7 +2,7 @@ name: PR Review Automation on: pull_request: - types: [opened, synchronize, reopened] + types: [opened, synchronize, reopened, edited] concurrency: group: pr-review-${{ github.event.pull_request.number }} @@ -11,6 +11,8 @@ concurrency: jobs: review: runs-on: ubuntu-latest + permissions: + pull-requests: write container: image: ubuntu:22.04 options: --dns 8.8.8.8 --dns 1.1.1.1 @@ -23,10 +25,13 @@ jobs: - name: Checkout code shell: bash + env: + SERVER_URL: ${{ github.server_url }} + REPOSITORY: ${{ github.repository }} run: | set -euo pipefail git init - git remote add origin https://gogs.tftsr.com/sarman/tftsr-devops_investigation.git + git remote add origin "${SERVER_URL}/${REPOSITORY}.git" git fetch --depth=1 origin ${{ github.head_ref }} git checkout FETCH_HEAD @@ -36,7 +41,7 @@ jobs: run: | set -euo pipefail git fetch origin ${{ github.base_ref }} - git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr_diff.txt + git diff origin/${{ github.base_ref }}...HEAD > /tmp/pr_diff.txt echo "diff_size=$(wc -l < /tmp/pr_diff.txt | tr -d ' ')" >> $GITHUB_OUTPUT - name: Analyze with Ollama @@ -54,7 +59,7 @@ jobs: echo "WARNING: Binary file changes detected — they will be excluded from analysis" fi DIFF_CONTENT=$(head -n 500 /tmp/pr_diff.txt \ - | sed -E 's/(password|token|secret|api_key|private_key)[[:space:]]*[=:][[:space:]]*\S+/\1=[REDACTED]/gi') + | sed -E 's/(password|token|secret|api_key|private_key)[[:space:]]*[=:][[:space:]]+([^$[:space:]][^[:space:]]*)/\1=[REDACTED]/gi') PROMPT="Analyze the following code changes for correctness, security issues, and best practices. PR Title: ${PR_TITLE}\n\nDiff:\n${DIFF_CONTENT}\n\nProvide a review with: 1) Summary, 2) Bugs/errors, 3) Security issues, 4) Best practices. Give specific comments with suggested fixes." BODY=$(jq -n \ --arg model "qwen3-coder-next:latest" \ @@ -62,7 +67,7 @@ jobs: '{model: $model, messages: [{role: "user", content: $content}], stream: false}') echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] PR #${PR_NUMBER} - Calling Ollama API (${#BODY} bytes)..." HTTP_CODE=$(curl -s --max-time 120 --connect-timeout 30 \ - --retry 3 --retry-delay 5 --retry-all-errors \ + --retry 3 --retry-delay 5 --retry-connrefused --retry-max-time 120 \ -o /tmp/ollama_response.json -w "%{http_code}" \ -X POST "$OLLAMA_URL/chat/completions" \ -H "Authorization: Bearer $OLLAMA_API_KEY" \ @@ -70,21 +75,23 @@ jobs: -d "$BODY") echo "HTTP status: $HTTP_CODE" echo "Response file size: $(wc -c < /tmp/ollama_response.json) bytes" + if [ "$HTTP_CODE" != "200" ]; then + echo "ERROR: Ollama returned HTTP $HTTP_CODE" + cat /tmp/ollama_response.json + exit 1 + fi if ! jq empty /tmp/ollama_response.json 2>/dev/null; then echo "ERROR: Invalid JSON response from Ollama" cat /tmp/ollama_response.json exit 1 fi jq . /tmp/ollama_response.json - if [ "$HTTP_CODE" != "200" ]; then - echo "ERROR: Ollama returned HTTP $HTTP_CODE" - exit 1 - fi REVIEW=$(jq -r '.choices[0].message.content // empty' /tmp/ollama_response.json) if [ -z "$REVIEW" ]; then echo "ERROR: No content in Ollama response" exit 1 fi + echo "Review length: ${#REVIEW} chars" echo "$REVIEW" > /tmp/pr_review.txt - name: Post review comment @@ -93,6 +100,8 @@ jobs: env: TF_TOKEN: ${{ secrets.TFT_GITEA_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} + SERVER_URL: ${{ github.server_url }} + REPOSITORY: ${{ github.repository }} run: | set -euo pipefail if [ -z "${TF_TOKEN:-}" ]; then @@ -110,7 +119,7 @@ jobs: fi HTTP_CODE=$(curl -s --max-time 30 --connect-timeout 10 \ -o /tmp/review_post_response.json -w "%{http_code}" \ - -X POST "https://gogs.tftsr.com/api/v1/repos/sarman/tftsr-devops_investigation/pulls/$PR_NUMBER/reviews" \ + -X POST "${SERVER_URL}/api/v1/repos/${REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ -H "Authorization: token $TF_TOKEN" \ -H "Content-Type: application/json" \ -d "$BODY") From 47b2e824e0a9ab9bca61d4bf6d6e9b2d474677ef Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 17:08:19 -0500 Subject: [PATCH 17/19] fix: replace github.server_url with hardcoded gogs.tftsr.com for container access --- .gitea/workflows/pr-review.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 4802cbad..e4636487 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -26,12 +26,11 @@ jobs: - name: Checkout code shell: bash env: - SERVER_URL: ${{ github.server_url }} REPOSITORY: ${{ github.repository }} run: | set -euo pipefail git init - git remote add origin "${SERVER_URL}/${REPOSITORY}.git" + git remote add origin "https://gogs.tftsr.com/${REPOSITORY}.git" git fetch --depth=1 origin ${{ github.head_ref }} git checkout FETCH_HEAD @@ -100,7 +99,6 @@ jobs: env: TF_TOKEN: ${{ secrets.TFT_GITEA_TOKEN }} PR_NUMBER: ${{ github.event.pull_request.number }} - SERVER_URL: ${{ github.server_url }} REPOSITORY: ${{ github.repository }} run: | set -euo pipefail @@ -119,7 +117,7 @@ jobs: fi HTTP_CODE=$(curl -s --max-time 30 --connect-timeout 10 \ -o /tmp/review_post_response.json -w "%{http_code}" \ - -X POST "${SERVER_URL}/api/v1/repos/${REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ + -X POST "https://gogs.tftsr.com/api/v1/repos/${REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ -H "Authorization: token $TF_TOKEN" \ -H "Content-Type: application/json" \ -d "$BODY") From 144a4551f2e32691a94ef2186b33b50cf0d74bf7 Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 17:11:54 -0500 Subject: [PATCH 18/19] =?UTF-8?q?fix:=20revert=20to=20two-dot=20diff=20?= =?UTF-8?q?=E2=80=94=20three-dot=20requires=20merge=20base=20unavailable?= =?UTF-8?q?=20in=20shallow=20clone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/pr-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index e4636487..39544c94 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -40,7 +40,7 @@ jobs: run: | set -euo pipefail git fetch origin ${{ github.base_ref }} - git diff origin/${{ github.base_ref }}...HEAD > /tmp/pr_diff.txt + git diff origin/${{ github.base_ref }}..HEAD > /tmp/pr_diff.txt echo "diff_size=$(wc -l < /tmp/pr_diff.txt | tr -d ' ')" >> $GITHUB_OUTPUT - name: Analyze with Ollama From 181b9ef73481ba75e083aa31f571e0ea08012e6a Mon Sep 17 00:00:00 2001 From: Shaun Arman Date: Sun, 12 Apr 2026 18:03:17 -0500 Subject: [PATCH 19/19] =?UTF-8?q?fix:=20harden=20pr-review=20workflow=20?= =?UTF-8?q?=E2=80=94=20secret=20redaction,=20log=20safety,=20auth=20header?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace flawed sed-based redaction with grep -v line-removal covering JS/YAML assignments, Authorization headers, AWS keys (AKIA…), Slack tokens (xox…), GitHub tokens (gh[opsu]_…), URLs with embedded credentials, and long Base64 strings - Add -c flag to jq -n when building Ollama request body (compact JSON) - Remove jq . full response dump to prevent LLM-echoed secrets in logs - Change Gitea API Authorization header from `token` to `Bearer` --- .gitea/workflows/pr-review.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitea/workflows/pr-review.yml b/.gitea/workflows/pr-review.yml index 39544c94..e72f3c4c 100644 --- a/.gitea/workflows/pr-review.yml +++ b/.gitea/workflows/pr-review.yml @@ -58,9 +58,10 @@ jobs: echo "WARNING: Binary file changes detected — they will be excluded from analysis" fi DIFF_CONTENT=$(head -n 500 /tmp/pr_diff.txt \ - | sed -E 's/(password|token|secret|api_key|private_key)[[:space:]]*[=:][[:space:]]+([^$[:space:]][^[:space:]]*)/\1=[REDACTED]/gi') + | grep -v -E '^[+-].*(password[[:space:]]*[=:"'"'"']|token[[:space:]]*[=:"'"'"']|secret[[:space:]]*[=:"'"'"']|api_key[[:space:]]*[=:"'"'"']|private_key[[:space:]]*[=:"'"'"']|Authorization:[[:space:]]|AKIA[A-Z0-9]{16}|xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}|gh[opsu]_[A-Za-z0-9_]{36,}|https?://[^@[:space:]]+:[^@[:space:]]+@)' \ + | grep -v -E '^[+-].*[A-Za-z0-9+/]{40,}={0,2}([^A-Za-z0-9+/=]|$)') PROMPT="Analyze the following code changes for correctness, security issues, and best practices. PR Title: ${PR_TITLE}\n\nDiff:\n${DIFF_CONTENT}\n\nProvide a review with: 1) Summary, 2) Bugs/errors, 3) Security issues, 4) Best practices. Give specific comments with suggested fixes." - BODY=$(jq -n \ + BODY=$(jq -cn \ --arg model "qwen3-coder-next:latest" \ --arg content "$PROMPT" \ '{model: $model, messages: [{role: "user", content: $content}], stream: false}') @@ -84,7 +85,6 @@ jobs: cat /tmp/ollama_response.json exit 1 fi - jq . /tmp/ollama_response.json REVIEW=$(jq -r '.choices[0].message.content // empty' /tmp/ollama_response.json) if [ -z "$REVIEW" ]; then echo "ERROR: No content in Ollama response" @@ -118,7 +118,7 @@ jobs: HTTP_CODE=$(curl -s --max-time 30 --connect-timeout 10 \ -o /tmp/review_post_response.json -w "%{http_code}" \ -X POST "https://gogs.tftsr.com/api/v1/repos/${REPOSITORY}/pulls/${PR_NUMBER}/reviews" \ - -H "Authorization: token $TF_TOKEN" \ + -H "Authorization: Bearer $TF_TOKEN" \ -H "Content-Type: application/json" \ -d "$BODY") echo "[$(date -u +%Y-%m-%dT%H:%M:%SZ)] Post review HTTP status: $HTTP_CODE"