Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
4001fe5
feat: add code-review task (initial commit)
DevelopmentCats Dec 4, 2025
c6b85ec
temp(workflows): update code-review workflow to use shared secrets fo…
DevelopmentCats Dec 4, 2025
2fea873
refactor: enhance code-review workflow with improved GitHub authentic…
DevelopmentCats Dec 4, 2025
84ccad8
chore: enhance code-review workflow with URL validation and improved …
DevelopmentCats Dec 4, 2025
d94e9df
refactor: update code-review workflow to enhance review phases and su…
DevelopmentCats Dec 4, 2025
724e8b1
fix: security vuln in linting
DevelopmentCats Dec 9, 2025
96e6afd
Merge branch 'main' into cat/code-review-task
DevelopmentCats Dec 9, 2025
647b610
Merge branch 'main' into cat/code-review-task
DevelopmentCats Dec 10, 2025
c7c96e9
Merge branch 'main' into cat/code-review-task
DevelopmentCats Dec 10, 2025
c5fe6c5
chore(workflows): add security instructions for PR content review
DevelopmentCats Dec 10, 2025
96c66d6
Merge branch 'main' into cat/code-review-task
DevelopmentCats Dec 10, 2025
62bf201
chore(workflows): streamline code review process and enhance security…
DevelopmentCats Dec 11, 2025
ca4dd32
Merge branch 'main' into cat/code-review-task
DevelopmentCats Dec 11, 2025
dcaedbd
chore(workflows): update code review prompt for critical suggestion i…
DevelopmentCats Dec 11, 2025
ff8d037
chore(workflows): enhance code review instructions for suggestion for…
DevelopmentCats Dec 11, 2025
a26b00f
chore(workflows): rewrite prompt
DevelopmentCats Dec 11, 2025
595278f
chore(workflows): update code review guidelines to include Coder-spec…
DevelopmentCats Dec 11, 2025
50dc5c0
chore(workflows): refine code review guidelines to emphasize actionab…
DevelopmentCats Dec 11, 2025
8ab152f
chore(workflows): update code review guidelines to address additional…
DevelopmentCats Dec 11, 2025
3d1dd32
chore(workflows): clarify code review guidelines regarding the use of…
DevelopmentCats Dec 11, 2025
5d9492b
chore: apply code-review suggestion for gnu specific syntax
DevelopmentCats Dec 11, 2025
32e54e8
chore(workflows): update code review comments to include Coder Tasks …
DevelopmentCats Dec 11, 2025
7ba4bdf
chore(workflows): simplify code review process by updating commit SHA…
DevelopmentCats Dec 11, 2025
f0eaa46
chore(workflows): improve portability of PR number extraction by repl…
DevelopmentCats Dec 11, 2025
d6cdd8f
Merge branch 'main' into cat/code-review-task
DevelopmentCats Dec 12, 2025
50281ce
chore(workflows): enhance code review instructions with clearer guide…
DevelopmentCats Dec 12, 2025
fb144d5
chore(workflows): update code review guidelines to enhance clarity an…
DevelopmentCats Dec 12, 2025
9a5f70f
chore(workflows): improve error handling and clarify set -u behavior …
DevelopmentCats Dec 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
382 changes: 382 additions & 0 deletions .github/workflows/code-review.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,382 @@
# This workflow performs AI-powered code review on PRs.
# It creates a Coder Task that uses AI to analyze PR changes,
# review code quality, identify issues, and post committable suggestions.
#
# The AI agent posts a single review with inline comments using GitHub's
# native suggestion syntax, allowing one-click commits of suggested changes.
#
# Triggered by: Adding the "code-review" label to a PR, or manual dispatch.
#
# Required secrets:
# - CODE_REVIEW_CODER_URL: URL of your Coder deployment
# - CODE_REVIEW_CODER_SESSION_TOKEN: Session token for Coder API

name: AI Code Review

on:
pull_request:
types:
- labeled
workflow_dispatch:
inputs:
pr_url:
description: "Pull Request URL to review"
required: true
type: string
template_preset:
description: "Template preset to use"
required: false
default: ""
type: string

