mirror of
https://github.com/xtr-dev/payload-billing.git
synced 2025-12-10 10:53:23 +00:00
- Add multi-level permission checking for issue implementation workflow - Support multiple permission strategies: privileged users, admins only, combined, org-based - Add permission validation with detailed error messages - Restrict code review workflow to privileged users and repository members - Create permission configuration file (.github/claude-config.json) - Add comprehensive permission documentation Permission strategies available: - Privileged users only (most restrictive) - Repository admins only - Admins OR privileged users (default) - Organization members with write access - Everyone with write access (least restrictive) Current configuration: - Issue implementation: admins OR privileged users (bastiaan, xtr-dev-team) - Code reviews: privileged users and repository members only 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
332 lines
13 KiB
YAML
332 lines
13 KiB
YAML
name: Claude Issue Implementation
|
|
|
|
on:
|
|
issue_comment:
|
|
types: [created]
|
|
|
|
permissions:
|
|
contents: write
|
|
issues: write
|
|
pull-requests: write
|
|
id-token: write
|
|
|
|
jobs:
|
|
claude-implement:
|
|
if: |
|
|
github.event.issue_comment.issue.state == 'open' &&
|
|
(
|
|
contains(github.event.comment.body, '@claude implement') ||
|
|
contains(github.event.comment.body, '@claude fix') ||
|
|
contains(github.event.comment.body, '@claude create')
|
|
)
|
|
runs-on: ubuntu-latest
|
|
|
|
steps:
|
|
- name: Check user permissions
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const username = context.actor;
|
|
|
|
// Method 1: Specific privileged users list
|
|
const privilegedUsers = [
|
|
'bastiaan', // Repository owner
|
|
'xtr-dev-team', // Core team members
|
|
// Add more usernames here
|
|
];
|
|
|
|
// Method 2: Check repository permission level
|
|
const { data: collaborator } = await github.rest.repos.getCollaboratorPermissionLevel({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
username: username
|
|
});
|
|
|
|
// Method 3: Check organization membership (if applicable)
|
|
let isOrgMember = false;
|
|
try {
|
|
await github.rest.orgs.getMembershipForUser({
|
|
org: context.repo.owner,
|
|
username: username
|
|
});
|
|
isOrgMember = true;
|
|
} catch (error) {
|
|
// User is not an org member or org doesn't exist
|
|
isOrgMember = false;
|
|
}
|
|
|
|
// Combined permission check
|
|
const isPrivilegedUser = privilegedUsers.includes(username);
|
|
const hasAdminAccess = collaborator.permission === 'admin';
|
|
const hasWriteAccess = ['admin', 'write'].includes(collaborator.permission);
|
|
|
|
// Choose your permission strategy:
|
|
// Option A: Only specific users
|
|
const allowedByUserList = isPrivilegedUser;
|
|
|
|
// Option B: Only admins
|
|
const allowedByAdminAccess = hasAdminAccess;
|
|
|
|
// Option C: Admin + specific users
|
|
const allowedByAdminOrPrivileged = hasAdminAccess || isPrivilegedUser;
|
|
|
|
// Option D: Organization members with write access
|
|
const allowedByOrgAndWrite = isOrgMember && hasWriteAccess;
|
|
|
|
// Set your chosen strategy here:
|
|
const isAllowed = allowedByAdminOrPrivileged; // Change this line to use your preferred strategy
|
|
|
|
if (!isAllowed) {
|
|
const errorMessage = `❌ **Access Denied**: Claude implementation is restricted to privileged users only.
|
|
|
|
**Your access level**: ${collaborator.permission}
|
|
**Privileged user**: ${isPrivilegedUser ? 'Yes' : 'No'}
|
|
**Organization member**: ${isOrgMember ? 'Yes' : 'No'}
|
|
|
|
Contact a repository administrator for access.`;
|
|
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
body: errorMessage
|
|
});
|
|
throw new Error('Insufficient permissions for Claude implementation');
|
|
}
|
|
|
|
// Log successful access
|
|
console.log(`✅ Access granted to ${username} (${collaborator.permission})`);
|
|
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
with:
|
|
fetch-depth: 0
|
|
token: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Set up Node.js
|
|
uses: actions/setup-node@v4
|
|
with:
|
|
node-version: '22'
|
|
cache: 'npm'
|
|
|
|
- name: Install pnpm
|
|
run: npm install -g pnpm@10.12.4
|
|
|
|
- name: Create Claude implementation branch
|
|
id: create-branch
|
|
run: |
|
|
# Create a unique branch name based on issue number and timestamp
|
|
BRANCH_NAME="claude/issue-${{ github.event.issue.number }}-$(date +%Y%m%d-%H%M%S)"
|
|
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
|
|
|
|
# Create and switch to the new branch
|
|
git checkout -b "$BRANCH_NAME"
|
|
git push origin "$BRANCH_NAME"
|
|
|
|
- name: Add comment with implementation start
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
body: `🤖 **Claude Implementation Started**
|
|
|
|
I'm now working on implementing this issue. Here's what I'm doing:
|
|
|
|
📋 **Issue**: #${{ github.event.issue.number }} - ${{ github.event.issue.title }}
|
|
🌿 **Branch**: \`${{ steps.create-branch.outputs.branch_name }}\`
|
|
⏱️ **Started**: ${new Date().toISOString()}
|
|
|
|
I'll analyze the requirements and create a pull request with the implementation. This may take a few minutes...
|
|
|
|
You can track the progress in the [Actions tab](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}).`
|
|
});
|
|
|
|
- name: Implement with Claude
|
|
id: implementation
|
|
uses: anthropics/claude-code-action@beta
|
|
with:
|
|
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
|
|
|
# Direct prompt with issue context
|
|
direct_prompt: |
|
|
Please implement the feature or fix described in this GitHub issue:
|
|
|
|
**Issue #${{ github.event.issue.number }}**: ${{ github.event.issue.title }}
|
|
|
|
**Issue Description**:
|
|
${{ github.event.issue.body }}
|
|
|
|
**Implementation Request**:
|
|
${{ github.event.comment.body }}
|
|
|
|
**Instructions**:
|
|
1. Analyze the issue requirements carefully
|
|
2. Follow the existing code patterns and conventions in this PayloadCMS plugin
|
|
3. Add appropriate tests if needed (check for existing test patterns)
|
|
4. Update documentation if necessary
|
|
5. Ensure the implementation is complete and working
|
|
6. Use TypeScript with proper typing
|
|
7. Follow the project's ESM module structure with .js extensions
|
|
|
|
The implementation should be production-ready and follow best practices for a PayloadCMS plugin.
|
|
|
|
**Repository Context**: This is the @xtr-dev/payload-billing plugin for PayloadCMS.
|
|
**Branch**: ${{ steps.create-branch.outputs.branch_name }}
|
|
|
|
# Allow Claude to run necessary commands
|
|
allowed_tools: "Bash(pnpm build),Bash(pnpm typecheck),Bash(pnpm lint),Bash(npm run test)"
|
|
|
|
- name: Check for changes
|
|
id: changes
|
|
run: |
|
|
if git diff --quiet; then
|
|
echo "has_changes=false" >> $GITHUB_OUTPUT
|
|
echo "No changes were made during implementation"
|
|
else
|
|
echo "has_changes=true" >> $GITHUB_OUTPUT
|
|
echo "Changes detected, preparing commit"
|
|
fi
|
|
|
|
- name: Commit changes
|
|
if: steps.changes.outputs.has_changes == 'true'
|
|
run: |
|
|
git config --local user.email "action@github.com"
|
|
git config --local user.name "Claude Implementation Bot"
|
|
|
|
git add .
|
|
git commit -m "$(cat <<'EOF'
|
|
feat: implement issue #${{ github.event.issue.number }} - ${{ github.event.issue.title }}
|
|
|
|
Implemented via Claude automation based on issue requirements.
|
|
|
|
Issue: #${{ github.event.issue.number }}
|
|
Requested by: @${{ github.event.comment.user.login }}
|
|
|
|
🤖 Generated with Claude Automation
|
|
|
|
Co-Authored-By: Claude <noreply@anthropic.com>
|
|
EOF
|
|
)"
|
|
|
|
git push origin ${{ steps.create-branch.outputs.branch_name }}
|
|
|
|
- name: Create Pull Request
|
|
if: steps.changes.outputs.has_changes == 'true'
|
|
uses: actions/github-script@v7
|
|
id: create-pr
|
|
with:
|
|
script: |
|
|
const { data: pr } = await github.rest.pulls.create({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
title: `🤖 Implement: ${{ github.event.issue.title }}`,
|
|
head: '${{ steps.create-branch.outputs.branch_name }}',
|
|
base: 'dev',
|
|
body: `## 🤖 Claude Implementation
|
|
|
|
This PR was automatically created by Claude to implement the feature/fix requested in issue #${{ github.event.issue.number }}.
|
|
|
|
### 📋 Issue Details
|
|
- **Issue**: #${{ github.event.issue.number }}
|
|
- **Title**: ${{ github.event.issue.title }}
|
|
- **Requested by**: @${{ github.event.comment.user.login }}
|
|
- **Branch**: \`${{ steps.create-branch.outputs.branch_name }}\`
|
|
|
|
### 🔍 Implementation
|
|
Claude analyzed the issue requirements and implemented the requested changes following the project's coding standards and best practices.
|
|
|
|
### ✅ Review Checklist
|
|
- [ ] Code follows project conventions
|
|
- [ ] Tests are included (if applicable)
|
|
- [ ] Documentation is updated (if needed)
|
|
- [ ] Implementation matches issue requirements
|
|
- [ ] No breaking changes (unless intended)
|
|
|
|
### 🔗 Related
|
|
Closes #${{ github.event.issue.number }}
|
|
|
|
---
|
|
|
|
**Note**: This implementation was generated automatically. Please review carefully before merging.
|
|
|
|
🤖 *Generated with Claude Automation*`
|
|
});
|
|
|
|
return pr.number;
|
|
|
|
- name: Update issue with success
|
|
if: steps.changes.outputs.has_changes == 'true'
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
body: `✅ **Implementation Complete!**
|
|
|
|
I've successfully implemented the requested changes and created a pull request:
|
|
|
|
🎯 **Pull Request**: #${{ steps.create-pr.outputs.result }}
|
|
🌿 **Branch**: \`${{ steps.create-branch.outputs.branch_name }}\`
|
|
⏱️ **Completed**: ${new Date().toISOString()}
|
|
|
|
## Next Steps
|
|
1. Review the implementation in the pull request
|
|
2. Test the changes locally if needed
|
|
3. Merge the PR if everything looks good
|
|
|
|
The implementation follows the project's coding standards and includes appropriate documentation.`
|
|
});
|
|
|
|
- name: Update issue with no changes
|
|
if: steps.changes.outputs.has_changes == 'false'
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
body: `⚠️ **Implementation Completed - No Changes**
|
|
|
|
I analyzed the issue but determined that no code changes are needed. This might be because:
|
|
|
|
- The feature is already implemented
|
|
- The issue requires clarification
|
|
- The request is not actionable as a code change
|
|
- Additional information is needed
|
|
|
|
🌿 **Branch**: \`${{ steps.create-branch.outputs.branch_name }}\` (will be cleaned up)
|
|
|
|
Please review the issue requirements and provide additional details if needed.`
|
|
});
|
|
|
|
- name: Clean up branch if no changes
|
|
if: steps.changes.outputs.has_changes == 'false'
|
|
run: |
|
|
git push origin --delete ${{ steps.create-branch.outputs.branch_name }} || true
|
|
|
|
- name: Handle implementation failure
|
|
if: failure()
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
await github.rest.issues.createComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
issue_number: context.issue.number,
|
|
body: `❌ **Implementation Failed**
|
|
|
|
I encountered an error while trying to implement this issue. Please check the [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
|
|
|
|
Common reasons for failure:
|
|
- Issue requirements are unclear or incomplete
|
|
- Technical constraints prevent implementation
|
|
- Repository permissions or configuration issues
|
|
|
|
You can try again by commenting \`@claude implement\` or provide more specific requirements.`
|
|
}); |