Skip to content

Commit 8c7e29e

Browse files
phernandezclaude
andauthored
chore: Update Claude Code GitHub Workflow (#308)
Signed-off-by: phernandez <[email protected]> Co-authored-by: Claude <[email protected]>
1 parent 84c0b36 commit 8c7e29e

File tree

3 files changed

+183
-84
lines changed

3 files changed

+183
-84
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
name: Claude Code Review
2+
3+
on:
4+
pull_request:
5+
types: [opened, synchronize]
6+
# Optional: Only run on specific file changes
7+
# paths:
8+
# - "src/**/*.ts"
9+
# - "src/**/*.tsx"
10+
# - "src/**/*.js"
11+
# - "src/**/*.jsx"
12+
13+
jobs:
14+
claude-review:
15+
# Only run for organization members and collaborators
16+
if: |
17+
github.event.pull_request.author_association == 'OWNER' ||
18+
github.event.pull_request.author_association == 'MEMBER' ||
19+
github.event.pull_request.author_association == 'COLLABORATOR'
20+
21+
runs-on: ubuntu-latest
22+
permissions:
23+
contents: read
24+
pull-requests: write
25+
issues: read
26+
id-token: write
27+
28+
steps:
29+
- name: Checkout repository
30+
uses: actions/checkout@v4
31+
with:
32+
fetch-depth: 1
33+
34+
- name: Run Claude Code Review
35+
id: claude-review
36+
uses: anthropics/claude-code-action@v1
37+
with:
38+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39+
track_progress: true # Enable visual progress tracking
40+
prompt: |
41+
Review this Basic Memory PR against our team checklist:
42+
43+
## Code Quality & Standards
44+
- [ ] Follows Basic Memory's coding conventions in CLAUDE.md
45+
- [ ] Python 3.12+ type annotations and async patterns
46+
- [ ] SQLAlchemy 2.0 best practices
47+
- [ ] FastAPI and Typer conventions followed
48+
- [ ] 100-character line length limit maintained
49+
- [ ] No commented-out code blocks
50+
51+
## Testing & Documentation
52+
- [ ] Unit tests for new functions/methods
53+
- [ ] Integration tests for new MCP tools
54+
- [ ] Test coverage for edge cases
55+
- [ ] Documentation updated (README, docstrings)
56+
- [ ] CLAUDE.md updated if conventions change
57+
58+
## Basic Memory Architecture
59+
- [ ] MCP tools follow atomic, composable design
60+
- [ ] Database changes include Alembic migrations
61+
- [ ] Preserves local-first architecture principles
62+
- [ ] Knowledge graph operations maintain consistency
63+
- [ ] Markdown file handling preserves integrity
64+
- [ ] AI-human collaboration patterns followed
65+
66+
## Security & Performance
67+
- [ ] No hardcoded secrets or credentials
68+
- [ ] Input validation for MCP tools
69+
- [ ] Proper error handling and logging
70+
- [ ] Performance considerations addressed
71+
- [ ] No sensitive data in logs or commits
72+
73+
Read the CLAUDE.md file for detailed project context. For each checklist item, verify if it's satisfied and comment on any that need attention. Use inline comments for specific code issues and post a summary with checklist results.
74+
75+
# Allow broader tool access for thorough code review
76+
claude_args: '--allowed-tools "Bash(gh pr:*),Bash(gh issue:*),Bash(gh api:*),Bash(git log:*),Bash(git show:*),Read,Grep,Glob"'
77+
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
name: Claude Issue Triage
2+
3+
on:
4+
issues:
5+
types: [opened]
6+
7+
jobs:
8+
triage:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
issues: write
12+
id-token: write
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
with:
17+
fetch-depth: 1
18+
19+
- name: Run Claude Issue Triage
20+
uses: anthropics/claude-code-action@v1
21+
with:
22+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
23+
track_progress: true # Show triage progress
24+
prompt: |
25+
Analyze this new Basic Memory issue and perform triage:
26+
27+
**Issue Analysis:**
28+
1. **Type Classification:**
29+
- Bug report (code defect)
30+
- Feature request (new functionality)
31+
- Enhancement (improvement to existing feature)
32+
- Documentation (docs improvement)
33+
- Question/Support (user help)
34+
- MCP tool issue (specific to MCP functionality)
35+
36+
2. **Priority Assessment:**
37+
- Critical: Security issues, data loss, complete breakage
38+
- High: Major functionality broken, affects many users
39+
- Medium: Minor bugs, usability issues
40+
- Low: Nice-to-have improvements, cosmetic issues
41+
42+
3. **Component Classification:**
43+
- CLI commands
44+
- MCP tools
45+
- Database/sync
46+
- Cloud functionality
47+
- Documentation
48+
- Testing
49+
50+
4. **Complexity Estimate:**
51+
- Simple: Quick fix, documentation update
52+
- Medium: Requires some investigation/testing
53+
- Complex: Major feature work, architectural changes
54+
55+
**Actions to Take:**
56+
1. Add appropriate labels using: `gh issue edit ${{ github.event.issue.number }} --add-label "label1,label2"`
57+
2. Check for duplicates using: `gh search issues`
58+
3. If duplicate found, comment mentioning the original issue
59+
4. For feature requests, ask clarifying questions if needed
60+
5. For bugs, request reproduction steps if missing
61+
62+
**Available Labels:**
63+
- Type: bug, enhancement, feature, documentation, question, mcp-tool
64+
- Priority: critical, high, medium, low
65+
- Component: cli, mcp, database, cloud, docs, testing
66+
- Complexity: simple, medium, complex
67+
- Status: needs-reproduction, needs-clarification, duplicate
68+
69+
Read the issue carefully and provide helpful triage with appropriate labels.
70+
71+
claude_args: '--allowed-tools "Bash(gh issue:*),Bash(gh search:*),Read"'

.github/workflows/claude.yml

Lines changed: 35 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -9,106 +9,57 @@ on:
99
types: [opened, assigned]
1010
pull_request_review:
1111
types: [submitted]
12+
pull_request_target:
13+
types: [opened, synchronize]
1214

1315
jobs:
1416
claude:
1517
if: |
16-
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
17-
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
18-
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
19-
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
20-
18+
(
19+
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
20+
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
21+
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
22+
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude'))) ||
23+
(github.event_name == 'pull_request_target' && contains(github.event.pull_request.body, '@claude'))
24+
) && (
25+
github.event.sender.author_association == 'OWNER' ||
26+
github.event.sender.author_association == 'MEMBER' ||
27+
github.event.sender.author_association == 'COLLABORATOR' ||
28+
github.event.pull_request.author_association == 'OWNER' ||
29+
github.event.pull_request.author_association == 'MEMBER' ||
30+
github.event.pull_request.author_association == 'COLLABORATOR'
31+
)
2132
runs-on: ubuntu-latest
2233
permissions:
2334
contents: read
2435
pull-requests: read
2536
issues: read
2637
id-token: write
38+
actions: read # Required for Claude to read CI results on PRs
2739
steps:
28-
- name: Check user permissions
29-
id: check_membership
30-
uses: actions/github-script@v7
31-
with:
32-
script: |
33-
let actor;
34-
if (context.eventName === 'issue_comment') {
35-
actor = context.payload.comment.user.login;
36-
} else if (context.eventName === 'pull_request_review_comment') {
37-
actor = context.payload.comment.user.login;
38-
} else if (context.eventName === 'pull_request_review') {
39-
actor = context.payload.review.user.login;
40-
} else if (context.eventName === 'issues') {
41-
actor = context.payload.issue.user.login;
42-
}
43-
44-
console.log(`Checking permissions for user: ${actor}`);
45-
46-
// List of explicitly allowed users (organization members)
47-
const allowedUsers = [
48-
'phernandez',
49-
'groksrc',
50-
'nellins',
51-
'bm-claudeai'
52-
];
53-
54-
if (allowedUsers.includes(actor)) {
55-
console.log(`User ${actor} is in the allowed list`);
56-
core.setOutput('is_member', true);
57-
return;
58-
}
59-
60-
// Fallback: Check if user has repository permissions
61-
try {
62-
const collaboration = await github.rest.repos.getCollaboratorPermissionLevel({
63-
owner: context.repo.owner,
64-
repo: context.repo.repo,
65-
username: actor
66-
});
67-
68-
const permission = collaboration.data.permission;
69-
console.log(`User ${actor} has permission level: ${permission}`);
70-
71-
// Allow if user has push access or higher (write, maintain, admin)
72-
const allowed = ['write', 'maintain', 'admin'].includes(permission);
73-
74-
core.setOutput('is_member', allowed);
75-
76-
if (!allowed) {
77-
core.notice(`User ${actor} does not have sufficient repository permissions (has: ${permission})`);
78-
}
79-
} catch (error) {
80-
console.log(`Error checking permissions: ${error.message}`);
81-
82-
// Final fallback: Check if user is a public member of the organization
83-
try {
84-
const membership = await github.rest.orgs.getMembershipForUser({
85-
org: 'basicmachines-co',
86-
username: actor
87-
});
88-
89-
const allowed = membership.data.state === 'active';
90-
core.setOutput('is_member', allowed);
91-
92-
if (!allowed) {
93-
core.notice(`User ${actor} is not a public member of basicmachines-co organization`);
94-
}
95-
} catch (membershipError) {
96-
console.log(`Error checking organization membership: ${membershipError.message}`);
97-
core.setOutput('is_member', false);
98-
core.notice(`User ${actor} does not have access to this repository`);
99-
}
100-
}
101-
10240
- name: Checkout repository
103-
if: steps.check_membership.outputs.is_member == 'true'
10441
uses: actions/checkout@v4
10542
with:
43+
# For pull_request_target, checkout the PR head to review the actual changes
44+
ref: ${{ github.event_name == 'pull_request_target' && github.event.pull_request.head.sha || github.sha }}
10645
fetch-depth: 1
10746

10847
- name: Run Claude Code
109-
if: steps.check_membership.outputs.is_member == 'true'
11048
id: claude
111-
uses: anthropics/claude-code-action@beta
49+
uses: anthropics/claude-code-action@v1
11250
with:
113-
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
114-
allowed_tools: Bash(uv run pytest),Bash(uv run ruff check . --fix),Bash(uv run ruff format .),Bash(uv run pyright),Bash(just test),Bash(just lint),Bash(just format),Bash(just type-check),Bash(just check),Read,Write,Edit,MultiEdit,Glob,Grep,LS, mcp__web_search
51+
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
52+
track_progress: true # Enable visual progress tracking
53+
54+
# This is an optional setting that allows Claude to read CI results on PRs
55+
additional_permissions: |
56+
actions: read
57+
58+
# Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
59+
# prompt: 'Update the pull request description to include a summary of changes.'
60+
61+
# Optional: Add claude_args to customize behavior and configuration
62+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
63+
# or https://docs.claude.com/en/docs/claude-code/sdk#command-line for available options
64+
# claude_args: '--model claude-opus-4-1-20250805 --allowed-tools Bash(gh pr:*)'
65+

0 commit comments

Comments
 (0)