jobs:
code-review:
name: AI Code Review
runs-on: ubuntu-latest
if: |
(github.event.label.name == 'code-review' || github.event_name == 'workflow_dispatch') &&
(github.event.pull_request.draft == false || github.event_name == 'workflow_dispatch')
timeout-minutes: 30
env:
CODER_URL: ${{ secrets.CODE_REVIEW_CODER_URL }}
CODER_SESSION_TOKEN: ${{ secrets.CODE_REVIEW_CODER_SESSION_TOKEN }}
permissions:
contents: read # Read repository contents and PR diff
pull-requests: write # Post review comments and suggestions
actions: write # Create workflow summaries

steps:
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing error handling if the secrets are not set. The workflow will fail silently or with unclear errors if CODE_REVIEW_CODER_URL or CODE_REVIEW_CODER_SESSION_TOKEN are not configured. Consider adding a validation step:

Suggested change
steps:
steps:
- name: Validate required secrets
run: |
if [[ -z "${{ secrets.CODE_REVIEW_CODER_URL }}" ]]; then
echo "::error::CODE_REVIEW_CODER_URL secret is not set"
exit 1
fi
if [[ -z "${{ secrets.CODE_REVIEW_CODER_SESSION_TOKEN }}" ]]; then
echo "::error::CODE_REVIEW_CODER_SESSION_TOKEN secret is not set"
exit 1
fi
- name: Determine PR Context
Suggested change
steps:
steps:
- name: Validate required secrets
run: |
if [[ -z "${{ secrets.CODE_REVIEW_CODER_URL }}" ]]; then
echo "::error::CODE_REVIEW_CODER_URL secret is not set"
exit 1
fi
if [[ -z "${{ secrets.CODE_REVIEW_CODER_SESSION_TOKEN }}" ]]; then
echo "::error::CODE_REVIEW_CODER_SESSION_TOKEN secret is not set"
exit 1
fi

Copilot uses AI. Check for mistakes.
- name: Determine PR Context
id: determine-context
env:
GITHUB_ACTOR: ${{ github.actor }}
GITHUB_EVENT_NAME: ${{ github.event_name }}
GITHUB_EVENT_PR_HTML_URL: ${{ github.event.pull_request.html_url }}
GITHUB_EVENT_PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_EVENT_SENDER_ID: ${{ github.event.sender.id }}
GITHUB_EVENT_SENDER_LOGIN: ${{ github.event.sender.login }}
INPUTS_PR_URL: ${{ inputs.pr_url }}
INPUTS_TEMPLATE_PRESET: ${{ inputs.template_preset || '' }}
GH_TOKEN: ${{ github.token }}
run: |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing error handling directives. Shell scripts should fail fast on errors to prevent cascading failures.

Without set -euo pipefail, if any command fails (like accessing an undefined variable), the script continues executing, potentially with invalid state.

Suggested change
run: |
run: |
set -euo pipefail
echo "Using template preset: ${INPUTS_TEMPLATE_PRESET}"

echo "Using template preset: ${INPUTS_TEMPLATE_PRESET}"
echo "template_preset=${INPUTS_TEMPLATE_PRESET}" >> "${GITHUB_OUTPUT}"

# For workflow_dispatch, use the provided PR URL
if [[ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]]; then
if ! GITHUB_USER_ID=$(gh api "users/${GITHUB_ACTOR}" --jq '.id'); then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: The GitHub API call for user ID lacks error context and doesn't validate the response.

If the API returns an empty or invalid response, GITHUB_USER_ID will be set to an empty string, which could cause issues downstream. The error message is good, but we should validate the result.

Suggested change
if ! GITHUB_USER_ID=$(gh api "users/${GITHUB_ACTOR}" --jq '.id'); then
if ! GITHUB_USER_ID=$(gh api "users/${GITHUB_ACTOR}" --jq '.id') || [[ -z "${GITHUB_USER_ID}" ]]; then
echo "::error::Failed to get GitHub user ID for actor ${GITHUB_ACTOR}"
exit 1
fi

echo "::error::Failed to get GitHub user ID for actor ${GITHUB_ACTOR}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Error message could be more helpful by suggesting what the user should check.

