verygoodplugins

.github/workflows/claude-auto-implement.yml

Aug 16th, 2025
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.32 KB | None | 0 0
  1. name: Claude Code - Auto Implementation
  2. on:
  3. issues:
  4. types: [labeled]
  5.  
  6. jobs:
  7. claude-implement:
  8. # Only run when the 'claude implement' label is added
  9. if: github.event.label.name == 'claude implement'
  10. runs-on: ubuntu-latest
  11. timeout-minutes: 30 # Prevent runaway processes
  12.  
  13. permissions:
  14. contents: write
  15. pull-requests: write
  16. issues: write
  17.  
  18. steps:
  19. # Step 1: Checkout the repository
  20. - name: Checkout Repository
  21. uses: actions/checkout@v4
  22.  
  23. # Step 2: Set up PHP environment for WordPress development
  24. - name: Setup PHP
  25. uses: shivammathur/setup-php@v2
  26. with:
  27. php-version: '8.1'
  28. tools: composer, wp-cli
  29. extensions: mysqli, pdo_mysql, zip, gd, mbstring, curl, xml, bcmath
  30.  
  31. # Step 3: Set up Node.js (required for Claude Code)
  32. - name: Setup Node.js
  33. uses: actions/setup-node@v4
  34. with:
  35. node-version: '20'
  36.  
  37. # Step 4: Install Composer dependencies if composer.json exists
  38. - name: Install PHP Dependencies
  39. if: hashFiles('composer.json') != ''
  40. run: composer install --no-progress --prefer-dist --no-dev
  41.  
  42. # Step 5: Extract issue details
  43. - name: Extract Issue Information
  44. id: issue_info
  45. uses: actions/github-script@v7
  46. with:
  47. github-token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
  48. script: |
  49. const issue = context.payload.issue;
  50. const issueNumber = issue.number;
  51. const issueTitle = issue.title;
  52. const issueBody = issue.body || '';
  53.  
  54. // Clean the issue body for use in branch name and commit messages
  55. const cleanTitle = issueTitle.toLowerCase()
  56. .replace(/[^a-z0-9]+/g, '-')
  57. .replace(/^-|-$/g, '')
  58. .substring(0, 50);
  59.  
  60. // Generate branch name following WP Fusion conventions
  61. const branchName = `feature/gh-issue-${issueNumber}-${cleanTitle}`;
  62.  
  63. // Output for use in next steps
  64. core.setOutput('issue_number', issueNumber);
  65. core.setOutput('issue_title', issueTitle);
  66. core.setOutput('issue_body', issueBody);
  67. core.setOutput('branch_name', branchName);
  68.  
  69. console.log(`Processing issue #${issueNumber}: ${issueTitle}`);
  70.  
  71. # Step 6: Create a new branch for the implementation
  72. - name: Create Feature Branch
  73. run: |
  74. git config --global user.name "Claude Code Bot"
  75. git config --global user.email "[email protected]"
  76.  
  77. # Check if branch exists on remote and delete it if it does
  78. if git ls-remote --heads origin ${{ steps.issue_info.outputs.branch_name }} | grep -q ${{ steps.issue_info.outputs.branch_name }}; then
  79. echo "Branch already exists on remote, deleting it first..."
  80. git push origin --delete ${{ steps.issue_info.outputs.branch_name }} || true
  81. fi
  82.  
  83. # Create and checkout the new branch
  84. git checkout -b ${{ steps.issue_info.outputs.branch_name }}
  85.  
  86. # Step 7: Run Claude Code to implement the fix/feature
  87. - name: Implement Fix with Claude Code
  88. id: claude_implementation
  89. uses: anthropics/claude-code-base-action@beta
  90. with:
  91. prompt: |
  92. You are working on the WP Fusion WordPress plugin located in the current directory. This is a WordPress plugin that syncs user data between WordPress and various CRM/marketing automation platforms.
  93.  
  94. Please implement the following based on issue #${{ steps.issue_info.outputs.issue_number }}:
  95.  
  96. Title: ${{ steps.issue_info.outputs.issue_title }}
  97.  
  98. Description:
  99. ${{ steps.issue_info.outputs.issue_body }}
  100.  
  101. IMPORTANT INSTRUCTIONS:
  102. 1. First, use GrepTool to search for files related to the issue described above
  103. 2. View only the most relevant files - don't try to read every file in the repository
  104. 3. Make targeted changes to fix the specific issue described - don't try to refactor unrelated code
  105. 4. Common locations in WP Fusion:
  106. - includes/ (core PHP logic and CRM integrations)
  107. - includes/admin/ (admin interface and settings)
  108. - includes/integrations/ (third-party plugin integrations)
  109. - includes/crms/ (CRM-specific implementations)
  110. - assets/js/ (JavaScript files)
  111. - assets/css/ (CSS stylesheets)
  112. 5. Identify the root cause of the issue and fix it with minimal changes
  113. 6. Follow WordPress coding standards
  114. 7. Ensure compatibility with PHP 7.4+ and WordPress 5.8+
  115.  
  116. AFTER implementing the fix, create a TEMPORARY file named `/tmp/pr-description.md` (NOT in the repository) with the following sections:
  117.  
  118. ## ๐Ÿ” Problem Identification
  119. [Explain what the root cause of the issue was]
  120.  
  121. ## ๐Ÿ’ก Solution Approach
  122. [Explain how you decided to fix it and why this approach was chosen]
  123.  
  124. ## ๐Ÿ› ๏ธ Implementation Details
  125. [List the specific changes made and which files were modified]
  126.  
  127. ## ๐Ÿงช Testing Instructions
  128. [Provide step-by-step instructions to test the fix]
  129.  
  130. ## โš ๏ธ Potential Side Effects
  131. [List any areas that should be checked for regressions]
  132.  
  133. BE EFFICIENT: Make only the necessary changes to fix the issue. Focus on solving the specific problem described.
  134. DO NOT create output.txt or any other files in the repository besides the actual fix.
  135.  
  136. claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
  137. allowed_tools: "View,Edit,Create,GlobTool,GrepTool,Bash"
  138. max_turns: 30
  139.  
  140. # Step 8: Run PHP Standards Enforcement
  141. - name: Enforce PHP Standards
  142. continue-on-error: true # Don't fail the workflow if standards checks fail
  143. run: |
  144. echo "๐Ÿ”ง Running PHP standards enforcement..."
  145.  
  146. # Configure Composer to allow the plugin
  147. composer global config --no-plugins allow-plugins.dealerdirect/phpcodesniffer-composer-installer true
  148.  
  149. # Install PHP CodeSniffer if not already available
  150. if ! command -v phpcs &> /dev/null; then
  151. composer global require "squizlabs/php_codesniffer=*"
  152. export PATH="$PATH:$(composer global config home --quiet)/vendor/bin"
  153. fi
  154.  
  155. # Install WordPress Coding Standards and additional dependencies
  156. if ! phpcs -i | grep -qi "WordPress"; then
  157. # Install all required packages including PHPCSUtils
  158. composer global require \
  159. "wp-coding-standards/wpcs:^3.0" \
  160. "phpcsstandards/phpcsutils:^1.0" \
  161. "phpcsstandards/phpcsextra:^1.0" \
  162. "sirbrillig/phpcs-variable-analysis:^2.0" \
  163. "phpcompatibility/php-compatibility:^9.3"
  164.  
  165. # Register all paths
  166. phpcs --config-set installed_paths \
  167. "$(composer global config home --quiet)/vendor/wp-coding-standards/wpcs,$(composer global config home --quiet)/vendor/phpcompatibility/php-compatibility,$(composer global config home --quiet)/vendor/phpcsstandards/phpcsutils,$(composer global config home --quiet)/vendor/phpcsstandards/phpcsextra,$(composer global config home --quiet)/vendor/sirbrillig/phpcs-variable-analysis"
  168. fi
  169.  
  170. # Run PHP CodeSniffer with WordPress standards
  171. if [ -f "phpcs.xml" ] || [ -f "phpcs.xml.dist" ]; then
  172. echo "Using project phpcs configuration"
  173. # Try to run with project config, but don't fail if there are issues
  174. phpcs --report=summary || echo "CodeSniffer completed with issues"
  175. else
  176. echo "Running with WordPress standards"
  177. phpcs --standard=WordPress --extensions=php --ignore=vendor/ . --report=summary || echo "CodeSniffer completed with issues"
  178. fi
  179.  
  180. # Run PHP Code Beautifier and Fixer
  181. if command -v phpcbf &> /dev/null; then
  182. echo "Running automatic code fixes..."
  183. if [ -f "phpcs.xml" ] || [ -f "phpcs.xml.dist" ]; then
  184. phpcbf || echo "Code beautifier completed"
  185. else
  186. phpcbf --standard=WordPress --extensions=php --ignore=vendor/ . || echo "Code beautifier completed"
  187. fi
  188. fi
  189.  
  190. # Step 9: Check if any changes were made
  191. - name: Check for Changes
  192. id: check_changes
  193. run: |
  194. # Remove output.txt if it was created (we don't want this)
  195. if [ -f "output.txt" ]; then
  196. echo "Removing output.txt file..."
  197. rm output.txt
  198. fi
  199.  
  200. if [[ -n $(git status --porcelain) ]]; then
  201. echo "changes=true" >> $GITHUB_OUTPUT
  202. echo "Changes detected, will create PR"
  203. git status --short
  204. else
  205. echo "changes=false" >> $GITHUB_OUTPUT
  206. echo "No changes made"
  207. fi
  208.  
  209. # Step 10: Commit and push changes
  210. - name: Commit Changes
  211. if: steps.check_changes.outputs.changes == 'true'
  212. run: |
  213. git add -A
  214. git commit -m "feat: ${{ steps.issue_info.outputs.issue_title }}
  215.  
  216. Automated implementation for issue #${{ steps.issue_info.outputs.issue_number }}
  217.  
  218. - Applied WordPress coding standards
  219. - Implemented requested functionality
  220. - Added appropriate error handling
  221.  
  222. This commit was automatically generated by Claude Code.
  223.  
  224. Closes #${{ steps.issue_info.outputs.issue_number }}"
  225.  
  226. # Force push to overwrite any existing branch
  227. git push --force origin ${{ steps.issue_info.outputs.branch_name }}
  228.  
  229. # Step 11: Create Pull Request
  230. - name: Create Pull Request
  231. if: steps.check_changes.outputs.changes == 'true'
  232. uses: actions/github-script@v7
  233. with:
  234. github-token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
  235. script: |
  236. const issueNumber = ${{ steps.issue_info.outputs.issue_number }};
  237. const branchName = '${{ steps.issue_info.outputs.branch_name }}';
  238. const issueTitle = `${{ steps.issue_info.outputs.issue_title }}`;
  239.  
  240. // Get repository default branch dynamically
  241. const { data: repo } = await github.rest.repos.get({
  242. owner: context.repo.owner,
  243. repo: context.repo.repo
  244. });
  245. const defaultBranch = repo.default_branch;
  246.  
  247. // Read the Claude-generated PR description if available
  248. const fs = require('fs');
  249. let claudeDescription = '';
  250.  
  251. try {
  252. const descFile = '/tmp/pr-description.md';
  253. if (fs.existsSync(descFile)) {
  254. claudeDescription = fs.readFileSync(descFile, 'utf8');
  255. console.log('Found Claude-generated PR description');
  256. // Delete the file after reading
  257. fs.unlinkSync(descFile);
  258. }
  259. } catch (e) {
  260. console.log('Could not read PR description file:', e.message);
  261. }
  262.  
  263. // Generate timestamp
  264. const timestamp = new Date().toISOString().replace('T', ' ').replace(/\.\d{3}Z$/, ' UTC');
  265.  
  266. // Create the PR body
  267. const prBody = claudeDescription ?
  268. `## ๐Ÿค– Automated Implementation for #${issueNumber}
  269.  
  270. ${claudeDescription}
  271.  
  272. ---
  273.  
  274. ### ๐Ÿ“‹ Issue Reference
  275. - **Issue:** #${issueNumber}
  276. - **Title:** ${issueTitle}
  277. - **Branch:** \`${branchName}\`
  278.  
  279. ### โš ๏ธ Review Requirements
  280. - [ ] Code review for quality and standards
  281. - [ ] Functional testing in development environment
  282. - [ ] Regression testing for related features
  283. - [ ] Performance impact assessment
  284. - [ ] Security review if applicable
  285.  
  286. ### ๐Ÿ”— Related
  287. Closes #${issueNumber}
  288.  
  289. ---
  290. *๐Ÿค– Generated by Claude Code GitHub Action*
  291. *๐Ÿ•’ Generated at: ${timestamp}*` :
  292. `## ๐Ÿš€ Automated Implementation
  293.  
  294. This pull request was automatically generated by Claude Code to address issue #${issueNumber}.
  295.  
  296. ### ๐Ÿ“‹ Issue Details
  297. - **Issue:** #${issueNumber}
  298. - **Title:** ${issueTitle}
  299. - **Branch:** \`${branchName}\`
  300.  
  301. ### ๐Ÿ”„ Changes Made
  302. Claude Code has analyzed and implemented a fix for this issue. Please review the file changes to understand the implementation.
  303.  
  304. ### ๐Ÿงช Testing Instructions
  305. 1. Review the implemented changes carefully
  306. 2. Test the specific functionality mentioned in the issue
  307. 3. Verify no regressions in related areas
  308. 4. Check error logs for any warnings or notices
  309.  
  310. ### โš ๏ธ Important Notes
  311. - This implementation was generated automatically
  312. - **Manual review is required** before merging
  313. - Test thoroughly in a staging environment
  314.  
  315. ### ๐Ÿ”— Related
  316. Closes #${issueNumber}
  317.  
  318. ---
  319. *๐Ÿค– Generated by Claude Code GitHub Action*
  320. *๐Ÿ•’ Generated at: ${timestamp}*`;
  321.  
  322. // Create the PR
  323. const { data: pr } = await github.rest.pulls.create({
  324. owner: context.repo.owner,
  325. repo: context.repo.repo,
  326. title: `๐Ÿค– Auto Implementation: ${issueTitle}`,
  327. body: prBody,
  328. head: branchName,
  329. base: defaultBranch,
  330. draft: true // Create as draft to require manual review
  331. });
  332.  
  333. console.log(`Created PR #${pr.number}: ${pr.html_url}`);
  334.  
  335. // Add labels to the PR
  336. try {
  337. await github.rest.issues.addLabels({
  338. owner: context.repo.owner,
  339. repo: context.repo.repo,
  340. issue_number: pr.number,
  341. labels: ['automated', 'needs-review', 'claude-code']
  342. });
  343. } catch (labelError) {
  344. console.log('Could not add labels (they may not exist):', labelError.message);
  345. }
  346.  
  347. // Add a comment on the original issue with summary
  348. const commentBody = claudeDescription ?
  349. `๐Ÿค– **Claude Code Implementation Complete**
  350.  
  351. I've analyzed this issue and created a pull request with the implementation: #${pr.number}
  352.  
  353. **Summary of changes:**
  354. ${claudeDescription.split('## ๐Ÿ” Problem Identification')[1]?.split('##')[0]?.trim() || 'See PR for details'}
  355.  
  356. **Next Steps:**
  357. 1. Review the PR description for full implementation details
  358. 2. Test the functionality as described in the PR
  359. 3. Check for any edge cases or regressions
  360. 4. Mark the PR as ready for review when satisfied
  361.  
  362. The PR is currently in **draft mode** to ensure manual review before merging.` :
  363. `๐Ÿค– **Claude Code Implementation Complete**
  364.  
  365. I've analyzed this issue and created a pull request with the implementation: #${pr.number}
  366.  
  367. **Next Steps:**
  368. 1. Review the generated code carefully
  369. 2. Test the functionality thoroughly
  370. 3. Check for any edge cases or regressions
  371. 4. Mark the PR as ready for review when satisfied
  372.  
  373. The PR is currently in **draft mode** to ensure manual review before merging.`;
  374.  
  375. await github.rest.issues.createComment({
  376. owner: context.repo.owner,
  377. repo: context.repo.repo,
  378. issue_number: issueNumber,
  379. body: commentBody
  380. });
  381.  
  382. # Step 12: Handle case where no changes were needed
  383. - name: Comment on Issue (No Changes)
  384. if: steps.check_changes.outputs.changes == 'false'
  385. uses: actions/github-script@v7
  386. with:
  387. github-token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
  388. script: |
  389. const issueNumber = ${{ steps.issue_info.outputs.issue_number }};
  390. await github.rest.issues.createComment({
  391. owner: context.repo.owner,
  392. repo: context.repo.repo,
  393. issue_number: issueNumber,
  394. body: `๐Ÿค– **Claude Code Analysis Complete**
  395.  
  396. I've analyzed this issue but determined that no code changes are needed at this time.
  397.  
  398. **Possible reasons:**
  399. - โœ… The functionality already exists
  400. - ๐Ÿ“ The issue needs more specific requirements
  401. - ๐Ÿ” The change requires manual investigation
  402. - ๐Ÿ› ๏ธ The implementation needs human expertise
  403.  
  404. **Recommendations:**
  405. 1. Review the issue description for clarity
  406. 2. Provide specific examples or use cases
  407. 3. Include steps to reproduce (for bugs)
  408. 4. Consider if this requires architectural changes
  409.  
  410. Feel free to add more details and re-apply the \`claude implement\` label.`
  411. });
  412.  
  413. # Step 13: Error handling
  414. - name: Handle Errors
  415. if: failure()
  416. uses: actions/github-script@v7
  417. with:
  418. github-token: ${{ secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}
  419. script: |
  420. const issueNumber = ${{ steps.issue_info.outputs.issue_number }};
  421. await github.rest.issues.createComment({
  422. owner: context.repo.owner,
  423. repo: context.repo.repo,
  424. issue_number: issueNumber,
  425. body: `๐Ÿ”ด **Claude Code Implementation Failed**
  426.  
  427. I encountered an error while trying to implement this issue.
  428.  
  429. **Common causes:**
  430. - ๐Ÿ”ง Complex requirements needing human expertise
  431. - ๐Ÿ“ Ambiguous or incomplete issue description
  432. - โš™๏ธ Technical limitations or dependencies
  433. - ๐Ÿ”’ Permissions or environment issues
  434.  
  435. **Next steps:**
  436. 1. Check the [workflow logs](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details
  437. 2. Consider implementing manually
  438. 3. Provide more specific requirements
  439. 4. Break down into smaller, focused issues
  440.  
  441. You can re-apply the \`claude implement\` label after addressing potential issues.`
  442. });
Advertisement
Add Comment
Please, Sign In to add comment