mirror of
https://github.com/markwylde/claude-code-gitea-action.git
synced 2026-02-20 02:22:49 +08:00
Attempt to make this work
This commit is contained in:
@@ -75,7 +75,7 @@ jobs:
|
|||||||
| `direct_prompt` | Direct prompt for Claude to execute automatically without needing a trigger (for automated workflows) | No | - |
|
| `direct_prompt` | Direct prompt for Claude to execute automatically without needing a trigger (for automated workflows) | No | - |
|
||||||
| `timeout_minutes` | Timeout in minutes for execution | No | `30` |
|
| `timeout_minutes` | Timeout in minutes for execution | No | `30` |
|
||||||
| `github_token` | GitHub token for Claude to operate with. **Only include this if you're connecting a custom GitHub app of your own!** | No | - |
|
| `github_token` | GitHub token for Claude to operate with. **Only include this if you're connecting a custom GitHub app of your own!** | No | - |
|
||||||
| `gitea_api_url` | Gitea API URL (e.g., `https://gitea.example.com/api/v1`) for Gitea installations. Leave empty for GitHub. | No | GitHub API |
|
| `gitea_api_url` | Gitea server URL (e.g., `https://gitea.example.com`) for Gitea installations. Leave empty for GitHub. | No | GitHub API |
|
||||||
| `model` | Model to use (provider-specific format required for Bedrock/Vertex) | No | - |
|
| `model` | Model to use (provider-specific format required for Bedrock/Vertex) | No | - |
|
||||||
| `anthropic_model` | **DEPRECATED**: Use `model` instead. Kept for backward compatibility. | No | - |
|
| `anthropic_model` | **DEPRECATED**: Use `model` instead. Kept for backward compatibility. | No | - |
|
||||||
| `use_bedrock` | Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API | No | `false` |
|
| `use_bedrock` | Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API | No | `false` |
|
||||||
@@ -96,7 +96,7 @@ This action has been enhanced to work with Gitea installations. The main differe
|
|||||||
|
|
||||||
1. **Local Git Operations**: Instead of using API-based file operations (which have limited support in Gitea), this action uses local git commands to create branches, commit files, and push changes.
|
1. **Local Git Operations**: Instead of using API-based file operations (which have limited support in Gitea), this action uses local git commands to create branches, commit files, and push changes.
|
||||||
|
|
||||||
2. **API URL Configuration**: You must specify your Gitea API URL using the `gitea_api_url` input.
|
2. **API URL Configuration**: You must specify your Gitea server URL using the `gitea_api_url` input.
|
||||||
|
|
||||||
### Example Gitea Workflow
|
### Example Gitea Workflow
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ jobs:
|
|||||||
- uses: anthropics/claude-code-action@beta
|
- uses: anthropics/claude-code-action@beta
|
||||||
with:
|
with:
|
||||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||||
gitea_api_url: "https://gitea.example.com/api/v1"
|
gitea_api_url: "https://gitea.example.com"
|
||||||
github_token: ${{ secrets.GITEA_TOKEN }}
|
github_token: ${{ secrets.GITEA_TOKEN }}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ inputs:
|
|||||||
description: "GitHub token with repo and pull request permissions (defaults to GITHUB_TOKEN)"
|
description: "GitHub token with repo and pull request permissions (defaults to GITHUB_TOKEN)"
|
||||||
required: false
|
required: false
|
||||||
gitea_api_url:
|
gitea_api_url:
|
||||||
description: "Gitea API URL (e.g., https://gitea.example.com/api/v1, defaults to GitHub API)"
|
description: "Gitea server URL (e.g., https://gitea.example.com, defaults to GitHub API)"
|
||||||
required: false
|
required: false
|
||||||
use_bedrock:
|
use_bedrock:
|
||||||
description: "Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API"
|
description: "Use Amazon Bedrock with OIDC authentication instead of direct Anthropic API"
|
||||||
|
|||||||
@@ -29,8 +29,11 @@ const BASE_ALLOWED_TOOLS = [
|
|||||||
"LS",
|
"LS",
|
||||||
"Read",
|
"Read",
|
||||||
"Write",
|
"Write",
|
||||||
"mcp__github_file_ops__commit_files",
|
"mcp__local_git_ops__commit_files",
|
||||||
"mcp__github_file_ops__delete_files",
|
"mcp__local_git_ops__delete_files",
|
||||||
|
"mcp__local_git_ops__push_branch",
|
||||||
|
"mcp__local_git_ops__create_pull_request",
|
||||||
|
"mcp__local_git_ops__git_status",
|
||||||
];
|
];
|
||||||
const DISALLOWED_TOOLS = ["WebSearch", "WebFetch"];
|
const DISALLOWED_TOOLS = ["WebSearch", "WebFetch"];
|
||||||
|
|
||||||
@@ -530,13 +533,13 @@ ${context.directPrompt ? ` - DIRECT INSTRUCTION: A direct instruction was prov
|
|||||||
${
|
${
|
||||||
eventData.isPR && !eventData.claudeBranch
|
eventData.isPR && !eventData.claudeBranch
|
||||||
? `
|
? `
|
||||||
- Push directly using mcp__github_file_ops__commit_files to the existing branch (works for both new and existing files).
|
- Push directly using mcp__local_git_ops__commit_files to the existing branch (works for both new and existing files).
|
||||||
- Use mcp__github_file_ops__commit_files to commit files atomically in a single commit (supports single or multiple files).
|
- Use mcp__local_git_ops__commit_files to commit files atomically in a single commit (supports single or multiple files).
|
||||||
- When pushing changes with this tool and TRIGGER_USERNAME is not "Unknown", include a "Co-authored-by: ${context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>" line in the commit message.`
|
- When pushing changes with this tool and TRIGGER_USERNAME is not "Unknown", include a "Co-authored-by: ${context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>" line in the commit message.`
|
||||||
: `
|
: `
|
||||||
- You are already on the correct branch (${eventData.claudeBranch || "the PR branch"}). Do not create a new branch.
|
- You are already on the correct branch (${eventData.claudeBranch || "the PR branch"}). Do not create a new branch.
|
||||||
- Push changes directly to the current branch using mcp__github_file_ops__commit_files (works for both new and existing files)
|
- Push changes directly to the current branch using mcp__local_git_ops__commit_files (works for both new and existing files)
|
||||||
- Use mcp__github_file_ops__commit_files to commit files atomically in a single commit (supports single or multiple files).
|
- Use mcp__local_git_ops__commit_files to commit files atomically in a single commit (supports single or multiple files).
|
||||||
- When pushing changes and TRIGGER_USERNAME is not "Unknown", include a "Co-authored-by: ${context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>" line in the commit message.
|
- When pushing changes and TRIGGER_USERNAME is not "Unknown", include a "Co-authored-by: ${context.triggerUsername} <${context.triggerUsername}@users.noreply.github.com>" line in the commit message.
|
||||||
${
|
${
|
||||||
eventData.claudeBranch
|
eventData.claudeBranch
|
||||||
@@ -571,7 +574,7 @@ ${context.directPrompt ? ` - DIRECT INSTRUCTION: A direct instruction was prov
|
|||||||
- Always update the GitHub comment to reflect the current todo state.
|
- Always update the GitHub comment to reflect the current todo state.
|
||||||
- When all todos are completed, remove the spinner and add a brief summary of what was accomplished, and what was not done.
|
- When all todos are completed, remove the spinner and add a brief summary of what was accomplished, and what was not done.
|
||||||
- Note: If you see previous Claude comments with headers like "**Claude finished @user's task**" followed by "---", do not include this in your comment. The system adds this automatically.
|
- Note: If you see previous Claude comments with headers like "**Claude finished @user's task**" followed by "---", do not include this in your comment. The system adds this automatically.
|
||||||
- If you changed any files locally, you must update them in the remote branch via mcp__github_file_ops__commit_files before saying that you're done.
|
- If you changed any files locally, you must update them in the remote branch via mcp__local_git_ops__commit_files before saying that you're done.
|
||||||
${eventData.claudeBranch ? `- If you created anything in your branch, your comment must include the PR URL with prefilled title and body mentioned above.` : ""}
|
${eventData.claudeBranch ? `- If you created anything in your branch, your comment must include the PR URL with prefilled title and body mentioned above.` : ""}
|
||||||
|
|
||||||
Important Notes:
|
Important Notes:
|
||||||
@@ -581,10 +584,10 @@ Important Notes:
|
|||||||
- You communicate exclusively by editing your single comment - not through any other means.
|
- You communicate exclusively by editing your single comment - not through any other means.
|
||||||
- Use this spinner HTML when work is in progress: <img src="https://github.com/user-attachments/assets/5ac382c7-e004-429b-8e35-7feb3e8f9c6f" width="14px" height="14px" style="vertical-align: middle; margin-left: 4px;" />
|
- Use this spinner HTML when work is in progress: <img src="https://github.com/user-attachments/assets/5ac382c7-e004-429b-8e35-7feb3e8f9c6f" width="14px" height="14px" style="vertical-align: middle; margin-left: 4px;" />
|
||||||
${eventData.isPR && !eventData.claudeBranch ? `- Always push to the existing branch when triggered on a PR.` : `- IMPORTANT: You are already on the correct branch (${eventData.claudeBranch || "the created branch"}). Never create new branches when triggered on issues or closed/merged PRs.`}
|
${eventData.isPR && !eventData.claudeBranch ? `- Always push to the existing branch when triggered on a PR.` : `- IMPORTANT: You are already on the correct branch (${eventData.claudeBranch || "the created branch"}). Never create new branches when triggered on issues or closed/merged PRs.`}
|
||||||
- Use mcp__github_file_ops__commit_files for making commits (works for both new and existing files, single or multiple). Use mcp__github_file_ops__delete_files for deleting files (supports deleting single or multiple files atomically), or mcp__github__delete_file for deleting a single file. Edit files locally, and the tool will read the content from the same path on disk.
|
- Use mcp__local_git_ops__commit_files for making commits (works for both new and existing files, single or multiple). Use mcp__local_git_ops__delete_files for deleting files (supports deleting single or multiple files atomically), or mcp__github__delete_file for deleting a single file. Edit files locally, and the tool will read the content from the same path on disk.
|
||||||
Tool usage examples:
|
Tool usage examples:
|
||||||
- mcp__github_file_ops__commit_files: {"files": ["path/to/file1.js", "path/to/file2.py"], "message": "feat: add new feature"}
|
- mcp__local_git_ops__commit_files: {"files": ["path/to/file1.js", "path/to/file2.py"], "message": "feat: add new feature"}
|
||||||
- mcp__github_file_ops__delete_files: {"files": ["path/to/old.js"], "message": "chore: remove deprecated file"}
|
- mcp__local_git_ops__delete_files: {"files": ["path/to/old.js"], "message": "chore: remove deprecated file"}
|
||||||
- Display the todo list as a checklist in the GitHub comment and mark things off as you go.
|
- Display the todo list as a checklist in the GitHub comment and mark things off as you go.
|
||||||
- REPOSITORY SETUP INSTRUCTIONS: The repository's CLAUDE.md file(s) contain critical repo-specific setup instructions, development guidelines, and preferences. Always read and follow these files, particularly the root CLAUDE.md, as they provide essential context for working with the codebase effectively.
|
- REPOSITORY SETUP INSTRUCTIONS: The repository's CLAUDE.md file(s) contain critical repo-specific setup instructions, development guidelines, and preferences. Always read and follow these files, particularly the root CLAUDE.md, as they provide essential context for working with the codebase effectively.
|
||||||
- Use h3 headers (###) for section titles in your comments, not h1 headers (#).
|
- Use h3 headers (###) for section titles in your comments, not h1 headers (#).
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ export async function setupBranch(
|
|||||||
console.log(`Working in directory: ${repoDir}`);
|
console.log(`Working in directory: ${repoDir}`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Check if we're in a git repository
|
||||||
|
console.log(`Checking if we're in a git repository...`);
|
||||||
|
await $`git status`;
|
||||||
|
|
||||||
// Ensure we have the latest version of the source branch
|
// Ensure we have the latest version of the source branch
|
||||||
console.log(`Fetching latest ${sourceBranch}...`);
|
console.log(`Fetching latest ${sourceBranch}...`);
|
||||||
await $`git fetch origin ${sourceBranch}`;
|
await $`git fetch origin ${sourceBranch}`;
|
||||||
@@ -109,18 +113,38 @@ export async function setupBranch(
|
|||||||
await $`git checkout ${sourceBranch}`;
|
await $`git checkout ${sourceBranch}`;
|
||||||
|
|
||||||
// Pull latest changes
|
// Pull latest changes
|
||||||
|
console.log(`Pulling latest changes for ${sourceBranch}...`);
|
||||||
await $`git pull origin ${sourceBranch}`;
|
await $`git pull origin ${sourceBranch}`;
|
||||||
|
|
||||||
// Create and checkout the new branch
|
// Create and checkout the new branch
|
||||||
console.log(`Creating new branch: ${newBranch}`);
|
console.log(`Creating new branch: ${newBranch}`);
|
||||||
await $`git checkout -b ${newBranch}`;
|
await $`git checkout -b ${newBranch}`;
|
||||||
|
|
||||||
console.log(`Successfully created and checked out branch: ${newBranch}`);
|
// Verify the branch was created
|
||||||
} catch (gitError: any) {
|
const currentBranch = await $`git branch --show-current`;
|
||||||
console.log(
|
console.log(
|
||||||
`Local git operations completed. Branch ${newBranch} ready for use.`,
|
`Current branch after creation: ${currentBranch.stdout.trim()}`,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (currentBranch.stdout.trim() === newBranch) {
|
||||||
|
console.log(
|
||||||
|
`✅ Successfully created and checked out branch: ${newBranch}`,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Branch creation failed. Expected ${newBranch}, got ${currentBranch.stdout.trim()}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (gitError: any) {
|
||||||
|
console.error(`❌ Git operations failed:`, gitError);
|
||||||
|
console.error(`Error message: ${gitError.message}`);
|
||||||
|
console.error(`Error stdout: ${gitError.stdout}`);
|
||||||
|
console.error(`Error stderr: ${gitError.stderr}`);
|
||||||
|
|
||||||
|
// This is a critical failure - the branch MUST be created for Claude to work
|
||||||
|
throw new Error(
|
||||||
|
`Failed to create branch ${newBranch}: ${gitError.message}`,
|
||||||
);
|
);
|
||||||
// Don't fail here - the branch will be created when files are committed
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(`Branch setup completed for: ${newBranch}`);
|
console.log(`Branch setup completed for: ${newBranch}`);
|
||||||
|
|||||||
@@ -258,6 +258,54 @@ server.tool(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Delete files tool
|
||||||
|
server.tool(
|
||||||
|
"delete_files",
|
||||||
|
"Delete one or more files and commit the deletion using local git operations",
|
||||||
|
{
|
||||||
|
files: z
|
||||||
|
.array(z.string())
|
||||||
|
.describe(
|
||||||
|
'Array of file paths relative to repository root (e.g. ["src/old-file.js", "docs/deprecated.md"])',
|
||||||
|
),
|
||||||
|
message: z.string().describe("Commit message for the deletion"),
|
||||||
|
},
|
||||||
|
async ({ files, message }) => {
|
||||||
|
try {
|
||||||
|
// Remove the specified files
|
||||||
|
for (const file of files) {
|
||||||
|
const filePath = file.startsWith("/") ? file.slice(1) : file;
|
||||||
|
runGitCommand(`git rm "${filePath}"`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commit the deletions
|
||||||
|
runGitCommand(`git commit -m "${message}"`);
|
||||||
|
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Successfully deleted and committed ${files.length} file(s): ${files.join(", ")}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
const errorMessage =
|
||||||
|
error instanceof Error ? error.message : String(error);
|
||||||
|
return {
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: "text",
|
||||||
|
text: `Error deleting files: ${errorMessage}`,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
error: errorMessage,
|
||||||
|
isError: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// Get git status tool
|
// Get git status tool
|
||||||
server.tool("git_status", "Get the current git status", {}, async () => {
|
server.tool("git_status", "Get the current git status", {}, async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user