fix: Standardize Docker image naming and improve environment variable handling (#159)

* fix: Standardize Docker image naming and improve environment variable handling

- Standardize on 'claudecode:latest' image name across the codebase
  - Update build script to use claudecode:latest instead of claude-code-runner:latest
  - Fix health check to use CLAUDE_CONTAINER_IMAGE env var dynamically

- Improve environment variable handling for git configuration
  - Pass BOT_EMAIL and BOT_USERNAME to containers
  - Entrypoint scripts already use these with appropriate defaults

- Add comprehensive environment variables documentation
  - Document all 90+ environment variables used in the project
  - Identify hard-coded values that could be made configurable
  - Update .env.example with missing variables

This ensures consistency in Docker image naming and allows proper git
configuration in containers using the configured bot identity.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Add BOT_EMAIL to docker-compose.yml

- Add BOT_EMAIL environment variable to docker-compose.yml
- Ensures git configuration in containers uses proper email address
- Complements the previous changes for environment variable handling

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Use BOT_USERNAME environment variable in prompt creation

- Fix undefined BOT_USERNAME reference in createPrompt function
- Change prompt to use actual bot username instead of hardcoded "Claude"
- Makes the prompt more accurate: "You are @MCPClaude" instead of "You are Claude"

This fixes the PR review functionality that was broken due to the
undefined variable reference.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Add verbose and stream-json output to Claude CLI for better debugging

- Add --verbose flag to see detailed Claude processing
- Add --output-format stream-json for structured output
- Helps diagnose issues with PR review and other operations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Use colon syntax for allowedTools in PR review to match auto-tagging

- Change from space syntax Bash(gh *) to colon syntax Bash(gh:*)
- This matches the working syntax used in auto-tagging
- Should fix the permission issues preventing PR reviews from posting

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* feat: Add Claude Code timeout configuration for unattended mode

- Add BASH_DEFAULT_TIMEOUT_MS (10 minutes) and BASH_MAX_TIMEOUT_MS (20 minutes)
- Pass timeout environment variables to Claude container
- Document new timeout settings in .env.example and environment-variables.md
- Better defaults for webhook mode where builds/tests may take longer

These timeouts are more suitable for unattended PR reviews and other
operations that might involve long-running commands like builds or tests.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Cheffromspace
2025-06-01 15:50:51 -05:00
committed by GitHub
parent faa60f4f55
commit 14785b2e64
8 changed files with 249 additions and 6 deletions

View File

@@ -55,10 +55,20 @@ CLAUDE_HUB_DIR=/home/user/.claude-hub
# Container Settings
CLAUDE_USE_CONTAINERS=1
CLAUDE_CONTAINER_IMAGE=claudecode:latest
CLAUDE_CONTAINER_PRIVILEGED=false
REPO_CACHE_DIR=/tmp/repo-cache
REPO_CACHE_MAX_AGE_MS=3600000
CONTAINER_LIFETIME_MS=7200000 # Container execution timeout in milliseconds (default: 2 hours)
# Claude Code Timeout Settings (for unattended mode)
BASH_DEFAULT_TIMEOUT_MS=600000 # Default timeout for bash commands (10 minutes)
BASH_MAX_TIMEOUT_MS=1200000 # Maximum timeout Claude can set (20 minutes)
# Container Resource Limits
CLAUDE_CONTAINER_CPU_SHARES=1024
CLAUDE_CONTAINER_MEMORY_LIMIT=2g
CLAUDE_CONTAINER_PIDS_LIMIT=256
# AWS Bedrock Credentials for Claude (if using Bedrock)
AWS_ACCESS_KEY_ID=your_aws_access_key_id
AWS_SECRET_ACCESS_KEY=your_aws_secret_access_key
@@ -76,6 +86,7 @@ CLAUDE_CONTAINER_CAP_NET_RAW=true
CLAUDE_CONTAINER_CAP_SYS_TIME=false
CLAUDE_CONTAINER_CAP_DAC_OVERRIDE=true
CLAUDE_CONTAINER_CAP_AUDIT_WRITE=true
CLAUDE_CONTAINER_CAP_SYS_ADMIN=false
# PR Review Configuration
PR_REVIEW_WAIT_FOR_ALL_CHECKS=true
@@ -86,3 +97,18 @@ PR_REVIEW_CONDITIONAL_TIMEOUT_MS=300000
# Test Configuration
TEST_REPO_FULL_NAME=owner/repo
# Security Configuration (optional)
# DISABLE_LOG_REDACTION=false # WARNING: Only enable for debugging, exposes sensitive data in logs
# File-based Secrets (optional, takes priority over environment variables)
# GITHUB_TOKEN_FILE=/run/secrets/github_token
# ANTHROPIC_API_KEY_FILE=/run/secrets/anthropic_api_key
# GITHUB_WEBHOOK_SECRET_FILE=/run/secrets/webhook_secret
# Authentication Methods (optional)
# CLAUDE_AUTH_HOST_DIR=/path/to/claude/auth # For setup container authentication
# CLI Configuration (optional)
# API_URL=http://localhost:3003 # Default API URL for CLI tool
# WEBHOOK_URL=http://localhost:3002/api/webhooks/github # Webhook endpoint URL

View File

@@ -13,6 +13,7 @@ services:
- TRUST_PROXY=${TRUST_PROXY:-true}
- AUTHORIZED_USERS=${AUTHORIZED_USERS:-Cheffromspace}
- BOT_USERNAME=${BOT_USERNAME:-@MCPClaude}
- BOT_EMAIL=${BOT_EMAIL:-claude@example.com}
- DEFAULT_GITHUB_OWNER=${DEFAULT_GITHUB_OWNER:-Cheffromspace}
- DEFAULT_GITHUB_USER=${DEFAULT_GITHUB_USER:-Cheffromspace}
- DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}
@@ -20,6 +21,9 @@ services:
- CLAUDE_CONTAINER_IMAGE=claudecode:latest
- CLAUDE_AUTH_HOST_DIR=${CLAUDE_AUTH_HOST_DIR:-${HOME}/.claude-hub}
- DISABLE_LOG_REDACTION=true
# Claude Code timeout settings for unattended mode
- BASH_DEFAULT_TIMEOUT_MS=${BASH_DEFAULT_TIMEOUT_MS:-600000} # 10 minutes default
- BASH_MAX_TIMEOUT_MS=${BASH_MAX_TIMEOUT_MS:-1200000} # 20 minutes max
# Smart wait for all meaningful checks by default, or use specific workflow trigger
- PR_REVIEW_WAIT_FOR_ALL_CHECKS=${PR_REVIEW_WAIT_FOR_ALL_CHECKS:-true}
- PR_REVIEW_TRIGGER_WORKFLOW=${PR_REVIEW_TRIGGER_WORKFLOW:-}