Suggested change
echo "::error::Failed to get GitHub user ID for actor ${GITHUB_ACTOR}"
echo "::error::Failed to get GitHub user ID for actor ${GITHUB_ACTOR}. Verify the user exists and has access to this repository."

exit 1
fi
echo "Using workflow_dispatch actor: ${GITHUB_ACTOR} (ID: ${GITHUB_USER_ID})"
echo "github_user_id=${GITHUB_USER_ID}" >> "${GITHUB_OUTPUT}"
echo "github_username=${GITHUB_ACTOR}" >> "${GITHUB_OUTPUT}"

echo "Using PR URL: ${INPUTS_PR_URL}"
# Convert /pull/ to /issues/ for create-task-action compatibility
ISSUE_URL="${INPUTS_PR_URL/\/pull\//\/issues\/}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Variable should be quoted to safely handle URLs with special characters or spaces.

While URLs shouldn't have spaces, defensive quoting is a shell scripting best practice.

Suggested change
ISSUE_URL="${INPUTS_PR_URL/\/pull\//\/issues\/}"
ISSUE_URL="${INPUTS_PR_URL/\/pull\//\/issues\/}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: Variable should be quoted to safely handle special characters in URLs.

Suggested change
ISSUE_URL="${INPUTS_PR_URL/\/pull\//\/issues\/}"
ISSUE_URL="${INPUTS_PR_URL/\/pull\//\/issues\/}"

echo "pr_url=${ISSUE_URL}" >> "${GITHUB_OUTPUT}"

# Extract PR number from URL for later use
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error handling for the gh api call is good, but the subsequent steps (lines 75-82) don't have similar error handling. If INPUTS_PR_URL is malformed or the PR number extraction fails, the workflow will continue with empty values. Consider adding validation:

Suggested change
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
echo "Using PR URL: ${INPUTS_PR_URL}"
# Convert /pull/ to /issues/ for create-task-action compatibility
ISSUE_URL="${INPUTS_PR_URL/\/pull\//\/issues\/}"
echo "pr_url=${ISSUE_URL}" >> "${GITHUB_OUTPUT}"
# Extract PR number from URL for later use
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | sed -n 's/.*\/pull\/\([0-9]*\).*/\1/p')
if [[ -z "${PR_NUMBER}" ]]; then
echo "::error::Failed to extract PR number from URL: ${INPUTS_PR_URL}"
exit 1
fi
echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
Suggested change
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
if [[ -z "${PR_NUMBER}" ]]; then
echo "::error::Failed to extract PR number from URL: ${INPUTS_PR_URL}"
exit 1
fi

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security: Potential command injection via unvalidated user input in regex. The INPUTS_PR_URL comes directly from user input and is used in a grep pattern without validation.

Recommendation: Validate URL format before extraction to prevent unexpected behavior with malformed URLs.

Suggested change
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
# Validate PR URL format before processing
if [[ ! "${INPUTS_PR_URL}" =~ ^https://github\.com/[^/]+/[^/]+/pull/[0-9]+$ ]]; then
echo "::error::Invalid PR URL format: ${INPUTS_PR_URL}. Expected format: https://github.com/owner/repo/pull/NUMBER"
exit 1
fi
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Using grep -oP with Perl regex is not portable and may fail on macOS runners or systems without GNU grep.

The -P flag (Perl regex) is a GNU extension not available in BSD grep (default on macOS). While this workflow runs on ubuntu-latest, it's better to use portable alternatives for maintainability.

Suggested change
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
# Extract PR number from URL
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | sed -n 's|.*/pull/\([0-9]*\)$|\1|p')
echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: [NITPICK] grep -oP uses Perl regex which is GNU-specific. While it works on GitHub Actions (Ubuntu), sed is more portable across all Unix systems.

This matches the portability pattern mentioned in the workflow's own examples (lines 221-226).

Suggested change
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | sed -n 's|.*/pull/\([0-9]*\)$|\1|p')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: [NITPICK] grep -oP uses Perl regex which is GNU-specific. While this works on GitHub Actions runners (ubuntu-latest), using sed would be more portable across all Unix systems.

The existing regex validation at line 79 already ensures the URL format is correct, so the extraction will succeed.

