- Update all workflows to use our forked claude-code-gitea-action - Switch from API key to OAuth authentication using claude_credentials - Update model to claude-opus-4-20250514 - Fix parameter names (hyphen to underscore): gitea_token, claude_git_name/email - Update runs-on to ubuntu-latest for all workflows - Remove deprecated gitea-url parameter
4.6 KiB
Claude Code Gitea Action Performance Analysis
Executive Summary
The Claude Code Gitea Action was experiencing significant performance issues, with total execution times of ~20 minutes for simple tasks that should complete in 2-3 minutes. This analysis identifies the root causes and provides solutions that can reduce execution time to 5-7 minutes.
Performance Breakdown
Current State (Before Optimizations)
- Total execution time: ~20 minutes
- Claude AI Assistant step: 10m51s
- Actual Claude execution: ~2.5 minutes
- Setup/installation: ~2 minutes
- MCP server shutdown wait: ~6 minutes
- Job cleanup: 7-9 minutes
Root Causes Identified
1. MCP Server Shutdown Issues (6 minutes delay)
The MCP servers (gitea-mcp-server.ts and local-git-ops-server.ts) were not shutting down properly after Claude completed execution. They use StdioServerTransport which keeps stdin/stdout connections open, waiting for an EOF signal that never arrived.
Impact: 6 minutes of unnecessary waiting
2. Container Layering
The workflow uses a nested container setup:
runs-on: ubuntu-latest
container:
image: node:18-bullseye
This creates multiple container layers that significantly increase cleanup time.
Impact: 5-6 minutes of additional cleanup time
3. Failed Cache Attempts
Multiple components attempt to use caching but fail with timeout errors:
- Bun package cache
- Node.js cache
- npm cache
Impact: 10-20 seconds per cache attempt, plus error noise in logs
4. Duplicate Package Installation
The action installs packages twice:
- First bun install for action dependencies
- Second bun install for claude-code package
Impact: ~3-4 seconds (minor but unnecessary)
Implemented Solutions
1. Fixed MCP Server Shutdown
Added proper shutdown handling to both MCP servers:
- Listen for stdin EOF signal
- Properly close transport connections
- Add signal handlers for SIGTERM, SIGINT, SIGHUP
- 5-minute timeout as safety net
Expected savings: 6 minutes
2. Disabled Caching
Added cache: false to Bun setup to avoid timeout errors.
Expected savings: 10-20 seconds, cleaner logs
3. Created Optimized Workflow
Provided claude-optimized.yml that removes the container layer.
Expected savings: 5-6 minutes in cleanup time
4. Custom Container Option
Created Dockerfile.runner for a pre-built container with all dependencies.
Expected savings: 1-2 minutes in setup time
Expected Results
With Current Workflow + MCP Fixes
- Total time: ~11-13 minutes (down from 20)
- Savings: ~7-9 minutes (35-45% improvement)
With Optimized Workflow (No Container Layer)
- Total time: ~6-7 minutes (down from 20)
- Savings: ~13-14 minutes (65-70% improvement)
With Custom Pre-built Container
- Total time: ~5-6 minutes (down from 20)
- Savings: ~14-15 minutes (70-75% improvement)
Recommendations
Immediate Actions (No Infrastructure Changes)
- Deploy the MCP server fixes - This alone saves 6 minutes
- Monitor the logs to confirm MCP servers shut down immediately after Claude completes
Short-term Optimizations
- Switch to the optimized workflow (remove container layer) for additional 5-6 minute savings
- Test with different runner configurations if available in your Gitea setup
Long-term Optimizations
- Build and use custom container image with pre-installed dependencies
- Consider runner-level optimizations:
- Use SSD storage for faster Docker operations
- Allocate more resources to runners
- Use local Docker registry for faster image pulls
- Optimize the base action to reduce duplicate installations
Additional Findings
Token Permissions
The action requires specific token scopes:
write:repository- For code changes (already working)write:issue- For commenting on issueswrite:pull_request- For creating PRs
Ensure your RUNNER_ACCESS_TOKEN has all required scopes.
OAuth Authentication
OAuth authentication via claude_credentials is working correctly after:
- Extracting access token from credentials JSON
- Passing via
claude_code_oauth_tokenparameter - Setting
CLAUDE_CODE_OAUTH_TOKENenvironment variable
Monitoring
After implementing these changes, monitor:
- MCP server shutdown logs - Should show "Stdin closed, shutting down..."
- Total step execution times in Gitea UI
- Any remaining timeout or connection errors
Conclusion
The performance issues were primarily caused by improper MCP server shutdown handling and unnecessary container layering. The implemented fixes should reduce execution time by 65-75%, bringing a 20-minute workflow down to 5-7 minutes.