View File

@@ -0,0 +1,204 @@
# Environment Variables Documentation
This document provides a comprehensive list of all environment variables used in the Claude GitHub Webhook project.
## Table of Contents
- [Core Application Configuration](#core-application-configuration)
- [Bot Configuration](#bot-configuration)
- [GitHub Configuration](#github-configuration)
- [Claude/Anthropic Configuration](#claudeanthropic-configuration)
- [Container Configuration](#container-configuration)
- [AWS Configuration](#aws-configuration)
- [PR Review Configuration](#pr-review-configuration)
- [Security & Secrets Configuration](#security--secrets-configuration)
- [Rate Limiting Configuration](#rate-limiting-configuration)
- [Health Check Configuration](#health-check-configuration)
- [Development/Test Variables](#developmenttest-variables)
- [Shell Script Variables](#shell-script-variables)
- [Hard-coded Values That Could Be Configurable](#hard-coded-values-that-could-be-configurable)
## Core Application Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `NODE_ENV` | Application environment (development/production/test) | `development` | No |
| `PORT` | Server port | `3002` | No |
| `TRUST_PROXY` | Trust proxy headers for X-Forwarded-For | `false` | No |
## Bot Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `BOT_USERNAME` | GitHub username the bot responds to (e.g., @ClaudeBot) | - | Yes |
| `BOT_EMAIL` | Email used for git commits by the bot | - | Yes |
| `DEFAULT_AUTHORIZED_USER` | Default authorized GitHub username | - | No |
| `AUTHORIZED_USERS` | Comma-separated list of authorized GitHub usernames | - | No |
## GitHub Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `GITHUB_TOKEN` | GitHub personal access token | - | Yes |
| `GITHUB_WEBHOOK_SECRET` | Secret for validating GitHub webhook payloads | - | Yes |
| `DEFAULT_GITHUB_OWNER` | Default GitHub organization/owner | - | No |
| `DEFAULT_GITHUB_USER` | Default GitHub username | - | No |
| `DEFAULT_BRANCH` | Default git branch | `main` | No |
| `TEST_REPO_FULL_NAME` | Test repository in owner/repo format | - | No |
## Claude/Anthropic Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `ANTHROPIC_API_KEY` | Anthropic API key for Claude access | - | Yes* |
| `ANTHROPIC_MODEL` | Model name | `us.anthropic.claude-3-7-sonnet-20250219-v1:0` | No |
| `CLAUDE_CODE_USE_BEDROCK` | Whether to use AWS Bedrock for Claude (0/1) | `0` | No |
| `CLAUDE_HUB_DIR` | Directory for Claude Hub config | `~/.claude-hub` | No |
| `CLAUDE_AUTH_HOST_DIR` | Host directory for Claude authentication | - | No |
*Required unless using AWS Bedrock or setup container authentication
## Container Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `CLAUDE_USE_CONTAINERS` | Enable container execution (0/1) | `1` | No |
| `CLAUDE_CONTAINER_IMAGE` | Docker image for Claude containers | `claudecode:latest` | No |
| `CLAUDE_CONTAINER_PRIVILEGED` | Run containers in privileged mode | `false` | No |
| `CLAUDE_CONTAINER_CAP_NET_RAW` | Add NET_RAW capability | `true` | No |
| `CLAUDE_CONTAINER_CAP_SYS_TIME` | Add SYS_TIME capability | `false` | No |
| `CLAUDE_CONTAINER_CAP_DAC_OVERRIDE` | Add DAC_OVERRIDE capability | `true` | No |
| `CLAUDE_CONTAINER_CAP_AUDIT_WRITE` | Add AUDIT_WRITE capability | `true` | No |
| `CLAUDE_CONTAINER_CPU_SHARES` | CPU shares for containers | `1024` | No |
| `CLAUDE_CONTAINER_MEMORY_LIMIT` | Memory limit for containers | `2g` | No |
| `CLAUDE_CONTAINER_PIDS_LIMIT` | Process limit for containers | `256` | No |
| `CONTAINER_LIFETIME_MS` | Container execution timeout in milliseconds | `7200000` (2 hours) | No |
| `REPO_CACHE_DIR` | Directory for repository cache | `/tmp/repo-cache` | No |
| `REPO_CACHE_MAX_AGE_MS` | Max age for cached repos in milliseconds | `3600000` (1 hour) | No |
## Claude Code Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `BASH_DEFAULT_TIMEOUT_MS` | Default timeout for bash commands in Claude Code | `600000` (10 minutes) | No |
| `BASH_MAX_TIMEOUT_MS` | Maximum timeout Claude can set for bash commands | `1200000` (20 minutes) | No |
## AWS Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `AWS_ACCESS_KEY_ID` | AWS access key ID | - | No* |
| `AWS_SECRET_ACCESS_KEY` | AWS secret access key | - | No* |
| `AWS_SESSION_TOKEN` | AWS session token (for temporary credentials) | - | No |
| `AWS_SECURITY_TOKEN` | Alternative name for session token | - | No |
| `AWS_REGION` | AWS region | `us-east-1` | No |
| `AWS_PROFILE` | AWS profile name | - | No |
| `USE_AWS_PROFILE` | Use AWS profile instead of direct credentials | `false` | No |
| `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` | ECS container credentials URI | - | No |
*Required if using AWS Bedrock for Claude
## PR Review Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `PR_REVIEW_WAIT_FOR_ALL_CHECKS` | Wait for all checks before PR review | `true` | No |
| `PR_REVIEW_TRIGGER_WORKFLOW` | Specific workflow name to trigger PR review | - | No |
| `PR_REVIEW_DEBOUNCE_MS` | Delay before checking all check suites | `5000` | No |
| `PR_REVIEW_MAX_WAIT_MS` | Max wait for in-progress checks | `1800000` (30 min) | No |
| `PR_REVIEW_CONDITIONAL_TIMEOUT_MS` | Timeout for conditional jobs | `300000` (5 min) | No |
## Security & Secrets Configuration
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `GITHUB_TOKEN_FILE` | Path to file containing GitHub token | `/run/secrets/github_token` | No |
| `ANTHROPIC_API_KEY_FILE` | Path to file containing Anthropic API key | `/run/secrets/anthropic_api_key` | No |
| `GITHUB_WEBHOOK_SECRET_FILE` | Path to file containing webhook secret | `/run/secrets/webhook_secret` | No |
| `DISABLE_LOG_REDACTION` | Disable credential redaction in logs | `false` | No |
## Rate Limiting Configuration
These values are currently hard-coded but could be made configurable:
| Value | Description | Current Value | Location |
|-------|-------------|---------------|----------|
| Rate limit window | API rate limit time window | 15 minutes | `src/index.ts:32` |
| Rate limit max requests | Max API requests per window | 100 | `src/index.ts:41` |
| Webhook rate limit window | Webhook rate limit time window | 5 minutes | `src/index.ts:50` |
| Webhook rate limit max requests | Max webhook requests per window | 50 | `src/index.ts:51` |
## Health Check Configuration
These values are defined in docker-compose.yml:
| Value | Description | Current Value |
|-------|-------------|---------------|
| Health check interval | Time between health checks | 30s |
| Health check timeout | Timeout for each health check | 10s |
| Health check retries | Number of retries before unhealthy | 3 |
| Health check start period | Grace period on startup | 10s |
## Development/Test Variables
| Variable | Description | Default | Required |
|----------|-------------|---------|----------|
| `API_URL` | API URL for testing | `http://localhost:3003` | No |
| `WEBHOOK_URL` | Webhook URL for testing | - | No |
| `CLAUDE_API_AUTH_REQUIRED` | Require auth for Claude API | `false` | No |
| `CLAUDE_API_AUTH_TOKEN` | Auth token for Claude API | - | No |
| `HOME` | User home directory | - | No |
| `WORKSPACE_PATH` | GitHub Actions workspace path | - | No |
| `GITHUB_WORKSPACE` | GitHub Actions workspace | - | No |
## Shell Script Variables
| Variable | Description | Used In |
|----------|-------------|---------|
| `ALLOWED_TOOLS` | Tools allowed for Claude execution | entrypoint scripts |
| `OPERATION_TYPE` | Type of operation (tagging, review, etc.) | entrypoint scripts |
| `PRODUCTION_BOT` | Production bot username | setup scripts |
| `STAGING_BOT` | Staging bot username | setup scripts |
| `RUNNER_TOKEN` | GitHub Actions runner token | runner scripts |
## Hard-coded Values That Could Be Configurable
The following values are currently hard-coded in the source code but could potentially be made configurable via environment variables:
### Buffer Sizes
- Docker execution buffer: 10MB (`src/services/claudeService.ts:160`)
- Container logs buffer: 1MB (`src/services/claudeService.ts:184,590`)
### External URLs
- EC2 metadata endpoint: `http://169.254.169.254/latest/meta-data/` (`src/utils/awsCredentialProvider.ts:94`)
- GitHub API meta: `https://api.github.com/meta` (`scripts/security/init-firewall.sh:32`)
### Allowed Domains (Firewall)
- `registry.npmjs.org`
- `api.anthropic.com`
- `sentry.io`
- `statsig.anthropic.com`
- `statsig.com`
### Default Values
- Default git email in containers: `claude@example.com` (`scripts/runtime/claudecode-entrypoint.sh:89`)
- Default git username in containers: `ClaudeBot` (`scripts/runtime/claudecode-entrypoint.sh:90`)
- Health check container image: `claude-code-runner:latest` (`src/index.ts:140`)
### Docker Base Images
- Node base image: `node:24` (`Dockerfile.claudecode:1`)
- Delta version: `0.18.2` (`Dockerfile.claudecode:87`)
- Zsh-in-docker version: `v1.2.0` (`Dockerfile.claudecode:91`)
## Notes
1. **Secret Files**: The application supports loading secrets from files, which takes priority over environment variables. This is more secure for production deployments.
2. **AWS Authentication**: The service supports multiple AWS authentication methods:
- Direct credentials (AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY)
- AWS profiles (AWS_PROFILE with USE_AWS_PROFILE=true)
- Instance profiles (EC2)
- Task roles (ECS)
3. **Container Capabilities**: The container capability flags allow fine-grained control over container permissions for security purposes.
4. **Staging Environment**: Additional environment variables are defined in `.env.staging` for staging deployments, following the pattern `VARIABLE_NAME_STAGING`.

View File

@@ -14,7 +14,7 @@ case "$BUILD_TYPE" in
claudecode)
echo "Building Claude Code runner Docker image..."
docker build -f Dockerfile.claudecode -t claude-code-runner:latest .
docker build -f Dockerfile.claudecode -t claudecode:latest .
;;
production)
@@ -121,7 +121,7 @@ ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
EOF
# Build the production image
docker build -f Dockerfile.claudecode.prod -t claude-code-runner:production .
docker build -f Dockerfile.claudecode.prod -t claudecode:production .
# Clean up temporary file
rm -f Dockerfile.claudecode.prod

View File

@@ -123,7 +123,7 @@ elif [ "${OPERATION_TYPE}" = "pr-review" ] || [ "${OPERATION_TYPE}" = "manual-pr
# PR Review: Broad research access + controlled write access
# Read access: Full file system, git history, GitHub data
# Write access: GitHub comments/reviews, PR labels, but no file deletion/modification
ALLOWED_TOOLS="Read,GitHub,Bash(gh *),Bash(git log*),Bash(git show*),Bash(git diff*),Bash(git blame*),Bash(find*),Bash(grep*),Bash(rg*),Bash(cat*),Bash(head*),Bash(tail*),Bash(ls*),Bash(tree*)"
ALLOWED_TOOLS="Read,GitHub,Bash(gh:*),Bash(git log:*),Bash(git show:*),Bash(git diff:*),Bash(git blame:*),Bash(find:*),Bash(grep:*),Bash(rg:*),Bash(cat:*),Bash(head:*),Bash(tail:*),Bash(ls:*),Bash(tree:*)"
echo "Running Claude Code for PR review with broad research access..." >&2
else
ALLOWED_TOOLS="Bash,Create,Edit,Read,Write,GitHub" # Full tools for general operations
@@ -154,8 +154,12 @@ sudo -u node -E env \
PATH="/usr/local/bin:/usr/local/share/npm-global/bin:$PATH" \
ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY}" \
GH_TOKEN="${GITHUB_TOKEN}" \
GITHUB_TOKEN="${GITHUB_TOKEN}" \
BASH_DEFAULT_TIMEOUT_MS="${BASH_DEFAULT_TIMEOUT_MS}" \
BASH_MAX_TIMEOUT_MS="${BASH_MAX_TIMEOUT_MS}" \
/usr/local/share/npm-global/bin/claude \
--allowedTools "${ALLOWED_TOOLS}" \
--verbose \
--print "${COMMAND}" \
> "${RESPONSE_FILE}" 2>&1

View File

@@ -136,8 +136,9 @@ app.get('/health', (req: WebhookRequest, res: express.Response<HealthCheckRespon
// Check Claude Code runner image
const imageCheckStart = Date.now();
const dockerImageName = process.env['CLAUDE_CONTAINER_IMAGE'] ?? 'claudecode:latest';
try {
execSync('docker image inspect claude-code-runner:latest', { stdio: 'ignore' });
execSync(`docker image inspect ${dockerImageName}`, { stdio: 'ignore' });
checks.claudeCodeImage.available = true;
} catch {
checks.claudeCodeImage.error = 'Image not found';

View File

@@ -281,7 +281,7 @@ ${command}
Complete the auto-tagging task using only the minimal required tools.`;
} else {
return `You are Claude, an AI assistant responding to a GitHub ${isPullRequest ? 'pull request' : 'issue'} via the ${BOT_USERNAME} webhook.
return `You are ${process.env.BOT_USERNAME}, an AI assistant responding to a GitHub ${isPullRequest ? 'pull request' : 'issue'}.
**Context:**
- Repository: ${repoFullName}
@@ -348,7 +348,9 @@ function createEnvironmentVars({
OPERATION_TYPE: operationType,
COMMAND: fullPrompt,
GITHUB_TOKEN: githubToken,
ANTHROPIC_API_KEY: secureCredentials.get('ANTHROPIC_API_KEY') ?? ''
ANTHROPIC_API_KEY: secureCredentials.get('ANTHROPIC_API_KEY') ?? '',
BOT_USERNAME: process.env.BOT_USERNAME,
BOT_EMAIL: process.env.BOT_EMAIL
};
}

View File

@@ -41,6 +41,8 @@ export interface ClaudeEnvironmentVars {
COMMAND: string;
GITHUB_TOKEN: string;
ANTHROPIC_API_KEY: string;
BOT_USERNAME?: string;
BOT_EMAIL?: string;
}
export interface DockerExecutionOptions {