talkable-style 1.2025.0205 → 1.2026.0730
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/actions/setup-apt-packages/action.yml +88 -0
- data/.github/workflows/claude-code-review.yml +258 -0
- data/.github/workflows/claude.yml +53 -0
- data/.github/workflows/droid.yml +43 -0
- data/.github/workflows/pr-agent.yml +51 -0
- data/.github/workflows/pr-review.yml +107 -0
- data/README.md +2 -2
- data/config/capybara.yml +17 -9
- data/config/discourse.yml +2 -1
- data/config/factory_bot.yml +1 -1
- data/config/gemspec.yml +2 -0
- data/config/graphql.yml +1 -1
- data/config/layout.yml +2 -0
- data/config/lint.yml +16 -0
- data/config/naming.yml +3 -1
- data/config/performance.yml +3 -1
- data/config/rails.yml +5 -1
- data/config/rake.yml +1 -1
- data/config/rspec.yml +5 -1
- data/config/rspec_rails.yml +3 -1
- data/config/style.yml +44 -0
- data/default.yml +3 -3
- data/lib/talkable/style/version.rb +1 -1
- data/shared/.pronto_spell.pws +269 -0
- data/talkable-style.gemspec +11 -15
- metadata +30 -40
- data/config/gitlab-security.yml +0 -12
- data/shared/.circleci/bin/pronto +0 -19
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 79d26ba5c41c3fa1e00856ceea66e97dcfbdee24a6287ce991daf16c04739c71
|
|
4
|
+
data.tar.gz: 658ee9af66f27ef07fef68b2e08d7597e225a25ae64070bd34c2cd736f553e6d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f9983b13c949f0bb30d45d49b49ba515326c0244e74b85e64d0bb66cdcb501d098cc5b38e00a15911b3a69fcfa2a828fd6bf185cfe0d3d52d49867c7262441fa
|
|
7
|
+
data.tar.gz: ad08a2b78a19bd00b92b38858f95b82ecaba4ec75275ffe45af9e354c2192c8b4f67c84bd1aee5b5d3b50cc16ed7a44a3190205429fbb9bb4037e8420a03ebf5
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# See https://github.com/actions/runner-images/issues/1120
|
|
2
|
+
name: Setup APT packages
|
|
3
|
+
description: Install APT packages with retry logic to handle lock conflicts
|
|
4
|
+
|
|
5
|
+
inputs:
|
|
6
|
+
packages:
|
|
7
|
+
description: Space-separated list of packages to install
|
|
8
|
+
required: true
|
|
9
|
+
|
|
10
|
+
runs:
|
|
11
|
+
using: composite
|
|
12
|
+
steps:
|
|
13
|
+
- name: Install APT packages
|
|
14
|
+
shell: bash
|
|
15
|
+
run: |
|
|
16
|
+
# Stop unattended-upgrades to prevent dpkg lock conflicts
|
|
17
|
+
sudo systemctl stop unattended-upgrades.service || true
|
|
18
|
+
sudo systemctl kill --kill-who=all unattended-upgrades.service || true
|
|
19
|
+
|
|
20
|
+
# Retry apt-get update up to 3 times to handle lock conflicts and mirror sync issues
|
|
21
|
+
for i in {1..3}; do
|
|
22
|
+
echo "Attempt $i: Updating package lists..."
|
|
23
|
+
|
|
24
|
+
# Wait for any existing dpkg processes to finish
|
|
25
|
+
timeout=60
|
|
26
|
+
elapsed=0
|
|
27
|
+
while sudo fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do
|
|
28
|
+
if [ $elapsed -ge $timeout ]; then
|
|
29
|
+
echo "Timeout waiting for dpkg lock to be released"
|
|
30
|
+
break
|
|
31
|
+
fi
|
|
32
|
+
echo "Waiting for existing dpkg processes to finish..."
|
|
33
|
+
sleep 2
|
|
34
|
+
elapsed=$((elapsed + 2))
|
|
35
|
+
done
|
|
36
|
+
|
|
37
|
+
# Run apt-get update and capture output
|
|
38
|
+
if output=$(sudo apt-get update 2>&1); then
|
|
39
|
+
echo "Package lists updated successfully"
|
|
40
|
+
break
|
|
41
|
+
else
|
|
42
|
+
echo "Update failed with output:"
|
|
43
|
+
echo "$output"
|
|
44
|
+
|
|
45
|
+
if [ $i -lt 3 ]; then
|
|
46
|
+
echo "Waiting 10 seconds before retry..."
|
|
47
|
+
sleep 10
|
|
48
|
+
else
|
|
49
|
+
echo "Failed to update package lists after 3 attempts"
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
# Retry apt-get install up to 3 times to handle lock conflicts
|
|
56
|
+
for i in {1..3}; do
|
|
57
|
+
echo "Attempt $i: Installing packages..."
|
|
58
|
+
|
|
59
|
+
# Wait for any existing dpkg processes to finish
|
|
60
|
+
timeout=60
|
|
61
|
+
elapsed=0
|
|
62
|
+
while sudo fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do
|
|
63
|
+
if [ $elapsed -ge $timeout ]; then
|
|
64
|
+
echo "Timeout waiting for dpkg lock to be released"
|
|
65
|
+
break
|
|
66
|
+
fi
|
|
67
|
+
echo "Waiting for existing dpkg processes to finish..."
|
|
68
|
+
sleep 2
|
|
69
|
+
elapsed=$((elapsed + 2))
|
|
70
|
+
done
|
|
71
|
+
|
|
72
|
+
# Run apt-get install and capture output
|
|
73
|
+
if output=$(sudo apt-get install -y --no-install-recommends ${{ inputs.packages }} 2>&1); then
|
|
74
|
+
echo "Packages installed successfully"
|
|
75
|
+
break
|
|
76
|
+
else
|
|
77
|
+
echo "Install failed with output:"
|
|
78
|
+
echo "$output"
|
|
79
|
+
|
|
80
|
+
if [ $i -lt 3 ]; then
|
|
81
|
+
echo "Waiting 10 seconds before retry..."
|
|
82
|
+
sleep 10
|
|
83
|
+
else
|
|
84
|
+
echo "Failed to install packages after 3 attempts"
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
fi
|
|
88
|
+
done
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
name: Claude Code Review
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
runs-on:
|
|
7
|
+
description: The type of machine to run the job on
|
|
8
|
+
default: ubuntu-latest
|
|
9
|
+
type: string
|
|
10
|
+
secrets:
|
|
11
|
+
CLAUDE_CODE_OAUTH_TOKEN:
|
|
12
|
+
required: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
claude-review:
|
|
16
|
+
if: |
|
|
17
|
+
github.event.sender.type != 'Bot' &&
|
|
18
|
+
github.actor != 'talkable-bot' &&
|
|
19
|
+
(
|
|
20
|
+
github.event_name == 'pull_request' ||
|
|
21
|
+
(
|
|
22
|
+
github.event_name == 'issue_comment' &&
|
|
23
|
+
contains(github.event.comment.body, '/claude-review')
|
|
24
|
+
)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
runs-on: ${{ inputs.runs-on }}
|
|
28
|
+
permissions:
|
|
29
|
+
actions: read
|
|
30
|
+
contents: read
|
|
31
|
+
pull-requests: read
|
|
32
|
+
issues: read
|
|
33
|
+
id-token: write
|
|
34
|
+
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout repository
|
|
37
|
+
uses: actions/checkout@v7
|
|
38
|
+
with:
|
|
39
|
+
fetch-depth: 1
|
|
40
|
+
|
|
41
|
+
# Removes any local .mcp.json file to ensure Claude Code Action uses its built-in GitHub MCP credentials
|
|
42
|
+
- name: Clean up local MCP configuration
|
|
43
|
+
run: rm -f .mcp.json
|
|
44
|
+
|
|
45
|
+
- name: Run Claude Code Review
|
|
46
|
+
id: claude-review
|
|
47
|
+
uses: anthropics/claude-code-action@v1
|
|
48
|
+
with:
|
|
49
|
+
use_sticky_comment: true
|
|
50
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
51
|
+
|
|
52
|
+
claude_args: |
|
|
53
|
+
--model claude-opus-5
|
|
54
|
+
--fallback-model claude-sonnet-5
|
|
55
|
+
--allowedTools "mcp__github__create_pending_pull_request_review,mcp__github__add_comment_to_pending_review,mcp__github__submit_pending_pull_request_review,mcp__github__get_pull_request_diff"
|
|
56
|
+
|
|
57
|
+
prompt: |
|
|
58
|
+
You are an expert code reviewer specializing in identifying bugs, performance bottlenecks, and logical
|
|
59
|
+
errors in pull requests. Your task is to perform a thorough, constructive code review of this pull request,
|
|
60
|
+
focusing on improving code quality.
|
|
61
|
+
|
|
62
|
+
REPO: ${{ github.repository }}
|
|
63
|
+
PR NUMBER: ${{ github.event_name == 'pull_request' && github.event.pull_request.number || github.event.issue.number }}
|
|
64
|
+
|
|
65
|
+
Note: The PR branch is already checked out in the current working directory.
|
|
66
|
+
|
|
67
|
+
CRITICAL LINE NUMBER GUIDANCE: When using `mcp__github__add_comment_to_pending_review`,
|
|
68
|
+
the `line` parameter must be the ACTUAL LINE NUMBER in the file, counting from 1 (not 0).
|
|
69
|
+
|
|
70
|
+
For NEW FILES (those starting with "new file mode" in the diff):
|
|
71
|
+
- Line 1 is the first line after "@@ -0,0 +1,XX @@"
|
|
72
|
+
- Count each subsequent line sequentially: 1, 2, 3, etc.
|
|
73
|
+
- The line number you specify is the actual line number in the new file
|
|
74
|
+
|
|
75
|
+
For MODIFIED FILES:
|
|
76
|
+
- Use the line number shown on the RIGHT side of the diff (after the + or space)
|
|
77
|
+
- These represent the line numbers in the new version of the file
|
|
78
|
+
|
|
79
|
+
For example, if reviewing a new file with this diff:
|
|
80
|
+
```
|
|
81
|
+
@@ -0,0 +1,29 @@
|
|
82
|
+
+#!/usr/bin/env bash
|
|
83
|
+
+
|
|
84
|
+
+if [ -z "$CIRCLE_PULL_REQUEST" ]; then
|
|
85
|
+
+ echo "Not a Pull Request, skipping Shippie."
|
|
86
|
+
+ exit 0
|
|
87
|
+
+fi
|
|
88
|
+
+
|
|
89
|
+
+export PRONTO_GITHUB_SLUG="$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME"
|
|
90
|
+
+export PRONTO_PULL_REQUEST_ID=$(echo "$CIRCLE_PULL_REQUEST" | grep -o 'pull.*' | cut -f2- -d/)
|
|
91
|
+
+
|
|
92
|
+
+url="https://api.github.com/repos/$PRONTO_GITHUB_SLUG/pulls/$PRONTO_PULL_REQUEST_ID"
|
|
93
|
+
+targetBranch=$(curl -H "Authorization: token $PRONTO_GITHUB_ACCESS_TOKEN" "$url" | jq '.base.ref' | tr -d '"')
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The line numbers are:
|
|
97
|
+
- Line 1: #!/usr/bin/env bash
|
|
98
|
+
- Line 2: (empty line)
|
|
99
|
+
- Line 3: if [ -z "$CIRCLE_PULL_REQUEST" ]; then
|
|
100
|
+
- ...
|
|
101
|
+
- Line 11: url="https://api.github.com/repos/$PRONTO_GITHUB_SLUG/pulls/$PRONTO_PULL_REQUEST_ID"
|
|
102
|
+
- Line 12: targetBranch=$(curl -H "Authorization: token $PRONTO_GITHUB_ACCESS_TOKEN" "$url" | jq '.base.ref' | tr -d '"')
|
|
103
|
+
|
|
104
|
+
To comment on the line with $PRONTO_GITHUB_ACCESS_TOKEN, use line: 12 (NOT 11).
|
|
105
|
+
|
|
106
|
+
Review Process:
|
|
107
|
+
1. Start a review using the `mcp__github__create_pending_pull_request_review` function.
|
|
108
|
+
2. Get the pull request diff information using the `mcp__github__get_pull_request_diff` function.
|
|
109
|
+
3. CAREFULLY note the line numbers shown in the diff for the RIGHT side (new file).
|
|
110
|
+
4. Analyze each file in the pull request systematically.
|
|
111
|
+
5. For each file, examine:
|
|
112
|
+
- The specific changes made
|
|
113
|
+
- How those changes interact with existing code
|
|
114
|
+
- Potential side effects or breaking changes
|
|
115
|
+
6. Identify issues in the following categories:
|
|
116
|
+
a. Bugs & Logic Errors
|
|
117
|
+
b. Performance Issues
|
|
118
|
+
c. Security Vulnerabilities
|
|
119
|
+
d. Code Quality & Maintainability
|
|
120
|
+
e. Architecture & Design
|
|
121
|
+
f. Testing Coverage
|
|
122
|
+
7. Categorize issues as Critical, Important, or Suggestions
|
|
123
|
+
8. Provide specific, actionable feedback with code examples using inline comments
|
|
124
|
+
9. When adding comments, use the EXACT line number shown in the diff for the specific line you're commenting on
|
|
125
|
+
10. After analyzing all files, submit the review with a summary comment
|
|
126
|
+
11. REMEMBER: You will submit review as COMMENT only, not approve/request changes
|
|
127
|
+
|
|
128
|
+
For each issue category, consider the following:
|
|
129
|
+
|
|
130
|
+
a. Bugs & Logic Errors:
|
|
131
|
+
- Potential null pointer exceptions or undefined behavior
|
|
132
|
+
- Off-by-one errors, incorrect boolean logic, or state management issues
|
|
133
|
+
- Error handling and edge case coverage
|
|
134
|
+
- Race conditions or concurrency issues
|
|
135
|
+
- Data transformations and type conversions
|
|
136
|
+
|
|
137
|
+
b. Performance Issues:
|
|
138
|
+
- N+1 query problems or inefficient database queries
|
|
139
|
+
- Unnecessary loops, redundant operations, or algorithmic inefficiencies
|
|
140
|
+
- Memory leaks or excessive memory allocation
|
|
141
|
+
- Caching opportunities
|
|
142
|
+
- Scalability of the solution
|
|
143
|
+
|
|
144
|
+
c. Security Vulnerabilities:
|
|
145
|
+
- SQL injection vulnerabilities
|
|
146
|
+
- Potential XSS or CSRF issues
|
|
147
|
+
- Authentication and authorization
|
|
148
|
+
- Exposed sensitive data (API keys, tokens) or improper sanitization
|
|
149
|
+
- Timing attacks or resource exhaustion vulnerabilities
|
|
150
|
+
|
|
151
|
+
d. Code Quality & Maintainability:
|
|
152
|
+
- Code readability and clarity
|
|
153
|
+
- Violations of DRY (Don't Repeat Yourself) principle
|
|
154
|
+
- Separation of concerns
|
|
155
|
+
- Consistent error handling patterns
|
|
156
|
+
- Missing validations or assertions
|
|
157
|
+
|
|
158
|
+
e. Architecture & Design:
|
|
159
|
+
- Alignment with existing patterns in the codebase
|
|
160
|
+
- Proper use of design patterns
|
|
161
|
+
- Database schema changes and migrations
|
|
162
|
+
- API contract changes and backwards compatibility
|
|
163
|
+
- Coupling and abstractions
|
|
164
|
+
|
|
165
|
+
f. Testing Coverage:
|
|
166
|
+
- Critical business logic test coverage
|
|
167
|
+
- Spec files for new service objects
|
|
168
|
+
- Factory definitions for new models
|
|
169
|
+
- System tests for end-to-end referral flows
|
|
170
|
+
- Reversible and tested database migrations
|
|
171
|
+
|
|
172
|
+
Before providing inline comments and the final review, wrap your analysis inside <file_analysis> tags. For each file:
|
|
173
|
+
|
|
174
|
+
1. List the specific changes made WITH THEIR EXACT LINE NUMBERS FROM THE DIFF
|
|
175
|
+
2. Analyze how these changes interact with existing code
|
|
176
|
+
3. Identify potential side effects or breaking changes
|
|
177
|
+
4. List all potential issues found, WITH THE EXACT LINE NUMBER where each issue occurs
|
|
178
|
+
5. For each potential issue:
|
|
179
|
+
- Note the EXACT line number from the diff where the issue is located
|
|
180
|
+
- Consider and note its impact on different aspects of the system (e.g., performance, security, maintainability)
|
|
181
|
+
- Assign a priority (Critical 🚨, Important ⚠️, or Suggestion 💡) based on its severity and impact
|
|
182
|
+
6. Prioritize the issues based on their assigned priorities and system impact
|
|
183
|
+
|
|
184
|
+
This process will help ensure a thorough interpretation of the code changes.
|
|
185
|
+
It's OK for this section to be quite long.
|
|
186
|
+
<file_analysis> tags are only for your analysis, do not include them in your final review.
|
|
187
|
+
|
|
188
|
+
Example of internal analysis (DO NOT OUTPUT THIS):
|
|
189
|
+
|
|
190
|
+
<file_analysis>
|
|
191
|
+
File: app/models/user.rb
|
|
192
|
+
1. Changes:
|
|
193
|
+
- Added new method `calculate_referral_bonus` (lines 45-52 in diff)
|
|
194
|
+
- Modified `update_profile` method (lines 78-85 in diff)
|
|
195
|
+
|
|
196
|
+
2. Interactions with existing code:
|
|
197
|
+
- New method called in referral processing workflow
|
|
198
|
+
- Modified method affects user profile updates
|
|
199
|
+
|
|
200
|
+
3. Potential side effects:
|
|
201
|
+
- Changes to referral bonus calculation may impact existing users
|
|
202
|
+
- Profile update changes could affect downstream processes
|
|
203
|
+
|
|
204
|
+
4. Potential issues:
|
|
205
|
+
- Performance: `calculate_referral_bonus` uses inefficient query (N+1 problem) - LINE 47 in diff
|
|
206
|
+
- Security: Referral bonus calculation not properly sanitized - LINE 49 in diff
|
|
207
|
+
- Testing: Missing unit test for edge cases in `update_profile` - LINE 82 in diff
|
|
208
|
+
- Code Quality: Duplication in error handling logic - LINES 51 and 84 in diff
|
|
209
|
+
|
|
210
|
+
5. System impact:
|
|
211
|
+
- Performance issue on LINE 47 could slow down referral processing for all users
|
|
212
|
+
- Security vulnerability on LINE 49 may expose the system to financial exploitation
|
|
213
|
+
- Lack of testing for changes on LINE 82 increases risk of regressions in user profile management
|
|
214
|
+
- Code duplication on LINES 51 and 84 may lead to inconsistent error handling across the application
|
|
215
|
+
...
|
|
216
|
+
</file_analysis>
|
|
217
|
+
|
|
218
|
+
After your analysis, provide inline comments using the `mcp__github__add_comment_to_pending_review` function. For each issue:
|
|
219
|
+
- Use the EXACT line number from the diff (not calculated or offset)
|
|
220
|
+
- Clearly explain the problem
|
|
221
|
+
- Provide the impact/consequences
|
|
222
|
+
- Suggest a specific solution with code examples
|
|
223
|
+
- Double-check that the line number matches where the issue actually appears in the diff
|
|
224
|
+
|
|
225
|
+
Remember to:
|
|
226
|
+
- Be constructive and professional
|
|
227
|
+
- Provide concrete examples and solutions
|
|
228
|
+
- Consider the broader system impact
|
|
229
|
+
- Verify that tests adequately cover the changes
|
|
230
|
+
- Check that documentation is updated if needed
|
|
231
|
+
- ALWAYS use the exact line numbers shown in the GitHub diff
|
|
232
|
+
|
|
233
|
+
After adding all inline comments, you MUST submit the review using the `mcp__github__submit_pending_pull_request_review` function with:
|
|
234
|
+
- event: "COMMENT" (MANDATORY - DO NOT USE "APPROVE" OR "REQUEST_CHANGES")
|
|
235
|
+
|
|
236
|
+
⚠️ IMPORTANT: You are providing code review feedback ONLY:
|
|
237
|
+
- Always use event: "COMMENT" when calling `mcp__github__add_comment_to_pending_review`
|
|
238
|
+
- NEVER use event: "APPROVE" or event: "REQUEST_CHANGES" (this would approve or block the PR)
|
|
239
|
+
- This applies regardless of the code quality or number of issues found
|
|
240
|
+
|
|
241
|
+
Include a summary review comment with the following structure:
|
|
242
|
+
|
|
243
|
+
```markdown
|
|
244
|
+
## Summary
|
|
245
|
+
[Brief overview of the PR and its purpose]
|
|
246
|
+
|
|
247
|
+
## Key Observations
|
|
248
|
+
- [List 3-5 main points about the changes]
|
|
249
|
+
|
|
250
|
+
## Recommendations
|
|
251
|
+
- [List 2-3 high-level recommendations]
|
|
252
|
+
|
|
253
|
+
## Overall Assessment
|
|
254
|
+
[1-2 sentences on the overall quality and readiness of the PR]
|
|
255
|
+
|
|
256
|
+
---
|
|
257
|
+
💡 To request another review, post a new comment with "/claude-review".
|
|
258
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: Claude Tag
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
runs-on:
|
|
7
|
+
description: The type of machine to run the job on
|
|
8
|
+
default: ubuntu-latest
|
|
9
|
+
type: string
|
|
10
|
+
allowed-non-write-users:
|
|
11
|
+
description: Comma-separated list of usernames allowed without write permissions
|
|
12
|
+
default: ''
|
|
13
|
+
type: string
|
|
14
|
+
secrets:
|
|
15
|
+
CLAUDE_CODE_OAUTH_TOKEN:
|
|
16
|
+
required: true
|
|
17
|
+
TALKABLE_BOT_GITHUB_ACCESS_TOKEN:
|
|
18
|
+
required: false
|
|
19
|
+
|
|
20
|
+
jobs:
|
|
21
|
+
claude:
|
|
22
|
+
if: |
|
|
23
|
+
github.event.sender.type != 'Bot' &&
|
|
24
|
+
github.actor != 'talkable-bot' &&
|
|
25
|
+
(
|
|
26
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
27
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
|
|
28
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
|
|
29
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
runs-on: ${{ inputs.runs-on }}
|
|
33
|
+
permissions:
|
|
34
|
+
contents: write
|
|
35
|
+
pull-requests: write
|
|
36
|
+
issues: write
|
|
37
|
+
id-token: write
|
|
38
|
+
actions: read
|
|
39
|
+
|
|
40
|
+
steps:
|
|
41
|
+
- name: Checkout repository
|
|
42
|
+
uses: actions/checkout@v7
|
|
43
|
+
with:
|
|
44
|
+
fetch-depth: 1
|
|
45
|
+
|
|
46
|
+
- name: Run Claude
|
|
47
|
+
uses: anthropics/claude-code-action@v1
|
|
48
|
+
with:
|
|
49
|
+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
50
|
+
github_token: ${{ secrets.TALKABLE_BOT_GITHUB_ACCESS_TOKEN }}
|
|
51
|
+
allowed_non_write_users: ${{ inputs.allowed-non-write-users }}
|
|
52
|
+
additional_permissions: |
|
|
53
|
+
actions: read
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Droid Tag
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
runs-on:
|
|
7
|
+
description: The type of machine to run the job on
|
|
8
|
+
default: ubuntu-latest
|
|
9
|
+
type: string
|
|
10
|
+
secrets:
|
|
11
|
+
FACTORY_API_KEY:
|
|
12
|
+
required: true
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
droid:
|
|
16
|
+
if: |
|
|
17
|
+
github.event.sender.type != 'Bot' &&
|
|
18
|
+
github.actor != 'talkable-bot' &&
|
|
19
|
+
(
|
|
20
|
+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@droid')) ||
|
|
21
|
+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@droid')) ||
|
|
22
|
+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@droid')) ||
|
|
23
|
+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@droid') || contains(github.event.issue.title, '@droid')))
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
runs-on: ${{ inputs.runs-on }}
|
|
27
|
+
permissions:
|
|
28
|
+
contents: write
|
|
29
|
+
pull-requests: write
|
|
30
|
+
issues: write
|
|
31
|
+
id-token: write
|
|
32
|
+
actions: read
|
|
33
|
+
|
|
34
|
+
steps:
|
|
35
|
+
- name: Checkout repository
|
|
36
|
+
uses: actions/checkout@v7
|
|
37
|
+
with:
|
|
38
|
+
fetch-depth: 1
|
|
39
|
+
|
|
40
|
+
- name: Run Droid
|
|
41
|
+
uses: Factory-AI/droid-action@v5
|
|
42
|
+
with:
|
|
43
|
+
factory_api_key: ${{ secrets.FACTORY_API_KEY }}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
name: PR Agent
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
runs-on:
|
|
7
|
+
description: The type of machine to run the job on
|
|
8
|
+
default: ubuntu-latest
|
|
9
|
+
type: string
|
|
10
|
+
secrets:
|
|
11
|
+
OPENAI_KEY:
|
|
12
|
+
required: true
|
|
13
|
+
TALKABLE_BOT_GITHUB_ACCESS_TOKEN:
|
|
14
|
+
required: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
pr-agent:
|
|
18
|
+
if: |
|
|
19
|
+
github.event.sender.type != 'Bot' &&
|
|
20
|
+
github.actor != 'talkable-bot' &&
|
|
21
|
+
(
|
|
22
|
+
github.event_name == 'pull_request' ||
|
|
23
|
+
(
|
|
24
|
+
github.event_name == 'issue_comment' &&
|
|
25
|
+
(
|
|
26
|
+
contains(github.event.comment.body, '/describe') ||
|
|
27
|
+
contains(github.event.comment.body, '/improve') ||
|
|
28
|
+
contains(github.event.comment.body, '/review')
|
|
29
|
+
)
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
runs-on: ${{ inputs.runs-on }}
|
|
34
|
+
permissions:
|
|
35
|
+
issues: write
|
|
36
|
+
pull-requests: write
|
|
37
|
+
contents: write
|
|
38
|
+
|
|
39
|
+
steps:
|
|
40
|
+
- name: PR Agent action step
|
|
41
|
+
id: pragent
|
|
42
|
+
uses: the-pr-agent/pr-agent@main
|
|
43
|
+
env:
|
|
44
|
+
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
|
|
45
|
+
GITHUB_TOKEN: ${{ secrets.TALKABLE_BOT_GITHUB_ACCESS_TOKEN }}
|
|
46
|
+
github_action_config.auto_review: "true"
|
|
47
|
+
github_action_config.auto_describe: "true"
|
|
48
|
+
github_action_config.auto_improve: "false"
|
|
49
|
+
config.model: "gpt-5.6"
|
|
50
|
+
config.fallback_models: '["gpt-5.6-terra"]'
|
|
51
|
+
pr_reviewer.extra_instructions: "Focus on identifying bugs, performance bottlenecks, logical errors and security issues."
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
name: PR Review by OpenHands
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_call:
|
|
5
|
+
inputs:
|
|
6
|
+
runs-on:
|
|
7
|
+
description: The type of machine to run the job on
|
|
8
|
+
default: ubuntu-latest
|
|
9
|
+
type: string
|
|
10
|
+
secrets:
|
|
11
|
+
OPENAI_KEY:
|
|
12
|
+
required: true
|
|
13
|
+
TALKABLE_BOT_GITHUB_ACCESS_TOKEN:
|
|
14
|
+
required: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
pr-review:
|
|
18
|
+
if: |
|
|
19
|
+
github.event.sender.type != 'Bot' &&
|
|
20
|
+
github.actor != 'talkable-bot' &&
|
|
21
|
+
(
|
|
22
|
+
github.event_name == 'pull_request' ||
|
|
23
|
+
(
|
|
24
|
+
github.event_name == 'issue_comment' &&
|
|
25
|
+
contains(github.event.comment.body, '/pr-review')
|
|
26
|
+
)
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
runs-on: ${{ inputs.runs-on }}
|
|
30
|
+
permissions:
|
|
31
|
+
issues: write
|
|
32
|
+
pull-requests: write
|
|
33
|
+
contents: read
|
|
34
|
+
|
|
35
|
+
steps:
|
|
36
|
+
- name: Checkout software-agent-sdk repository
|
|
37
|
+
uses: actions/checkout@v7
|
|
38
|
+
with:
|
|
39
|
+
repository: OpenHands/software-agent-sdk
|
|
40
|
+
path: software-agent-sdk
|
|
41
|
+
|
|
42
|
+
- name: Get PR details
|
|
43
|
+
id: pr-details
|
|
44
|
+
env:
|
|
45
|
+
GH_TOKEN: ${{ secrets.TALKABLE_BOT_GITHUB_ACCESS_TOKEN }}
|
|
46
|
+
run: |
|
|
47
|
+
if [[ "${{ github.event_name }}" == "issue_comment" ]]; then
|
|
48
|
+
PR_NUMBER=${{ github.event.issue.number }}
|
|
49
|
+
PR_DATA=$(gh api repos/${{ github.repository }}/pulls/$PR_NUMBER)
|
|
50
|
+
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
|
|
51
|
+
echo "pr_title=$(echo "$PR_DATA" | jq -r '.title')" >> $GITHUB_OUTPUT
|
|
52
|
+
echo "pr_body<<EOF" >> $GITHUB_OUTPUT
|
|
53
|
+
echo "$PR_DATA" | jq -r '.body // ""' >> $GITHUB_OUTPUT
|
|
54
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
55
|
+
echo "pr_head_branch=$(echo "$PR_DATA" | jq -r '.head.ref')" >> $GITHUB_OUTPUT
|
|
56
|
+
echo "pr_base_branch=$(echo "$PR_DATA" | jq -r '.base.ref')" >> $GITHUB_OUTPUT
|
|
57
|
+
else
|
|
58
|
+
echo "pr_number=${{ github.event.pull_request.number }}" >> $GITHUB_OUTPUT
|
|
59
|
+
echo "pr_title=${{ github.event.pull_request.title }}" >> $GITHUB_OUTPUT
|
|
60
|
+
echo "pr_body<<EOF" >> $GITHUB_OUTPUT
|
|
61
|
+
echo "${{ github.event.pull_request.body }}" >> $GITHUB_OUTPUT
|
|
62
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
63
|
+
echo "pr_head_branch=${{ github.event.pull_request.head.ref }}" >> $GITHUB_OUTPUT
|
|
64
|
+
echo "pr_base_branch=${{ github.event.pull_request.base.ref }}" >> $GITHUB_OUTPUT
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
- name: Checkout PR repository
|
|
68
|
+
uses: actions/checkout@v7
|
|
69
|
+
with:
|
|
70
|
+
fetch-depth: 0
|
|
71
|
+
path: pr-repo
|
|
72
|
+
ref: ${{ steps.pr-details.outputs.pr_head_branch }}
|
|
73
|
+
|
|
74
|
+
- name: Set up Python
|
|
75
|
+
uses: actions/setup-python@v7
|
|
76
|
+
with:
|
|
77
|
+
python-version: '3.14'
|
|
78
|
+
|
|
79
|
+
- name: Install uv
|
|
80
|
+
uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
|
|
81
|
+
with:
|
|
82
|
+
enable-cache: true
|
|
83
|
+
|
|
84
|
+
- name: Install OpenHands dependencies
|
|
85
|
+
run: |
|
|
86
|
+
# Install OpenHands SDK and tools from git repository
|
|
87
|
+
uv pip install --system "openhands-sdk @ git+https://github.com/OpenHands/software-agent-sdk.git@main#subdirectory=openhands-sdk"
|
|
88
|
+
uv pip install --system "openhands-tools @ git+https://github.com/OpenHands/software-agent-sdk.git@main#subdirectory=openhands-tools"
|
|
89
|
+
|
|
90
|
+
- name: Run PR review
|
|
91
|
+
env:
|
|
92
|
+
GITHUB_TOKEN: ${{ secrets.TALKABLE_BOT_GITHUB_ACCESS_TOKEN }}
|
|
93
|
+
LLM_API_KEY: ${{ secrets.OPENAI_KEY }}
|
|
94
|
+
LLM_BASE_URL: https://api.openai.com/v1
|
|
95
|
+
LLM_MODEL: gpt-5.6
|
|
96
|
+
PR_BASE_BRANCH: ${{ steps.pr-details.outputs.pr_base_branch }}
|
|
97
|
+
PR_BODY: ${{ steps.pr-details.outputs.pr_body }}
|
|
98
|
+
PR_HEAD_BRANCH: ${{ steps.pr-details.outputs.pr_head_branch }}
|
|
99
|
+
PR_NUMBER: ${{ steps.pr-details.outputs.pr_number }}
|
|
100
|
+
PR_TITLE: ${{ steps.pr-details.outputs.pr_title }}
|
|
101
|
+
REPO_NAME: ${{ github.repository }}
|
|
102
|
+
run: |
|
|
103
|
+
# Change to the PR repository directory so agent can analyze the code
|
|
104
|
+
cd pr-repo
|
|
105
|
+
|
|
106
|
+
# Run the PR review script from the agent-sdk checkout
|
|
107
|
+
uv run python ../software-agent-sdk/examples/03_github_workflows/02_pr_review/agent_script.py
|
data/README.md
CHANGED
|
@@ -21,7 +21,7 @@ spec.add_development_dependency "talkable-style"
|
|
|
21
21
|
And then run:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
|
|
24
|
+
bundle install
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
## Usage
|
|
@@ -37,7 +37,7 @@ inherit_gem:
|
|
|
37
37
|
Now, run:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
|
|
40
|
+
bundle exec rubocop
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
You do not need to include rubocop directly in your application's dependencies. Talkable-style will include a specific version of `rubocop` and `rubocop-*` that is shared across all projects.
|
data/config/capybara.yml
CHANGED
|
@@ -1,24 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
plugins: rubocop-capybara
|
|
2
2
|
|
|
3
|
-
Capybara/
|
|
3
|
+
Capybara/AmbiguousClick:
|
|
4
4
|
Enabled: true
|
|
5
|
-
Capybara/
|
|
5
|
+
Capybara/AssertStyle:
|
|
6
6
|
Enabled: true
|
|
7
|
-
Capybara/
|
|
7
|
+
Capybara/FindAllFirst:
|
|
8
8
|
Enabled: true
|
|
9
|
-
Capybara/
|
|
9
|
+
Capybara/RSpec/CurrentPathExpectation:
|
|
10
|
+
Enabled: true
|
|
11
|
+
Capybara/RSpec/HaveContent:
|
|
10
12
|
Enabled: true
|
|
11
13
|
Capybara/RSpec/HaveSelector:
|
|
12
14
|
Enabled: true
|
|
15
|
+
Capybara/RSpec/MatchStyle:
|
|
16
|
+
Enabled: true
|
|
17
|
+
Capybara/RSpec/NegationMatcher:
|
|
18
|
+
Enabled: true
|
|
19
|
+
Capybara/RSpec/NegationMatcherAfterVisit:
|
|
20
|
+
Enabled: true
|
|
13
21
|
Capybara/RSpec/PredicateMatcher:
|
|
14
22
|
Enabled: true
|
|
23
|
+
Capybara/RSpec/SpecificMatcher:
|
|
24
|
+
Enabled: true
|
|
25
|
+
Capybara/RSpec/VisibilityMatcher:
|
|
26
|
+
Enabled: true
|
|
15
27
|
Capybara/RedundantWithinFind:
|
|
16
28
|
Enabled: true
|
|
17
29
|
Capybara/SpecificActions:
|
|
18
30
|
Enabled: true
|
|
19
31
|
Capybara/SpecificFinders:
|
|
20
32
|
Enabled: true
|
|
21
|
-
Capybara/SpecificMatcher:
|
|
22
|
-
Enabled: true
|
|
23
|
-
Capybara/VisibilityMatcher:
|
|
24
|
-
Enabled: true
|
data/config/discourse.yml
CHANGED