mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-01-23 23:14:13 +08:00
Compare commits
3 Commits
ashwin/ver
...
ashwin/env
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8177a01b9e | ||
|
|
9f02f6f6d4 | ||
|
|
79cee96324 |
@@ -178,7 +178,7 @@ runs:
|
|||||||
echo "Base-action dependencies installed"
|
echo "Base-action dependencies installed"
|
||||||
cd -
|
cd -
|
||||||
# Install Claude Code globally
|
# Install Claude Code globally
|
||||||
curl -fsSL https://claude.ai/install.sh | bash -s 1.0.85
|
curl -fsSL https://claude.ai/install.sh | bash -s 1.0.86
|
||||||
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
||||||
|
|
||||||
- name: Setup Network Restrictions
|
- name: Setup Network Restrictions
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ runs:
|
|||||||
|
|
||||||
- name: Install Claude Code
|
- name: Install Claude Code
|
||||||
shell: bash
|
shell: bash
|
||||||
run: curl -fsSL https://claude.ai/install.sh | bash -s 1.0.85
|
run: curl -fsSL https://claude.ai/install.sh | bash -s 1.0.86
|
||||||
|
|
||||||
- name: Run Claude Code Action
|
- name: Run Claude Code Action
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|||||||
@@ -145,14 +145,6 @@ export async function runClaude(promptPath: string, options: ClaudeOptions) {
|
|||||||
|
|
||||||
console.log(`Prompt file size: ${promptSize} bytes`);
|
console.log(`Prompt file size: ${promptSize} bytes`);
|
||||||
|
|
||||||
// Log custom environment variables if any
|
|
||||||
const customEnvKeys = Object.keys(config.env).filter(
|
|
||||||
(key) => key !== "CLAUDE_ACTION_INPUTS_PRESENT",
|
|
||||||
);
|
|
||||||
if (customEnvKeys.length > 0) {
|
|
||||||
console.log(`Custom environment variables: ${customEnvKeys.join(", ")}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output to console
|
// Output to console
|
||||||
console.log(`Running Claude with prompt from file: ${config.promptPath}`);
|
console.log(`Running Claude with prompt from file: ${config.promptPath}`);
|
||||||
|
|
||||||
@@ -168,6 +160,11 @@ export async function runClaude(promptPath: string, options: ClaudeOptions) {
|
|||||||
pipeStream.destroy();
|
pipeStream.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log("yolo", process.env);
|
||||||
|
console.log("yolo running with", {
|
||||||
|
...process.env,
|
||||||
|
...config.env,
|
||||||
|
});
|
||||||
const claudeProcess = spawn("claude", config.claudeArgs, {
|
const claudeProcess = spawn("claude", config.claudeArgs, {
|
||||||
stdio: ["pipe", "pipe", "inherit"],
|
stdio: ["pipe", "pipe", "inherit"],
|
||||||
env: {
|
env: {
|
||||||
@@ -307,7 +304,10 @@ export async function runClaude(promptPath: string, options: ClaudeOptions) {
|
|||||||
await writeFile("output.txt", output);
|
await writeFile("output.txt", output);
|
||||||
|
|
||||||
// Process output.txt into JSON and save to execution file
|
// Process output.txt into JSON and save to execution file
|
||||||
const { stdout: jsonOutput } = await execAsync("jq -s '.' output.txt");
|
// Increase maxBuffer from Node.js default of 1MB to 10MB to handle large Claude outputs
|
||||||
|
const { stdout: jsonOutput } = await execAsync("jq -s '.' output.txt", {
|
||||||
|
maxBuffer: 10 * 1024 * 1024,
|
||||||
|
});
|
||||||
await writeFile(EXECUTION_FILE, jsonOutput);
|
await writeFile(EXECUTION_FILE, jsonOutput);
|
||||||
|
|
||||||
console.log(`Log saved to ${EXECUTION_FILE}`);
|
console.log(`Log saved to ${EXECUTION_FILE}`);
|
||||||
@@ -324,7 +324,10 @@ export async function runClaude(promptPath: string, options: ClaudeOptions) {
|
|||||||
if (output) {
|
if (output) {
|
||||||
try {
|
try {
|
||||||
await writeFile("output.txt", output);
|
await writeFile("output.txt", output);
|
||||||
const { stdout: jsonOutput } = await execAsync("jq -s '.' output.txt");
|
// Increase maxBuffer from Node.js default of 1MB to 10MB to handle large Claude outputs
|
||||||
|
const { stdout: jsonOutput } = await execAsync("jq -s '.' output.txt", {
|
||||||
|
maxBuffer: 10 * 1024 * 1024,
|
||||||
|
});
|
||||||
await writeFile(EXECUTION_FILE, jsonOutput);
|
await writeFile(EXECUTION_FILE, jsonOutput);
|
||||||
core.setOutput("execution_file", EXECUTION_FILE);
|
core.setOutput("execution_file", EXECUTION_FILE);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -367,7 +367,6 @@ server.tool(
|
|||||||
// We're seeing intermittent 403 "Resource not accessible by integration" errors
|
// We're seeing intermittent 403 "Resource not accessible by integration" errors
|
||||||
// on certain repos when updating git references. These appear to be transient
|
// on certain repos when updating git references. These appear to be transient
|
||||||
// GitHub API issues that succeed on retry.
|
// GitHub API issues that succeed on retry.
|
||||||
let lastErrorDetails: any = null;
|
|
||||||
await retryWithBackoff(
|
await retryWithBackoff(
|
||||||
async () => {
|
async () => {
|
||||||
const updateRefResponse = await fetch(updateRefUrl, {
|
const updateRefResponse = await fetch(updateRefUrl, {
|
||||||
@@ -386,48 +385,17 @@ server.tool(
|
|||||||
|
|
||||||
if (!updateRefResponse.ok) {
|
if (!updateRefResponse.ok) {
|
||||||
const errorText = await updateRefResponse.text();
|
const errorText = await updateRefResponse.text();
|
||||||
let errorJson: any = {};
|
|
||||||
try {
|
|
||||||
errorJson = JSON.parse(errorText);
|
|
||||||
} catch {
|
|
||||||
// If not JSON, use the text as-is
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect debugging information
|
|
||||||
const debugInfo = {
|
|
||||||
status: updateRefResponse.status,
|
|
||||||
statusText: updateRefResponse.statusText,
|
|
||||||
headers: Object.fromEntries(updateRefResponse.headers.entries()),
|
|
||||||
errorBody: errorJson || errorText,
|
|
||||||
context: {
|
|
||||||
repository: `${owner}/${repo}`,
|
|
||||||
branch: branch,
|
|
||||||
baseBranch: process.env.BASE_BRANCH,
|
|
||||||
targetSha: newCommitData.sha,
|
|
||||||
parentSha: baseSha,
|
|
||||||
isGitHubAction: !!process.env.GITHUB_ACTIONS,
|
|
||||||
eventName: process.env.GITHUB_EVENT_NAME,
|
|
||||||
isPR: process.env.IS_PR,
|
|
||||||
tokenLength: githubToken?.length || 0,
|
|
||||||
tokenPrefix: githubToken?.substring(0, 10) + "...",
|
|
||||||
apiUrl: updateRefUrl,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
lastErrorDetails = debugInfo;
|
|
||||||
|
|
||||||
const error = new Error(
|
const error = new Error(
|
||||||
`Failed to update reference: ${updateRefResponse.status} - ${errorText}\n\nDebug Info: ${JSON.stringify(debugInfo, null, 2)}`,
|
`Failed to update reference: ${updateRefResponse.status} - ${errorText}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Only retry on 403 errors - these are the intermittent failures we're targeting
|
// Only retry on 403 errors - these are the intermittent failures we're targeting
|
||||||
if (updateRefResponse.status === 403) {
|
if (updateRefResponse.status === 403) {
|
||||||
console.error("403 Error encountered (will retry):", debugInfo);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For non-403 errors, fail immediately without retry
|
// For non-403 errors, fail immediately without retry
|
||||||
console.error("Non-retryable error:", debugInfo);
|
console.error("Non-retryable error:", updateRefResponse.status);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -437,23 +405,7 @@ server.tool(
|
|||||||
maxDelayMs: 5000, // Max 5 seconds delay
|
maxDelayMs: 5000, // Max 5 seconds delay
|
||||||
backoffFactor: 2, // Double the delay each time
|
backoffFactor: 2, // Double the delay each time
|
||||||
},
|
},
|
||||||
).catch((error) => {
|
|
||||||
// If all retries failed, enhance the error message with collected details
|
|
||||||
if (lastErrorDetails) {
|
|
||||||
throw new Error(
|
|
||||||
`All retry attempts failed for ref update.\n\n` +
|
|
||||||
`Final error: ${error.message}\n\n` +
|
|
||||||
`Debugging hints:\n` +
|
|
||||||
`- Check if branch '${branch}' is protected and the GitHub App has bypass permissions\n` +
|
|
||||||
`- Verify the token has 'contents:write' permission for ${owner}/${repo}\n` +
|
|
||||||
`- Check for concurrent operations updating the same branch\n` +
|
|
||||||
`- Token appears to be: ${lastErrorDetails.context.tokenPrefix}\n` +
|
|
||||||
`- This may be a transient GitHub API issue if it works on retry\n\n` +
|
|
||||||
`Full debug details: ${JSON.stringify(lastErrorDetails, null, 2)}`,
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
});
|
|
||||||
|
|
||||||
const simplifiedResult = {
|
const simplifiedResult = {
|
||||||
commit: {
|
commit: {
|
||||||
@@ -621,7 +573,6 @@ server.tool(
|
|||||||
// We're seeing intermittent 403 "Resource not accessible by integration" errors
|
// We're seeing intermittent 403 "Resource not accessible by integration" errors
|
||||||
// on certain repos when updating git references. These appear to be transient
|
// on certain repos when updating git references. These appear to be transient
|
||||||
// GitHub API issues that succeed on retry.
|
// GitHub API issues that succeed on retry.
|
||||||
let lastErrorDetails: any = null;
|
|
||||||
await retryWithBackoff(
|
await retryWithBackoff(
|
||||||
async () => {
|
async () => {
|
||||||
const updateRefResponse = await fetch(updateRefUrl, {
|
const updateRefResponse = await fetch(updateRefUrl, {
|
||||||
@@ -640,52 +591,18 @@ server.tool(
|
|||||||
|
|
||||||
if (!updateRefResponse.ok) {
|
if (!updateRefResponse.ok) {
|
||||||
const errorText = await updateRefResponse.text();
|
const errorText = await updateRefResponse.text();
|
||||||
let errorJson: any = {};
|
|
||||||
try {
|
|
||||||
errorJson = JSON.parse(errorText);
|
|
||||||
} catch {
|
|
||||||
// If not JSON, use the text as-is
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collect debugging information
|
|
||||||
const debugInfo = {
|
|
||||||
status: updateRefResponse.status,
|
|
||||||
statusText: updateRefResponse.statusText,
|
|
||||||
headers: Object.fromEntries(updateRefResponse.headers.entries()),
|
|
||||||
errorBody: errorJson || errorText,
|
|
||||||
context: {
|
|
||||||
operation: "delete_files",
|
|
||||||
repository: `${owner}/${repo}`,
|
|
||||||
branch: branch,
|
|
||||||
baseBranch: process.env.BASE_BRANCH,
|
|
||||||
targetSha: newCommitData.sha,
|
|
||||||
parentSha: baseSha,
|
|
||||||
isGitHubAction: !!process.env.GITHUB_ACTIONS,
|
|
||||||
eventName: process.env.GITHUB_EVENT_NAME,
|
|
||||||
isPR: process.env.IS_PR,
|
|
||||||
tokenLength: githubToken?.length || 0,
|
|
||||||
tokenPrefix: githubToken?.substring(0, 10) + "...",
|
|
||||||
apiUrl: updateRefUrl,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
lastErrorDetails = debugInfo;
|
|
||||||
|
|
||||||
const error = new Error(
|
const error = new Error(
|
||||||
`Failed to update reference: ${updateRefResponse.status} - ${errorText}\n\nDebug Info: ${JSON.stringify(debugInfo, null, 2)}`,
|
`Failed to update reference: ${updateRefResponse.status} - ${errorText}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Only retry on 403 errors - these are the intermittent failures we're targeting
|
// Only retry on 403 errors - these are the intermittent failures we're targeting
|
||||||
if (updateRefResponse.status === 403) {
|
if (updateRefResponse.status === 403) {
|
||||||
console.error(
|
console.log("Received 403 error, will retry...");
|
||||||
"403 Error encountered during delete (will retry):",
|
|
||||||
debugInfo,
|
|
||||||
);
|
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For non-403 errors, fail immediately without retry
|
// For non-403 errors, fail immediately without retry
|
||||||
console.error("Non-retryable error during delete:", debugInfo);
|
console.error("Non-retryable error:", updateRefResponse.status);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -695,23 +612,7 @@ server.tool(
|
|||||||
maxDelayMs: 5000, // Max 5 seconds delay
|
maxDelayMs: 5000, // Max 5 seconds delay
|
||||||
backoffFactor: 2, // Double the delay each time
|
backoffFactor: 2, // Double the delay each time
|
||||||
},
|
},
|
||||||
).catch((error) => {
|
|
||||||
// If all retries failed, enhance the error message with collected details
|
|
||||||
if (lastErrorDetails) {
|
|
||||||
throw new Error(
|
|
||||||
`All retry attempts failed for ref update during file deletion.\n\n` +
|
|
||||||
`Final error: ${error.message}\n\n` +
|
|
||||||
`Debugging hints:\n` +
|
|
||||||
`- Check if branch '${branch}' is protected and the GitHub App has bypass permissions\n` +
|
|
||||||
`- Verify the token has 'contents:write' permission for ${owner}/${repo}\n` +
|
|
||||||
`- Check for concurrent operations updating the same branch\n` +
|
|
||||||
`- Token appears to be: ${lastErrorDetails.context.tokenPrefix}\n` +
|
|
||||||
`- This may be a transient GitHub API issue if it works on retry\n\n` +
|
|
||||||
`Full debug details: ${JSON.stringify(lastErrorDetails, null, 2)}`,
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
});
|
|
||||||
|
|
||||||
const simplifiedResult = {
|
const simplifiedResult = {
|
||||||
commit: {
|
commit: {
|
||||||
|
|||||||
Reference in New Issue
Block a user