fix: Fix syntax errors and code formatting issues

- Fixed missing catch clause in handleWebhook function
- Removed extra closing braces causing syntax errors
- Fixed indentation issues throughout githubController.js
- Updated lint scripts for ESLint 9 flat config
- Applied automatic formatting fixes
- Fixed test data for check-suite tests

All tests now pass and code meets linting standards.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Jonathan Flatt
2025-05-22 21:49:42 +00:00
committed by Cheffromspace
parent 7182855dbe
commit 78815925da
4 changed files with 194 additions and 117 deletions

View File

@@ -14,8 +14,8 @@
"test:watch": "jest --watch",
"test:ci": "jest --ci --coverage",
"pretest": "./scripts/utils/ensure-test-dirs.sh",
"lint": "eslint src/ test/ --ext .js --fix",
"lint:check": "eslint src/ test/ --ext .js",
"lint": "eslint src/ test/ --fix",
"lint:check": "eslint src/ test/",
"format": "prettier --write src/ test/",
"format:check": "prettier --check src/ test/",
"security:audit": "npm audit --audit-level=moderate",

View File

@@ -426,89 +426,90 @@ Please check with an administrator to review the logs for more details.`
// Only proceed if the check suite is for a pull request and conclusion is success
if (checkSuite.conclusion === 'success' && checkSuite.pull_requests && checkSuite.pull_requests.length > 0) {
try {
for (const pr of checkSuite.pull_requests) {
// Verify ALL required status checks have passed using Combined Status API
let combinedStatus;
try {
// Verify ALL required status checks have passed using Combined Status API
let combinedStatus;
try {
// Use the check suite's head_sha if pr.head.sha is not available
const commitSha = pr.head?.sha || checkSuite.head_sha;
const commitSha = pr.head?.sha || checkSuite.head_sha;
if (!commitSha) {
logger.error(
{
repo: repo.full_name,
pr: pr.number,
prData: JSON.stringify(pr),
checkSuiteData: {
id: checkSuite.id,
head_sha: checkSuite.head_sha,
head_branch: checkSuite.head_branch
}
},
'No commit SHA available for PR - cannot check combined status'
);
continue;
}
if (!commitSha) {
logger.error(
{
repo: repo.full_name,
pr: pr.number,
prData: JSON.stringify(pr),
checkSuiteData: {
id: checkSuite.id,
head_sha: checkSuite.head_sha,
head_branch: checkSuite.head_branch
}
},
'No commit SHA available for PR - cannot check combined status'
);
continue;
}
logger.info(
{
repo: repo.full_name,
pr: pr.number,
prHeadSha: pr.head?.sha,
checkSuiteHeadSha: checkSuite.head_sha,
usingSha: commitSha
},
'Getting combined status for PR'
);
combinedStatus = await githubService.getCombinedStatus({
repoOwner: repo.owner.login,
repoName: repo.name,
ref: commitSha
});
// Only proceed if ALL status checks are successful
if (combinedStatus.state !== 'success') {
logger.info(
{
repo: repo.full_name,
pr: pr.number,
checkSuite: checkSuite.id,
combinedState: combinedStatus.state,
totalChecks: combinedStatus.total_count
prHeadSha: pr.head?.sha,
checkSuiteHeadSha: checkSuite.head_sha,
usingSha: commitSha
},
'Skipping PR review - not all required status checks have passed'
'Getting combined status for PR'
);
combinedStatus = await githubService.getCombinedStatus({
repoOwner: repo.owner.login,
repoName: repo.name,
ref: commitSha
});
// Only proceed if ALL status checks are successful
if (combinedStatus.state !== 'success') {
logger.info(
{
repo: repo.full_name,
pr: pr.number,
checkSuite: checkSuite.id,
combinedState: combinedStatus.state,
totalChecks: combinedStatus.total_count
},
'Skipping PR review - not all required status checks have passed'
);
continue;
}
} catch (error) {
logger.error(
{
err: error.message,
repo: repo.full_name,
pr: pr.number,
checkSuite: checkSuite.id
},
'Error checking combined status - skipping PR review'
);
continue;
}
} catch (error) {
logger.error(
logger.info(
{
err: error.message,
repo: repo.full_name,
pr: pr.number,
checkSuite: checkSuite.id
checkSuite: checkSuite.id,
conclusion: checkSuite.conclusion,
combinedState: combinedStatus.state,
totalChecks: combinedStatus.total_count
},
'Error checking combined status - skipping PR review'
'All checks passed - triggering automated PR review'
);
continue;
}
logger.info(
{
repo: repo.full_name,
pr: pr.number,
checkSuite: checkSuite.id,
conclusion: checkSuite.conclusion,
combinedState: combinedStatus.state,
totalChecks: combinedStatus.total_count
},
'All checks passed - triggering automated PR review'
);
try {
try {
// Create the PR review prompt
const prReviewPrompt = `## PR Review Workflow Instructions
const prReviewPrompt = `## PR Review Workflow Instructions
You are Claude, acting as a professional code reviewer through Claude Code CLI. Your task is to review GitHub pull requests and provide constructive feedback.
@@ -588,37 +589,37 @@ After completing the review, all output from this process will be automatically
Please perform a comprehensive review of PR #${pr.number} in repository ${repo.full_name}.`;
// Process the PR review with Claude
logger.info('Sending PR for automated Claude review');
const claudeResponse = await claudeService.processCommand({
repoFullName: repo.full_name,
issueNumber: pr.number,
command: prReviewPrompt,
isPullRequest: true,
branchName: pr.head.ref
});
// Process the PR review with Claude
logger.info('Sending PR for automated Claude review');
const claudeResponse = await claudeService.processCommand({
repoFullName: repo.full_name,
issueNumber: pr.number,
command: prReviewPrompt,
isPullRequest: true,
branchName: pr.head.ref
});
logger.info(
{
repo: repo.full_name,
pr: pr.number,
responseLength: claudeResponse ? claudeResponse.length : 0
},
'Automated PR review completed successfully'
);
} catch (error) {
logger.error(
{
errorMessage: error.message || 'Unknown error',
errorType: error.constructor.name,
repo: repo.full_name,
pr: pr.number,
checkSuite: checkSuite.id
},
'Error processing automated PR review'
);
logger.info(
{
repo: repo.full_name,
pr: pr.number,
responseLength: claudeResponse ? claudeResponse.length : 0
},
'Automated PR review completed successfully'
);
} catch (error) {
logger.error(
{
errorMessage: error.message || 'Unknown error',
errorType: error.constructor.name,
repo: repo.full_name,
pr: pr.number,
checkSuite: checkSuite.id
},
'Error processing automated PR review'
);
}
}
}
// Return success after processing all PRs
return res.status(200).json({
success: true,
@@ -630,32 +631,52 @@ Please perform a comprehensive review of PR #${pr.number} in repository ${repo.f
pullRequests: checkSuite.pull_requests.map(pr => pr.number)
}
});
} else if (checkSuite.head_branch) {
// If no pull requests in payload but we have a head_branch,
// this might be a PR from a fork - log for debugging
logger.warn(
} catch (error) {
logger.error(
{
err: error,
repo: repo.full_name,
checkSuite: checkSuite.id,
headBranch: checkSuite.head_branch,
headSha: checkSuite.head_sha
checkSuite: checkSuite.id
},
'Check suite succeeded but no pull requests found in payload - possible fork PR'
'Error processing check suite for PR reviews'
);
// TODO: Could query GitHub API to find PRs for this branch/SHA
// For now, just acknowledge the webhook
return res.status(200).json({
success: true,
message: 'Check suite completed but no PRs found in payload',
return res.status(500).json({
success: false,
error: 'Failed to process check suite',
message: error.message,
context: {
repo: repo.full_name,
checkSuite: checkSuite.id,
conclusion: checkSuite.conclusion,
headBranch: checkSuite.head_branch
type: 'check_suite'
}
});
}
} else if (checkSuite.head_branch) {
// If no pull requests in payload but we have a head_branch,
// this might be a PR from a fork - log for debugging
logger.warn(
{
repo: repo.full_name,
checkSuite: checkSuite.id,
headBranch: checkSuite.head_branch,
headSha: checkSuite.head_sha
},
'Check suite succeeded but no pull requests found in payload - possible fork PR'
);
// TODO: Could query GitHub API to find PRs for this branch/SHA
// For now, just acknowledge the webhook
return res.status(200).json({
success: true,
message: 'Check suite completed but no PRs found in payload',
context: {
repo: repo.full_name,
checkSuite: checkSuite.id,
conclusion: checkSuite.conclusion,
headBranch: checkSuite.head_branch
}
});
} else {
// Log the specific reason why PR review was not triggered
const reasons = [];

View File

@@ -1,17 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="jest tests" tests="6" failures="0" errors="0" time="0.321">
<testsuite name="GitHub Controller - Check Suite Events" errors="0" failures="0" skipped="0" timestamp="2025-05-22T21:32:17" time="0.279" tests="6">
<testsuites name="jest tests" tests="30" failures="0" errors="0" time="0.65">
<testsuite name="GitHub Controller - Check Suite Events" errors="0" failures="0" skipped="0" timestamp="2025-05-22T21:49:28" time="0.424" tests="6">
<testcase classname="GitHub Controller - Check Suite Events should trigger PR review when check suite succeeds with PRs" name="GitHub Controller - Check Suite Events should trigger PR review when check suite succeeds with PRs" time="0.005">
</testcase>
<testcase classname="GitHub Controller - Check Suite Events should not trigger PR review when check suite fails" name="GitHub Controller - Check Suite Events should not trigger PR review when check suite fails" time="0.001">
</testcase>
<testcase classname="GitHub Controller - Check Suite Events should not trigger PR review when check suite succeeds but has no PRs" name="GitHub Controller - Check Suite Events should not trigger PR review when check suite succeeds but has no PRs" time="0.001">
</testcase>
<testcase classname="GitHub Controller - Check Suite Events should handle multiple PRs in check suite" name="GitHub Controller - Check Suite Events should handle multiple PRs in check suite" time="0.002">
<testcase classname="GitHub Controller - Check Suite Events should handle multiple PRs in check suite" name="GitHub Controller - Check Suite Events should handle multiple PRs in check suite" time="0.001">
</testcase>
<testcase classname="GitHub Controller - Check Suite Events should handle Claude service errors gracefully" name="GitHub Controller - Check Suite Events should handle Claude service errors gracefully" time="0">
</testcase>
<testcase classname="GitHub Controller - Check Suite Events should use check suite head_sha when PR head.sha is missing" name="GitHub Controller - Check Suite Events should use check suite head_sha when PR head.sha is missing" time="0">
</testcase>
</testsuite>
<testsuite name="githubService" errors="0" failures="0" skipped="0" timestamp="2025-05-22T21:49:29" time="0.044" tests="10">
<testcase classname="githubService getFallbackLabels should identify bug labels correctly" name="githubService getFallbackLabels should identify bug labels correctly" time="0.001">
</testcase>
<testcase classname="githubService getFallbackLabels should identify feature labels correctly" name="githubService getFallbackLabels should identify feature labels correctly" time="0">
</testcase>
<testcase classname="githubService getFallbackLabels should identify enhancement labels correctly" name="githubService getFallbackLabels should identify enhancement labels correctly" time="0">
</testcase>
<testcase classname="githubService getFallbackLabels should identify question labels correctly" name="githubService getFallbackLabels should identify question labels correctly" time="0.001">
</testcase>
<testcase classname="githubService getFallbackLabels should identify documentation labels correctly" name="githubService getFallbackLabels should identify documentation labels correctly" time="0">
</testcase>
<testcase classname="githubService getFallbackLabels should default to medium priority when no specific priority keywords found" name="githubService getFallbackLabels should default to medium priority when no specific priority keywords found" time="0">
</testcase>
<testcase classname="githubService getFallbackLabels should handle empty descriptions gracefully" name="githubService getFallbackLabels should handle empty descriptions gracefully" time="0">
</testcase>
<testcase classname="githubService addLabelsToIssue - test mode should return mock data in test mode" name="githubService addLabelsToIssue - test mode should return mock data in test mode" time="0">
</testcase>
<testcase classname="githubService createRepositoryLabels - test mode should return labels array in test mode" name="githubService createRepositoryLabels - test mode should return labels array in test mode" time="0.001">
</testcase>
<testcase classname="githubService postComment - test mode should return mock comment data in test mode" name="githubService postComment - test mode should return mock comment data in test mode" time="0">
</testcase>
</testsuite>
<testsuite name="AWS Credential Provider" errors="0" failures="0" skipped="0" timestamp="2025-05-22T21:49:29" time="0.044" tests="7">
<testcase classname="AWS Credential Provider should get credentials from AWS profile" name="AWS Credential Provider should get credentials from AWS profile" time="0.001">
</testcase>
<testcase classname="AWS Credential Provider should cache credentials" name="AWS Credential Provider should cache credentials" time="0.001">
</testcase>
<testcase classname="AWS Credential Provider should clear credential cache" name="AWS Credential Provider should clear credential cache" time="0">
</testcase>
<testcase classname="AWS Credential Provider should get Docker environment variables" name="AWS Credential Provider should get Docker environment variables" time="0.001">
</testcase>
<testcase classname="AWS Credential Provider should throw error if AWS_PROFILE is not set" name="AWS Credential Provider should throw error if AWS_PROFILE is not set" time="0.008">
</testcase>
<testcase classname="AWS Credential Provider should throw error for non-existent profile" name="AWS Credential Provider should throw error for non-existent profile" time="0.001">
</testcase>
<testcase classname="AWS Credential Provider should throw error for incomplete credentials" name="AWS Credential Provider should throw error for incomplete credentials" time="0.001">
</testcase>
</testsuite>
<testsuite name="GitHub Controller" errors="0" failures="0" skipped="0" timestamp="2025-05-22T21:49:29" time="0.043" tests="4">
<testcase classname="GitHub Controller should process a valid webhook with @TestBot mention" name="GitHub Controller should process a valid webhook with @TestBot mention" time="0.002">
</testcase>
<testcase classname="GitHub Controller should reject a webhook with invalid signature" name="GitHub Controller should reject a webhook with invalid signature" time="0.008">
</testcase>
<testcase classname="GitHub Controller should ignore comments without @TestBot mention" name="GitHub Controller should ignore comments without @TestBot mention" time="0.001">
</testcase>
<testcase classname="GitHub Controller should handle errors from Claude service" name="GitHub Controller should handle errors from Claude service" time="0.005">
</testcase>
</testsuite>
<testsuite name="Container Execution E2E Tests" errors="0" failures="0" skipped="0" timestamp="2025-05-22T21:49:29" time="0.022" tests="3">
<testcase classname="Container Execution E2E Tests Container should be properly configured" name="Container Execution E2E Tests Container should be properly configured" time="0.001">
</testcase>
<testcase classname="Container Execution E2E Tests Should process a simple Claude request" name="Container Execution E2E Tests Should process a simple Claude request" time="0">
</testcase>
<testcase classname="Container Execution E2E Tests Should handle errors gracefully" name="Container Execution E2E Tests Should handle errors gracefully" time="0">
</testcase>
</testsuite>
</testsuites>

View File

@@ -86,9 +86,9 @@ app.post('/webhook', (req, res) => {
// Start server
app.listen(PORT, () => {
logger.info({ port: PORT }, `Debug webhook server listening on port ${PORT}`);
console.log(`\nTo test this webhook receiver:`);
console.log('\nTo test this webhook receiver:');
console.log(`1. Configure your GitHub webhook to point to: http://YOUR_SERVER:${PORT}/webhook`);
console.log(`2. Make sure to include check_suite events in the webhook configuration`);
console.log(`3. Trigger a check suite completion in your repository`);
console.log(`4. Check the logs above for detailed information\n`);
console.log('2. Make sure to include check_suite events in the webhook configuration');
console.log('3. Trigger a check suite completion in your repository');
console.log('4. Check the logs above for detailed information\n');
});