feat: Improve Claude authentication setup experience (#153)

* feat: Improve Claude authentication setup experience

- Replace 'claude login' with 'claude --dangerously-skip-permissions'
- Fix path references from /auth-output to actual authentication location
- Simplify user instructions to be more accessible
- Add automatic authentication execution (no manual typing required)
- Add comprehensive validation for authentication success
- Check file existence, size, and timestamp
- Provide clear error messages for different failure scenarios
- Remove deprecated setup-claude-auth.sh script
- Update CLAUDE.md to reference correct build script path
- Exclude todos directory from authentication capture

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

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

* remove self-hosted runners from ci

---------

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Cheffromspace
2025-06-01 12:54:58 -05:00
committed by GitHub
parent 31efbbc2bb
commit af851491e8
10 changed files with 118 additions and 107 deletions

View File

@@ -154,7 +154,7 @@ jobs:
sarif_file: 'trivy-results.sarif'
# ============================================
# CD Jobs - Run on self-hosted runners
# CD Jobs - Run on GitHub-hosted runners
# ============================================
deploy-staging:

View File

@@ -16,13 +16,11 @@ env:
DOCKER_HUB_USERNAME: ${{ vars.DOCKER_HUB_USERNAME || 'cheffromspace' }}
DOCKER_HUB_ORGANIZATION: ${{ vars.DOCKER_HUB_ORGANIZATION || 'intelligenceassist' }}
IMAGE_NAME: ${{ vars.DOCKER_IMAGE_NAME || 'claude-hub' }}
# Runner configuration - set USE_SELF_HOSTED to 'false' to force GitHub-hosted runners
USE_SELF_HOSTED: ${{ vars.USE_SELF_HOSTED || 'true' }}
jobs:
build:
# Use self-hosted runners by default, with ability to override via repository variable
runs-on: ${{ vars.USE_SELF_HOSTED == 'false' && 'ubuntu-latest' || fromJSON('["self-hosted", "linux", "x64", "docker"]') }}
# Always use GitHub-hosted runners
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
@@ -118,7 +116,7 @@ jobs:
# Build claudecode separately
build-claudecode:
runs-on: ${{ vars.USE_SELF_HOSTED == 'false' && 'ubuntu-latest' || fromJSON('["self-hosted", "linux", "x64", "docker"]') }}
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
timeout-minutes: 30
permissions:
@@ -170,25 +168,4 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
# Fallback job if self-hosted runners timeout
build-fallback:
needs: [build, build-claudecode]
if: |
always() &&
(needs.build.result == 'failure' || needs.build-claudecode.result == 'failure') &&
vars.USE_SELF_HOSTED != 'false'
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
security-events: write
steps:
- name: Trigger rebuild on GitHub-hosted runners
run: |
echo "Self-hosted runner build failed. To retry with GitHub-hosted runners:"
echo "1. Set the repository variable USE_SELF_HOSTED to 'false'"
echo "2. Re-run this workflow"
echo ""
echo "Or manually trigger a new workflow run with GitHub-hosted runners."
exit 1
# Note: Fallback job removed since we're always using GitHub-hosted runners

View File

@@ -42,7 +42,7 @@ jobs:
extra_args: --debug --only-verified
build:
runs-on: [self-hosted, docker]
runs-on: ubuntu-latest
needs: [test, security]
permissions:
contents: read

View File

@@ -29,7 +29,7 @@ jobs:
- run: ./scripts/security/credential-audit.sh
docker:
runs-on: [self-hosted, docker]
runs-on: ubuntu-latest
if: contains(github.event.pull_request.changed_files, 'Dockerfile') || contains(github.event.pull_request.changed_files, 'src/')
steps:
- uses: actions/checkout@v4

2
.gitignore vendored
View File

@@ -79,6 +79,8 @@ service-account.json
# Claude authentication output
.claude-hub/
claude-config/
claude-config*
# Docker secrets
secrets/

View File

@@ -46,7 +46,7 @@ This repository contains a webhook service that integrates Claude with GitHub, a
- **View logs**: `docker compose logs -f webhook`
- **Restart**: `docker compose restart webhook`
- Build Claude container: `./build-claude-container.sh`
- Build Claude Code container: `./scripts/build/build-claudecode.sh`
- Build Claude Code container: `./scripts/build/build.sh claudecode`
- Update production image: `./update-production-image.sh`
### AWS Credential Management

View File

@@ -8,7 +8,8 @@ RUN apt update && apt install -y \
curl \
vim \
nano \
gh
gh \
rsync
# Set up npm global directory
RUN mkdir -p /usr/local/share/npm-global && \
@@ -32,34 +33,31 @@ RUN mkdir -p /auth-setup && chown -R node:node /auth-setup
ENV SHELL /bin/zsh
WORKDIR /auth-setup
# Create setup script that captures authentication state
RUN cat > /setup-claude-auth.sh << 'EOF'
# Create setup script
COPY <<'EOF' /setup-claude-auth.sh
#!/bin/bash
set -e
echo "🔧 Claude Authentication Setup Container"
echo "========================================"
echo "🔧 Claude Authentication Setup"
echo "=============================="
echo ""
echo "This container allows you to authenticate with Claude interactively"
echo "and capture the authentication state for use in other containers."
echo "This will help you connect Claude to your account."
echo ""
echo "Instructions:"
echo "1. Run: claude login"
echo "2. Follow the authentication flow"
echo "3. Test with: claude status"
echo "4. Type 'exit' when authentication is working"
echo "Quick setup - just run this command:"
echo ""
echo "The ~/.claude directory will be preserved in /auth-output"
echo " claude --dangerously-skip-permissions && exit"
echo ""
echo "This will authenticate Claude and save your setup automatically."
echo ""
# Function to copy authentication state
copy_auth_state() {
if [ -d "/home/node/.claude" ] && [ -d "/auth-output" ]; then
echo "💾 Copying authentication state..."
cp -r /home/node/.claude/* /auth-output/ 2>/dev/null || true
cp -r /home/node/.claude/.* /auth-output/ 2>/dev/null || true
chown -R node:node /auth-output
echo "✅ Authentication state copied to /auth-output"
echo "💾 Saving your authentication..."
# Copy authentication files, excluding todos
rsync -a --exclude='todos/' /home/node/.claude/ /auth-output/ 2>/dev/null || \
cp -r /home/node/.claude/. /auth-output/ 2>/dev/null || true
echo "✅ Authentication saved successfully!"
fi
}
@@ -70,21 +68,41 @@ trap copy_auth_state EXIT
sudo -u node mkdir -p /home/node/.claude
echo "🔐 Starting interactive shell as 'node' user..."
echo "💡 Tip: Run 'claude --version' to verify Claude CLI is available"
echo ""
echo ""
# Switch to node user and start interactive shell
sudo -u node bash -c '
# Check if we should run automatically
if [ "$1" = "--auto" ]; then
echo "Running authentication automatically..."
echo ""
sudo -u node bash -c '
export HOME=/home/node
export PATH=/usr/local/share/npm-global/bin:$PATH
cd /home/node
echo "Environment ready! Claude CLI is available at: $(which claude || echo "/usr/local/share/npm-global/bin/claude")"
echo "Run: claude login"
claude --dangerously-skip-permissions
exit_code=$?
if [ $exit_code -ne 0 ]; then
echo ""
echo "❌ Authentication command failed with exit code $exit_code"
exit $exit_code
fi
'
else
# Switch to node user and start interactive shell
sudo -u node bash -c '
export HOME=/home/node
export PATH=/usr/local/share/npm-global/bin:$PATH
cd /home/node
echo "Ready! Run this command to authenticate and exit:"
echo ""
echo " claude --dangerously-skip-permissions && exit"
echo ""
exec bash -i
'
'
fi
EOF
RUN chmod +x /setup-claude-auth.sh
# Set entrypoint to setup script
ENTRYPOINT ["/setup-claude-auth.sh"]
ENTRYPOINT ["/bin/bash", "/setup-claude-auth.sh"]

View File

@@ -1,14 +0,0 @@
#!/bin/bash
echo "Setting up Claude Code authentication..."
# Build the setup container
docker build -f Dockerfile.setup -t claude-setup .
# Run it interactively with AWS credentials mounted
docker run -it -v $HOME/.aws:/root/.aws:ro claude-setup
echo ""
echo "After completing the authentication in the container:"
echo "1. Run 'docker ps -a' to find the container ID"
echo "2. Run 'docker cp <container_id>:/root/.claude ./claude-config'"
echo "3. Then run './update-production-image.sh'"

View File

@@ -19,48 +19,76 @@ echo "📦 Building Claude setup container..."
docker build -f "$PROJECT_ROOT/Dockerfile.claude-setup" -t claude-setup:latest "$PROJECT_ROOT"
echo ""
echo "🚀 Starting interactive Claude authentication container..."
echo "🚀 Starting Claude authentication..."
echo ""
echo "IMPORTANT: This will open an interactive shell where you can:"
echo " 1. Run 'claude --dangerously-skip-permissions' to authenticate"
echo " 2. Follow the authentication flow"
echo " 3. Type 'exit' when done to preserve authentication state"
echo "What happens next:"
echo " 1. Claude will open your browser for authentication"
echo " 2. Complete the authentication in your browser"
echo " 3. Return here when done - the container will exit automatically"
echo ""
echo "The authenticated ~/.claude directory will be saved to:"
echo " $AUTH_OUTPUT_DIR"
echo ""
read -p "Press Enter to continue or Ctrl+C to cancel..."
read -p "Press Enter to start authentication..."
# Run the interactive container
# Run the container with automatic authentication
docker run -it --rm \
-v "$AUTH_OUTPUT_DIR:/auth-output" \
-v "$HOME/.gitconfig:/home/node/.gitconfig:ro" \
--name claude-auth-setup \
claude-setup:latest
claude-setup:latest --auto
# Capture the exit code
DOCKER_EXIT_CODE=$?
echo ""
echo "📋 Checking authentication output..."
if [ -f "$AUTH_OUTPUT_DIR/.credentials.json" ] || [ -f "$AUTH_OUTPUT_DIR/settings.local.json" ]; then
echo "✅ Authentication files found in $AUTH_OUTPUT_DIR"
# First check if docker command failed
if [ $DOCKER_EXIT_CODE -ne 0 ]; then
echo "❌ Authentication process failed (exit code: $DOCKER_EXIT_CODE)"
echo ""
echo "📁 Captured authentication files:"
find "$AUTH_OUTPUT_DIR" -type f -name "*.json" -o -name "*.db" | head -10
echo ""
echo "🔄 To use this authentication in your webhook service:"
echo " 1. Copy files to your ~/.claude directory:"
echo " cp -r $AUTH_OUTPUT_DIR/* ~/.claude/"
echo " 2. Or update docker-compose.yml to mount the auth directory:"
echo " - $AUTH_OUTPUT_DIR:/home/node/.claude:ro"
echo ""
else
echo "⚠️ No authentication files found. You may need to:"
echo " 1. Run the container again and complete the authentication flow"
echo " 2. Ensure you ran 'claude --dangerously-skip-permissions' and completed authentication"
echo " 3. Check that you have an active Claude Code subscription"
echo "Please check the error messages above and try again."
exit 1
fi
# Check if authentication was successful
if [ -f "$AUTH_OUTPUT_DIR/.credentials.json" ]; then
# Get file size
FILE_SIZE=$(stat -f%z "$AUTH_OUTPUT_DIR/.credentials.json" 2>/dev/null || stat -c%s "$AUTH_OUTPUT_DIR/.credentials.json" 2>/dev/null || echo "0")
# Check if file has reasonable content (at least 100 bytes for a valid JSON)
if [ "$FILE_SIZE" -gt 100 ]; then
# Check if file was written recently (within last 5 minutes)
if [ "$(find "$AUTH_OUTPUT_DIR/.credentials.json" -mmin -5 2>/dev/null)" ]; then
echo "✅ Success! Your Claude authentication is saved."
echo ""
echo "The webhook service will use this automatically when you run:"
echo " docker compose up -d"
echo ""
exit 0
else
echo "⚠️ Found old authentication files. The authentication may not have completed."
echo "Please run the setup again to refresh your authentication."
exit 1
fi
else
echo "❌ Authentication file is too small (${FILE_SIZE} bytes). The authentication did not complete."
echo ""
echo "Common causes:"
echo " - Browser authentication was cancelled"
echo " - Network connection issues"
echo " - Claude Code subscription not active"
echo ""
echo "Please run the setup again and complete the browser authentication."
exit 1
fi
else
echo "❌ Authentication failed - no credentials were saved."
echo ""
echo "This can happen if:"
echo " - The browser authentication was not completed"
echo " - The container exited before authentication finished"
echo " - There was an error during the authentication process"
echo ""
echo "Please run './scripts/setup/setup-claude-interactive.sh' again."
exit 1
fi
echo ""
echo "🧪 Testing authentication..."
echo "You can test the captured authentication with:"
echo " docker run --rm -v \"$AUTH_OUTPUT_DIR:/home/node/.claude:ro\" claude-setup:latest claude --dangerously-skip-permissions --print 'test'"