# 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: ```yaml 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) 1. **Deploy the MCP server fixes** - This alone saves 6 minutes 2. **Monitor the logs** to confirm MCP servers shut down immediately after Claude completes ### Short-term Optimizations 1. **Switch to the optimized workflow** (remove container layer) for additional 5-6 minute savings 2. **Test with different runner configurations** if available in your Gitea setup ### Long-term Optimizations 1. **Build and use custom container image** with pre-installed dependencies 2. **Consider runner-level optimizations**: - Use SSD storage for faster Docker operations - Allocate more resources to runners - Use local Docker registry for faster image pulls 3. **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 issues - `write: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_token` parameter - Setting `CLAUDE_CODE_OAUTH_TOKEN` environment variable ## Monitoring After implementing these changes, monitor: 1. MCP server shutdown logs - Should show "Stdin closed, shutting down..." 2. Total step execution times in Gitea UI 3. 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.