mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-22 22:44:13 +08:00
- Log entire raw response body in text, hex, and base64 formats - Capture complete request context including timing and memory usage - Add detailed error response parsing with fallback handling - Include environment and operation state context - Special handling for 500 errors with GitHub request IDs - Log all response headers including rate limit info
261 lines
8.3 KiB
TypeScript
261 lines
8.3 KiB
TypeScript
#!/usr/bin/env bun
|
|
// Test script that creates a new branch to test the commit_files flow
|
|
// Run with: bun test-with-new-branch.ts <github-pat> <owner> <repo>
|
|
|
|
const GITHUB_API_URL = "https://api.github.com";
|
|
|
|
async function testCommitFilesWithNewBranch(token: string, owner: string, repo: string) {
|
|
const headers = {
|
|
Accept: "application/vnd.github+json",
|
|
Authorization: `Bearer ${token}`,
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
};
|
|
|
|
// Create a unique branch name for testing
|
|
const timestamp = Date.now();
|
|
const testBranch = `claude-debug-500-test-${timestamp}`;
|
|
|
|
console.log(`\n=== Testing commit_files flow ===`);
|
|
console.log(`Repository: ${owner}/${repo}`);
|
|
console.log(`Test branch: ${testBranch}\n`);
|
|
|
|
try {
|
|
// First, get the default branch to branch from
|
|
console.log("Getting repository info...");
|
|
const repoResponse = await fetch(
|
|
`${GITHUB_API_URL}/repos/${owner}/${repo}`,
|
|
{ headers }
|
|
);
|
|
|
|
if (!repoResponse.ok) {
|
|
console.error(`Cannot access repository: ${repoResponse.status}`);
|
|
const error = await repoResponse.text();
|
|
console.error(error);
|
|
return;
|
|
}
|
|
|
|
const repoData = await repoResponse.json();
|
|
const defaultBranch = repoData.default_branch;
|
|
console.log(`✓ Default branch: ${defaultBranch}`);
|
|
|
|
// Get the SHA of the default branch
|
|
console.log(`\nGetting ${defaultBranch} branch SHA...`);
|
|
const defaultBranchResponse = await fetch(
|
|
`${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${defaultBranch}`,
|
|
{ headers }
|
|
);
|
|
|
|
if (!defaultBranchResponse.ok) {
|
|
console.error(`Cannot get default branch: ${defaultBranchResponse.status}`);
|
|
return;
|
|
}
|
|
|
|
const defaultBranchData = await defaultBranchResponse.json();
|
|
const baseSha = defaultBranchData.object.sha;
|
|
console.log(`✓ Base SHA: ${baseSha}`);
|
|
|
|
// Create a new branch
|
|
console.log(`\nCreating test branch: ${testBranch}...`);
|
|
const createBranchResponse = await fetch(
|
|
`${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs`,
|
|
{
|
|
method: "POST",
|
|
headers: {
|
|
...headers,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
ref: `refs/heads/${testBranch}`,
|
|
sha: baseSha,
|
|
}),
|
|
}
|
|
);
|
|
|
|
if (!createBranchResponse.ok) {
|
|
console.error(`Failed to create branch: ${createBranchResponse.status}`);
|
|
const error = await createBranchResponse.text();
|
|
console.error(error);
|
|
return;
|
|
}
|
|
|
|
console.log(`✓ Created test branch: ${testBranch}`);
|
|
|
|
// Now replicate the commit_files flow
|
|
console.log("\n--- Starting commit_files flow ---");
|
|
|
|
// Step 1: Get the branch reference (should be same as baseSha)
|
|
console.log("\nStep 1: Getting branch reference...");
|
|
const refUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${testBranch}`;
|
|
const refResponse = await fetch(refUrl, { headers });
|
|
|
|
if (!refResponse.ok) {
|
|
console.error(`Failed: ${refResponse.status}`);
|
|
return;
|
|
}
|
|
|
|
const refData = await refResponse.json();
|
|
console.log(`✓ Branch SHA: ${refData.object.sha}`);
|
|
|
|
// Step 2: Get the base commit
|
|
console.log("\nStep 2: Getting base commit...");
|
|
const commitUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/commits/${baseSha}`;
|
|
const commitResponse = await fetch(commitUrl, { headers });
|
|
|
|
if (!commitResponse.ok) {
|
|
console.error(`Failed: ${commitResponse.status}`);
|
|
return;
|
|
}
|
|
|
|
const commitData = await commitResponse.json();
|
|
const baseTreeSha = commitData.tree.sha;
|
|
console.log(`✓ Base tree SHA: ${baseTreeSha}`);
|
|
|
|
// Step 3: Create a new tree
|
|
console.log("\nStep 3: Creating new tree...");
|
|
const treeUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/trees`;
|
|
|
|
const testFileContent = `# Test file for debugging 500 error
|
|
# Created at: ${new Date().toISOString()}
|
|
# This simulates the commit_files operation from claude-code-action
|
|
|
|
def test_function():
|
|
# This simulates fixing a code issue
|
|
result = "Fixed code"
|
|
return result
|
|
`;
|
|
|
|
const treeBody = {
|
|
base_tree: baseTreeSha,
|
|
tree: [{
|
|
path: "test-debug-500.py",
|
|
mode: "100644",
|
|
type: "blob",
|
|
content: testFileContent,
|
|
}],
|
|
};
|
|
|
|
const treeResponse = await fetch(treeUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
...headers,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(treeBody),
|
|
});
|
|
|
|
if (!treeResponse.ok) {
|
|
console.error(`Failed to create tree: ${treeResponse.status}`);
|
|
const error = await treeResponse.text();
|
|
console.error(error);
|
|
return;
|
|
}
|
|
|
|
const treeData = await treeResponse.json();
|
|
console.log(`✓ Tree SHA: ${treeData.sha}`);
|
|
|
|
// Step 4: Create commit
|
|
console.log("\nStep 4: Creating commit...");
|
|
const newCommitUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/commits`;
|
|
const commitBody = {
|
|
message: "Test: Debugging 500 error in commit_files",
|
|
tree: treeData.sha,
|
|
parents: [baseSha],
|
|
};
|
|
|
|
const newCommitResponse = await fetch(newCommitUrl, {
|
|
method: "POST",
|
|
headers: {
|
|
...headers,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(commitBody),
|
|
});
|
|
|
|
if (!newCommitResponse.ok) {
|
|
console.error(`Failed to create commit: ${newCommitResponse.status}`);
|
|
const error = await newCommitResponse.text();
|
|
console.error(error);
|
|
return;
|
|
}
|
|
|
|
const newCommitData = await newCommitResponse.json();
|
|
console.log(`✓ Commit SHA: ${newCommitData.sha}`);
|
|
|
|
// Step 5: Update reference (this is where the 500 error happens)
|
|
console.log("\nStep 5: Updating branch reference (the critical step)...");
|
|
const updateRefUrl = `${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${testBranch}`;
|
|
const updateBody = {
|
|
sha: newCommitData.sha,
|
|
force: false,
|
|
};
|
|
|
|
console.log(`URL: PATCH ${updateRefUrl}`);
|
|
console.log(`Body: ${JSON.stringify(updateBody)}`);
|
|
|
|
const startTime = Date.now();
|
|
const updateRefResponse = await fetch(updateRefUrl, {
|
|
method: "PATCH",
|
|
headers: {
|
|
...headers,
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify(updateBody),
|
|
});
|
|
const duration = Date.now() - startTime;
|
|
|
|
console.log(`\nStatus: ${updateRefResponse.status} (took ${duration}ms)`);
|
|
console.log(`Headers:`, {
|
|
'x-ratelimit-remaining': updateRefResponse.headers.get('x-ratelimit-remaining'),
|
|
'x-github-request-id': updateRefResponse.headers.get('x-github-request-id'),
|
|
});
|
|
|
|
if (!updateRefResponse.ok) {
|
|
console.error(`\n✗ FAILED: ${updateRefResponse.status}`);
|
|
const errorText = await updateRefResponse.text();
|
|
console.error(`Error body: "${errorText}"`);
|
|
|
|
if (updateRefResponse.status === 500) {
|
|
console.error(`\n🔍 500 ERROR REPRODUCED!`);
|
|
console.error(`This confirms the issue exists with PAT as well.`);
|
|
console.error(`GitHub Request ID: ${updateRefResponse.headers.get('x-github-request-id')}`);
|
|
}
|
|
} else {
|
|
console.log(`\n✓ SUCCESS: Branch updated!`);
|
|
console.log(`The 500 error might be specific to certain conditions.`);
|
|
|
|
// Cleanup: delete the test branch
|
|
console.log(`\nCleaning up test branch...`);
|
|
const deleteResponse = await fetch(
|
|
`${GITHUB_API_URL}/repos/${owner}/${repo}/git/refs/heads/${testBranch}`,
|
|
{
|
|
method: "DELETE",
|
|
headers,
|
|
}
|
|
);
|
|
|
|
if (deleteResponse.ok) {
|
|
console.log(`✓ Test branch deleted`);
|
|
}
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error(`\nUnexpected error:`, error);
|
|
}
|
|
}
|
|
|
|
// Main execution
|
|
const [token, owner, repo] = process.argv.slice(2);
|
|
|
|
if (!token || !owner || !repo) {
|
|
console.log("Usage: bun test-with-new-branch.ts <github-pat> <owner> <repo>");
|
|
console.log("");
|
|
console.log("Examples:");
|
|
console.log(" bun test-with-new-branch.ts ghp_xxx myorg myrepo");
|
|
console.log(" bun test-with-new-branch.ts ghp_xxx anthropics anthropic");
|
|
console.log("");
|
|
console.log("This creates a test branch and replicates the commit_files flow.");
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log("Starting test with new branch...");
|
|
testCommitFilesWithNewBranch(token, owner, repo); |