Suggested change
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | sed -n 's|.*/pull/\([0-9]*\)$|\1|p')

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: [NITPICK] grep -oP uses Perl-compatible regex which is GNU-specific and not available on all systems (e.g., macOS/BSD grep). While GitHub Actions runners use Ubuntu and this will work fine, sed is more portable.

Suggested change
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | grep -oP '(?<=pull/)\d+')
PR_NUMBER=$(echo "${INPUTS_PR_URL}" | sed -n 's|.*/pull/\([0-9]\+\)$|\1|p')

echo "pr_number=${PR_NUMBER}" >> "${GITHUB_OUTPUT}"

elif [[ "${GITHUB_EVENT_NAME}" == "pull_request" ]]; then
GITHUB_USER_ID=${GITHUB_EVENT_SENDER_ID}
echo "Using label adder: ${GITHUB_EVENT_SENDER_LOGIN} (ID: ${GITHUB_USER_ID})"
echo "github_user_id=${GITHUB_USER_ID}" >> "${GITHUB_OUTPUT}"
echo "github_username=${GITHUB_EVENT_SENDER_LOGIN}" >> "${GITHUB_OUTPUT}"

echo "Using PR URL: ${GITHUB_EVENT_PR_HTML_URL}"
# Convert /pull/ to /issues/ for create-task-action compatibility
ISSUE_URL="${GITHUB_EVENT_PR_HTML_URL/\/pull\//\/issues\/}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Variable should be quoted for consistency and safety with special characters.

Suggested change
ISSUE_URL="${GITHUB_EVENT_PR_HTML_URL/\/pull\//\/issues\/}"
ISSUE_URL="${GITHUB_EVENT_PR_HTML_URL/\/pull\//\/issues\/}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: Variable should be quoted for consistency and safety.

Suggested change
ISSUE_URL="${GITHUB_EVENT_PR_HTML_URL/\/pull\//\/issues\/}"
ISSUE_URL="${GITHUB_EVENT_PR_HTML_URL/\/pull\//\/issues\/}"

echo "pr_url=${ISSUE_URL}" >> "${GITHUB_OUTPUT}"
echo "pr_number=${GITHUB_EVENT_PR_NUMBER}" >> "${GITHUB_OUTPUT}"

else
echo "::error::Unsupported event type: ${GITHUB_EVENT_NAME}"
exit 1
fi

- name: Extract repository info
id: repo-info
run: |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing error handling directives for this shell script block.

Suggested change
run: |
run: |
set -euo pipefail
echo "owner=${{ github.repository_owner }}" >> "${GITHUB_OUTPUT}"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: Missing set -euo pipefail for consistency with other shell script blocks.

Suggested change
run: |
run: |
set -euo pipefail
echo "owner=${{ github.repository_owner }}" >> "${GITHUB_OUTPUT}"

echo "owner=${{ github.repository_owner }}" >> "${GITHUB_OUTPUT}"
echo "repo=${{ github.event.repository.name }}" >> "${GITHUB_OUTPUT}"

- name: Build code review prompt
id: build-prompt
env:
PR_URL: ${{ steps.determine-context.outputs.pr_url }}
PR_NUMBER: ${{ steps.determine-context.outputs.pr_number }}
REPO_OWNER: ${{ steps.repo-info.outputs.owner }}
REPO_NAME: ${{ steps.repo-info.outputs.repo }}
GH_TOKEN: ${{ github.token }}
run: |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing error handling directives. This is especially important for the heredoc block that follows.

Suggested change
run: |
run: |
set -euo pipefail
echo "Building code review prompt for PR #${PR_NUMBER}"

echo "Building code review prompt for PR #${PR_NUMBER}"

Comment on lines +132 to +133
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Issue: Missing set -euo pipefail at the start of the script block.

Impact: Without these flags, if PR_NUMBER is undefined or the heredoc fails, the step could succeed with an incomplete or malformed prompt, causing the Coder task to receive invalid instructions.

Suggested change
echo "Building code review prompt for PR #${PR_NUMBER}"
run: |
set -euo pipefail
echo "Building code review prompt for PR #${PR_NUMBER}"

# Build task prompt
TASK_PROMPT=$(cat <<EOF
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The bash heredoc syntax is missing proper indentation handling. The <<EOF should be <<-EOF to strip leading tabs, making the code more readable:

Suggested change
TASK_PROMPT=$(cat <<EOF
TASK_PROMPT=$(cat <<-EOF
Suggested change
TASK_PROMPT=$(cat <<EOF
TASK_PROMPT=$(cat <<-EOF

Copilot uses AI. Check for mistakes.
Perform a thorough code review of PR #${PR_NUMBER} with actionable code suggestions.

PR URL: ${PR_URL}
Repository: ${REPO_OWNER}/${REPO_NAME}

WORKFLOW:
1. Setup (repo is pre-cloned at ~/coder)
cd ~/coder
git fetch origin pull/${PR_NUMBER}/head:pr-${PR_NUMBER}
git checkout pr-${PR_NUMBER}

2. Get PR info
Use GitHub MCP tools to get PR title, body, and full diff
Or use: git diff main...pr-${PR_NUMBER}
Note: GH_TOKEN environment variable is already configured for gh CLI

3. Analyze the Changes
- Understand what the PR is trying to accomplish
- Review the code for quality, clarity, and correctness
- Check for potential bugs, edge cases, or security issues
- Verify error handling and logging
- Check for proper testing coverage
- Look for performance issues
- Verify adherence to coding standards and best practices

4. Review Specific Areas
- Code structure and organization
- Naming conventions and readability
- Proper use of types and interfaces
- Error handling patterns
- Test coverage and quality
- Security considerations
- Performance implications
- Database query efficiency (if applicable)
- Proper use of context and cancellation (Go code)
- Authorization checks (dbauthz patterns)

5. Check Against Project Standards
- Review against Uber Go Style Guide (for Go code)
- Check commit message format
- Verify proper comments (explain why, not what)
- Ensure no unnecessary changes to unrelated code
- Check for proper line wrapping (80 chars for comments)
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prompt mentions reviewing against "Uber Go Style Guide" and checking for "context and cancellation (Go code)" and "dbauthz patterns" which are all Go/Coder-specific. This creates a workflow that's tightly coupled to a specific tech stack. Consider either:

  1. Renaming the workflow to indicate it's Go-specific
  2. Making these guidelines configurable via inputs
  3. Having the AI detect the project language and apply appropriate style guides

Copilot uses AI. Check for mistakes.

6. Create ONE review with ALL inline comments using GitHub's review API
CRITICAL: Submit everything as a single review, not separate comments

7. Use GitHub's native suggestion format for committable changes

HOW TO POST A REVIEW WITH INLINE COMMENTS:

IMPORTANT: You have access to gh CLI with GH_TOKEN already configured.

Step 1: Get the PR commit SHA
COMMIT_SHA="\$(gh api repos/${REPO_OWNER}/${REPO_NAME}/pulls/${PR_NUMBER} --jq '.head.sha')"

Step 2: Build comments array and submit as ONE review
Example using gh api:

gh api repos/${REPO_OWNER}/${REPO_NAME}/pulls/${PR_NUMBER}/reviews \\
--method POST \\
-f event="COMMENT" \\
-f commit_id="\${COMMIT_SHA}" \\
-f body="## 🔍 AI Code Review Summary

I've reviewed the changes and posted inline suggestions below.
Click 'Commit suggestion' on any suggestion to apply it directly.

### Summary
[Brief overview of changes and overall assessment]

### ✅ Strengths
[Positive aspects found]

### 📊 Review Stats
- High priority issues: X
- Medium priority issues: Y
- Low priority suggestions: Z

---
*Generated by AI Agent via [Coder Tasks](https://coder.com/docs/ai-coder/tasks)*" \\
-f 'comments[][path]=coderd/oauth2.go' \\
-F 'comments[][line]=123' \\
-f 'comments[][side]=RIGHT' \\
-f 'comments[][body]=**Issue:** Error not wrapped with context

\`\`\`suggestion
if err != nil {
return xerrors.Errorf("fetch user data: %w", err)
}
\`\`\`' \\
-f 'comments[][path]=coderd/users.go' \\
-F 'comments[][line]=45' \\
-f 'comments[][side]=RIGHT' \\
-f 'comments[][body]=**Issue:** Variable name not descriptive

\`\`\`suggestion
var retryCount int
\`\`\`'

IMPORTANT NOTES:
- Use -F (uppercase) for line numbers (integers), -f (lowercase) for strings
- side should be "RIGHT" for the new/changed code
- event can be "COMMENT", "APPROVE", or "REQUEST_CHANGES"
- For this task, use "COMMENT" (neutral feedback with suggestions)

GITHUB SUGGESTION SYNTAX:
GitHub renders \`\`\`suggestion blocks as one-click committable suggestions.
The suggestion replaces the line(s) it comments on.

Example inline comment body:
**Issue:** Error not wrapped with context. Makes debugging harder.

\`\`\`suggestion
if err != nil {
return xerrors.Errorf("fetch user data: %w", err)
}
\`\`\`

WORKFLOW:
1. Read the PR diff and analyze all changes
2. Build a list of ALL issues with their file path, line number, and suggested fix
3. Submit ONE review with ALL inline comments at once
4. Include a summary body in the review

COMMENT FORMAT FOR SUMMARY:
## 🔍 AI Code Review Summary

I've posted inline review comments with committable suggestions on specific lines.
Click "Commit suggestion" on any suggestion to apply it directly.

### Summary
[Brief overview of what the PR does and overall assessment]

### ✅ Strengths
- Positive aspects of the implementation
- Good patterns or approaches used

### 📊 Review Stats
- High priority issues: X
- Medium priority issues: Y
- Suggestions: Z

### 🧪 Testing Notes
[Comments about test coverage and quality]

---
*This review was generated by an AI Agent through [Coder Tasks](https://coder.com/docs/ai-coder/tasks)*

CRITICAL REQUIREMENTS:
1. Post inline comments on SPECIFIC LINES where issues exist
2. Use \`\`\`suggestion syntax for every code change
3. Each suggestion must be committable with one click
4. Only include the lines that need to change in the suggestion block
5. Make sure suggestion syntax is exactly: \`\`\`suggestion (no language tag)
6. Post summary comment after all inline comments are done

EXAMPLE INLINE COMMENT:
File: coderd/oauth2.go, Line: 123
Comment body:
"**Issue:** Error not wrapped with context. This makes debugging harder.

\`\`\`suggestion
if err != nil {
return xerrors.Errorf("fetch user data: %w", err)
}
\`\`\`
"

SUGGESTION BLOCK RULES:
- Use \`\`\`suggestion (not \`\`\`go or any other language)
- Include ONLY the corrected lines
- Preserve exact indentation from the original file
- GitHub will replace the commented line(s) with your suggestion
- For single-line suggestions: comment on that line
- For multi-line suggestions: use start_line and line parameters
Example: -F 'comments[][start_line]=10' -F 'comments[][line]=15'
This comments on lines 10-15 and your suggestion replaces all of them
- Always use side="RIGHT" to comment on the PR changes

BEST PRACTICES:
1. Review the ENTIRE diff before starting to comment
2. Group related issues together when possible
3. Be constructive - explain WHY, not just WHAT
4. Prioritize critical issues (security, bugs) over style
5. Use "COMMENT" event for suggestions (not REQUEST_CHANGES)
6. Test your gh api command before submitting (dry run if possible)
7. If the review is too large (>20 comments), focus on most important
8. Include positive feedback in strengths section
9. Make suggestions actionable and specific

COMMON MISTAKES TO AVOID:
- Don't use language tags in suggestion blocks (no \`\`\`go)
- Don't forget to get the commit SHA first
- Don't post individual comments - batch them in ONE review
- Don't use -f for line numbers, use -F (uppercase)
- Don't comment on unchanged lines (use side="RIGHT")
- Don't include more context than needed in suggestion blocks
- Don't suggest changes to test files that mock prod behavior
- Don't nitpick formatting if it follows project style

ERROR HANDLING:
If gh api fails:
1. Check that GH_TOKEN is set and valid
2. Verify the commit SHA exists
3. Ensure file paths are relative to repo root
4. Check line numbers are within the changed lines
5. Fall back to posting a summary comment if review API fails

EOF
)

# Output the prompt
{
echo "task_prompt<<EOFOUTPUT"
echo "${TASK_PROMPT}"
echo "EOFOUTPUT"
Comment on lines +246 to +248
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The heredoc marker at line 334 and line 336 use different markers (EOFOUTPUT). While this works, it would be more maintainable to use consistent naming. Also, the heredoc at line 119 uses EOF while this uses EOFOUTPUT, creating inconsistency:

Suggested change
echo "task_prompt<<EOFOUTPUT"
echo "${TASK_PROMPT}"
echo "EOFOUTPUT"
echo "task_prompt<<EOF_TASK_PROMPT"
echo "${TASK_PROMPT}"
echo "EOF_TASK_PROMPT"
Suggested change
echo "task_prompt<<EOFOUTPUT"
echo "${TASK_PROMPT}"
echo "EOFOUTPUT"
echo "task_prompt<<EOF_TASK_PROMPT"
echo "${TASK_PROMPT}"
echo "EOF_TASK_PROMPT"

Copilot uses AI. Check for mistakes.
} >> "${GITHUB_OUTPUT}"

- name: Checkout create-task-action
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best Practice: Consider pinning to a specific commit SHA rather than the main branch for better reproducibility and security.

Using ref: main means the workflow behavior can change unexpectedly if the action is updated. Pinning to a commit SHA ensures consistent behavior and allows you to review changes before updating.

Suggested change
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
ref: main # TODO: Pin to commit SHA for reproducibility (e.g., abc123def456...)

with:
fetch-depth: 1
path: ./.github/actions/create-task-action
persist-credentials: false
ref: main
Copy link

Copilot AI Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow checks out an external action from the main branch (line 345), which could introduce supply chain security risks if that branch is compromised. Consider pinning to a specific commit SHA or tag version for better security:

Suggested change
ref: main
ref: v1.0.0 # or a specific commit SHA
Suggested change
ref: main
ref: v1.0.0 # or a specific commit SHA

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Pin to commit SHA instead of main for reproducibility. Using main means workflow behavior can change unexpectedly.

Suggested change
ref: main
ref: main # TODO: Pin to specific commit SHA for reproducibility

repository: coder/create-task-action

- name: Create Coder Task for Code Review
id: create_task
uses: ./.github/actions/create-task-action
with:
coder-url: ${{ secrets.CODE_REVIEW_CODER_URL }}
coder-token: ${{ secrets.CODE_REVIEW_CODER_SESSION_TOKEN }}
coder-organization: "default"
coder-template-name: coder
coder-template-preset: ${{ steps.determine-context.outputs.template_preset }}
coder-task-name-prefix: code-review
coder-task-prompt: ${{ steps.build-prompt.outputs.task_prompt }}
github-user-id: ${{ steps.determine-context.outputs.github_user_id }}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Missing error handling directives for consistency with other steps.

Suggested change
github-user-id: ${{ steps.determine-context.outputs.github_user_id }}
run: |
set -euo pipefail
{

github-token: ${{ github.token }}
github-issue-url: ${{ steps.determine-context.outputs.pr_url }}
# The AI will post the review itself, not as a general comment
comment-on-issue: false

- name: Write outputs
env:
TASK_CREATED: ${{ steps.create_task.outputs.task-created }}
TASK_NAME: ${{ steps.create_task.outputs.task-name }}
TASK_URL: ${{ steps.create_task.outputs.task-url }}
PR_URL: ${{ steps.determine-context.outputs.pr_url }}
run: |
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: Missing set -euo pipefail for consistency.

Suggested change
run: |
run: |
set -euo pipefail
{

{
echo "## Code Review Task"
echo ""
echo "**PR:** ${PR_URL}"
echo "**Task created:** ${TASK_CREATED}"
echo "**Task name:** ${TASK_NAME}"
echo "**Task URL:** ${TASK_URL}"
echo ""
echo "The Coder task is analyzing the PR and will comment with a code review."
} >> "${GITHUB_STEP_SUMMARY}"

Loading