diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml new file mode 100644 index 0000000..561ed4e --- /dev/null +++ b/.github/workflows/docker-publish.yml @@ -0,0 +1,120 @@ +name: Docker Build and Publish + +on: + push: + branches: + - main + - master + tags: + - 'v*.*.*' + pull_request: + branches: + - main + - master + +env: + DOCKER_HUB_USERNAME: cheffromspace + DOCKER_HUB_ORGANIZATION: intelligenceassist + IMAGE_NAME: claude-github-webhook + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + + - name: Extract metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.IMAGE_NAME }} + tags: | + # For branches (master/main), use 'staging' tag + type=ref,event=branch,suffix=-staging + # For semantic version tags, use the version + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + # Latest tag for semantic version tags + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} + # SHA for every build + type=sha,prefix={{branch}}-,enable=true + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + platforms: linux/amd64,linux/arm64 + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Update Docker Hub Description + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + uses: peter-evans/dockerhub-description@v3 + with: + username: ${{ env.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + repository: ${{ env.DOCKER_HUB_ORGANIZATION }}/${{ env.IMAGE_NAME }} + readme-filepath: ./README.dockerhub.md + short-description: ${{ github.event.repository.description }} + + # Additional job to build and push the Claude Code container + build-claudecode: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ env.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_TOKEN }} + + - name: Extract metadata for claudecode + id: meta-claudecode + uses: docker/metadata-action@v5 + with: + images: ${{ env.DOCKER_HUB_ORGANIZATION }}/claudecode + tags: | + type=ref,event=branch,suffix=-staging + type=semver,pattern={{version}} + type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }} + + - name: Build and push Claude Code Docker image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile.claudecode + platforms: linux/amd64 + push: true + tags: ${{ steps.meta-claudecode.outputs.tags }} + labels: ${{ steps.meta-claudecode.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max \ No newline at end of file diff --git a/DOCKERHUB_SHORT_DESCRIPTION.txt b/DOCKERHUB_SHORT_DESCRIPTION.txt new file mode 100644 index 0000000..7a36ef5 --- /dev/null +++ b/DOCKERHUB_SHORT_DESCRIPTION.txt @@ -0,0 +1 @@ +GitHub webhook service that enables Claude AI to respond to mentions in issues and PRs. Features auto-tagging, automated PR reviews, and secure container execution. Mention your bot to trigger Claude's code analysis and assistance. \ No newline at end of file diff --git a/DOCKER_HUB.md b/DOCKER_HUB.md new file mode 100644 index 0000000..9abc15d --- /dev/null +++ b/DOCKER_HUB.md @@ -0,0 +1,116 @@ +# Docker Hub Deployment Guide + +## Quick Start + +Pull and run the Claude GitHub Webhook from Docker Hub: + +```bash +docker pull intelligenceassist/claude-github-webhook:latest +docker run -d \ + -p 8082:3002 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -e GITHUB_TOKEN=your_github_token \ + -e GITHUB_WEBHOOK_SECRET=your_webhook_secret \ + -e ANTHROPIC_API_KEY=your_anthropic_key \ + -e BOT_USERNAME=@YourBotName \ + -e AUTHORIZED_USERS=user1,user2 \ + intelligenceassist/claude-github-webhook:latest +``` + +## Using Docker Compose + +1. Create a `.env` file with your configuration: + +```env +# Required +GITHUB_TOKEN=your_github_token +GITHUB_WEBHOOK_SECRET=your_webhook_secret +ANTHROPIC_API_KEY=your_anthropic_key + +# Bot Configuration +BOT_USERNAME=@YourBotName +AUTHORIZED_USERS=user1,user2 +DEFAULT_GITHUB_OWNER=your-org +DEFAULT_GITHUB_USER=your-username + +# Optional: Docker Hub username (not needed for pulling) +``` + +2. Download the docker-compose file: + +```bash +curl -O https://raw.githubusercontent.com/intelligence-assist/claude-github-webhook/main/docker-compose.publish.yml +``` + +3. Start the service: + +```bash +docker compose -f docker-compose.publish.yml up -d +``` + +## Environment Variables + +### Required +- `GITHUB_TOKEN`: GitHub personal access token with repo permissions +- `GITHUB_WEBHOOK_SECRET`: Secret for validating GitHub webhooks +- `ANTHROPIC_API_KEY`: Anthropic API key for Claude access + +### Bot Configuration +- `BOT_USERNAME`: GitHub username the bot responds to (default: `@ClaudeBot`) +- `AUTHORIZED_USERS`: Comma-separated list of authorized GitHub usernames +- `DEFAULT_GITHUB_OWNER`: Default repository owner +- `DEFAULT_GITHUB_USER`: Default GitHub user +- `DEFAULT_BRANCH`: Default branch name (default: `main`) + +### Container Settings +- `CLAUDE_USE_CONTAINERS`: Enable container execution (default: `1`) +- `CLAUDE_CONTAINER_IMAGE`: Claude container image (default: `claudecode:latest`) + +## GitHub Webhook Configuration + +1. Go to your repository settings → Webhooks +2. Add webhook: + - **Payload URL**: `http://your-server:8082/api/webhooks/github` + - **Content type**: `application/json` + - **Secret**: Same as `GITHUB_WEBHOOK_SECRET` + - **Events**: Select "Issue comments" and "Pull request reviews" + +## Security Notes + +- The container requires Docker socket access for Claude container execution +- Use secrets management for sensitive environment variables in production +- Consider using Docker secrets or a secrets manager instead of plain environment variables + +## Building Claude Code Container + +The webhook uses a separate Claude Code container for execution. Build it with: + +```bash +docker build -f Dockerfile.claudecode -t claudecode:latest . +``` + +Or pull a pre-built version if available. + +## Troubleshooting + +### Check logs +```bash +docker logs +``` + +### Test webhook endpoint +```bash +curl http://localhost:8082/health +``` + +### Verify webhook delivery +Check GitHub webhook settings for recent deliveries and responses. + +## Updates + +Pull the latest version: +```bash +docker pull intelligenceassist/claude-github-webhook:latest +docker compose -f docker-compose.publish.yml down +docker compose -f docker-compose.publish.yml up -d +``` \ No newline at end of file diff --git a/README.dockerhub.md b/README.dockerhub.md new file mode 100644 index 0000000..69bcef7 --- /dev/null +++ b/README.dockerhub.md @@ -0,0 +1,93 @@ +# Claude GitHub Webhook + +A webhook service that enables Claude AI to respond to GitHub mentions and execute commands within repository contexts. + +## Quick Start + +```bash +docker pull intelligenceassist/claude-github-webhook:latest + +docker run -d \ + -p 8082:3002 \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -e GITHUB_TOKEN=your_github_token \ + -e GITHUB_WEBHOOK_SECRET=your_webhook_secret \ + -e ANTHROPIC_API_KEY=your_anthropic_key \ + -e BOT_USERNAME=@YourBotName \ + -e AUTHORIZED_USERS=user1,user2 \ + intelligenceassist/claude-github-webhook:latest +``` + +## Features + +- 🤖 Responds to GitHub mentions in issues and PRs +- 🔧 Executes Claude Code in isolated containers +- 🏷️ Auto-tags issues based on content analysis +- 🔍 Automated PR reviews when checks pass +- 🔒 Secure webhook signature verification +- 📊 Health check endpoint for monitoring + +## Docker Compose + +```yaml +version: '3.8' + +services: + claude-webhook: + image: intelligenceassist/claude-github-webhook:latest + ports: + - "8082:3002" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + environment: + - GITHUB_TOKEN=${GITHUB_TOKEN} + - GITHUB_WEBHOOK_SECRET=${GITHUB_WEBHOOK_SECRET} + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} + - BOT_USERNAME=@YourBotName + - AUTHORIZED_USERS=user1,user2 + restart: unless-stopped +``` + +## Environment Variables + +### Required +- `GITHUB_TOKEN` - GitHub personal access token +- `GITHUB_WEBHOOK_SECRET` - Secret for webhook validation +- `ANTHROPIC_API_KEY` - Anthropic API key for Claude + +### Optional +- `BOT_USERNAME` - Bot mention trigger (default: @ClaudeBot) +- `AUTHORIZED_USERS` - Comma-separated authorized users +- `CLAUDE_USE_CONTAINERS` - Enable container mode (default: 1) +- `PORT` - Server port (default: 3002) + +## GitHub Setup + +1. Go to **Settings → Webhooks** in your repository +2. Add webhook: + - **Payload URL**: `http://your-server:8082/api/webhooks/github` + - **Content type**: `application/json` + - **Secret**: Same as `GITHUB_WEBHOOK_SECRET` + - **Events**: Issues, Issue comments, Pull requests + +## Usage + +Mention your bot in any issue or PR comment: +``` +@YourBotName Can you analyze this code and suggest improvements? +``` + +## Tags + +- `latest` - Most recent stable version +- `0.1.0` - Initial release + +## Links + +- [GitHub Repository](https://github.com/intelligence-assist/claude-github-webhook) +- [Documentation](https://github.com/intelligence-assist/claude-github-webhook/tree/main/docs) +- [Issue Tracker](https://github.com/intelligence-assist/claude-github-webhook/issues) + +## License + +MIT \ No newline at end of file diff --git a/docker-compose.publish.yml b/docker-compose.publish.yml new file mode 100644 index 0000000..98a5a1b --- /dev/null +++ b/docker-compose.publish.yml @@ -0,0 +1,41 @@ +version: '3.8' + +services: + claude-webhook: + image: intelligenceassist/claude-github-webhook:latest + ports: + - "8082:3002" + volumes: + # Mount Docker socket for container execution + - /var/run/docker.sock:/var/run/docker.sock + # Mount AWS credentials (optional, for AWS Bedrock access) + - ${HOME}/.aws:/root/.aws:ro + environment: + - NODE_ENV=production + - PORT=3002 + + # Required: GitHub webhook configuration + - GITHUB_TOKEN=${GITHUB_TOKEN} + - GITHUB_WEBHOOK_SECRET=${GITHUB_WEBHOOK_SECRET} + + # Required: Anthropic API key for Claude access + - ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY} + + # Bot configuration + - BOT_USERNAME=${BOT_USERNAME:-@ClaudeBot} + - AUTHORIZED_USERS=${AUTHORIZED_USERS} + - DEFAULT_GITHUB_OWNER=${DEFAULT_GITHUB_OWNER} + - DEFAULT_GITHUB_USER=${DEFAULT_GITHUB_USER} + - DEFAULT_BRANCH=${DEFAULT_BRANCH:-main} + + # Container execution settings + - CLAUDE_USE_CONTAINERS=${CLAUDE_USE_CONTAINERS:-1} + - CLAUDE_CONTAINER_IMAGE=${CLAUDE_CONTAINER_IMAGE:-claudecode:latest} + + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:3002/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s \ No newline at end of file diff --git a/docs/docker-ci-cd.md b/docs/docker-ci-cd.md new file mode 100644 index 0000000..8aba912 --- /dev/null +++ b/docs/docker-ci-cd.md @@ -0,0 +1,113 @@ +# Docker CI/CD Pipeline + +This document describes the automated Docker build and publish pipeline for the Claude GitHub Webhook. + +## Overview + +The pipeline automatically builds and publishes Docker images to Docker Hub based on Git events: + +- **Push to main/master**: Builds and tags as `staging` +- **Git tags (v*.*.*)**: Builds and tags with version numbers and `latest` +- **Pull requests**: Builds but doesn't push (for testing) + +## Workflow Triggers + +### Branch Pushes (Staging) +When you push to `main` or `master`: +- Image tagged as: `main-staging` or `master-staging` +- Also tagged with commit SHA: `main-abc1234` + +### Version Tags (Releases) +When you create a semantic version tag (e.g., `v1.2.3`): +- Image tagged as: `1.2.3`, `1.2`, `1`, and `latest` +- Also tagged with commit SHA + +### Pull Requests +- Builds the image but doesn't push +- Allows testing of Dockerfile changes + +## Setup Requirements + +1. **Docker Hub Token**: Create a Docker Hub access token + - Go to Docker Hub → Account Settings → Security → Access Tokens + - Create a new token with `Read, Write, Delete` permissions + - Add as GitHub secret: `DOCKER_HUB_TOKEN` + +2. **GitHub Repository Secrets**: + ``` + DOCKER_HUB_TOKEN: Your Docker Hub access token + ``` + +## Image Tags + +### Main Repository (`intelligenceassist/claude-github-webhook`) +- `latest`: Latest stable release +- `X.Y.Z`: Specific version +- `main-staging`: Latest from main branch +- `main-sha-abc1234`: Specific commit + +### Claude Code Container (`intelligenceassist/claudecode`) +- `latest`: Latest stable release +- `X.Y.Z`: Specific version +- `main-staging`: Latest from main branch + +## Creating a Release + +1. **Test on staging**: + ```bash + git checkout main + git pull origin main + # Make your changes + git add . + git commit -m "feat: your feature" + git push origin main + ``` + This triggers a staging build. + +2. **Create a release**: + ```bash + # After testing staging + git tag v0.2.0 + git push origin v0.2.0 + ``` + This triggers a release build with proper version tags. + +## Multi-Platform Builds + +The workflow builds for multiple platforms: +- `linux/amd64`: Standard x86_64 architecture +- `linux/arm64`: ARM64 (for Apple Silicon, AWS Graviton, etc.) + +## Caching + +The workflow uses GitHub Actions cache to speed up builds: +- Docker layers are cached between builds +- Cache is stored in GitHub Actions cache storage + +## Monitoring Builds + +1. **GitHub Actions**: Check the Actions tab in your repository +2. **Docker Hub**: View pushed tags at https://hub.docker.com/r/intelligenceassist/claude-github-webhook/tags + +## Best Practices + +1. **Always test on staging first**: Push to main before creating a release tag +2. **Use semantic versioning**: Follow vX.Y.Z format for release tags +3. **Write descriptive commit messages**: They appear in Docker Hub +4. **Update README.dockerhub.md**: It auto-syncs to Docker Hub on main pushes + +## Troubleshooting + +### Build Failures +- Check GitHub Actions logs +- Ensure Dockerfile syntax is correct +- Verify all files referenced in Dockerfile exist + +### Push Failures +- Verify `DOCKER_HUB_TOKEN` secret is set correctly +- Ensure token has write permissions +- Check Docker Hub quota limits + +### Tag Issues +- Tags must start with 'v' for version detection (e.g., v1.0.0) +- Ensure no spaces or special characters in tag names \ No newline at end of file diff --git a/publish-docker.sh b/publish-docker.sh new file mode 100755 index 0000000..a280c1a --- /dev/null +++ b/publish-docker.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Docker Hub publishing script for Claude GitHub Webhook +# Usage: ./publish-docker.sh YOUR_DOCKERHUB_USERNAME [VERSION] + +DOCKERHUB_USERNAME=${1:-intelligenceassist} +VERSION=${2:-latest} + +# Default to intelligenceassist organization + +IMAGE_NAME="claude-github-webhook" +FULL_IMAGE_NAME="$DOCKERHUB_USERNAME/$IMAGE_NAME" + +echo "Building Docker image..." +docker build -t $IMAGE_NAME:latest . + +echo "Tagging image as $FULL_IMAGE_NAME:$VERSION..." +docker tag $IMAGE_NAME:latest $FULL_IMAGE_NAME:$VERSION + +if [ "$VERSION" != "latest" ]; then + echo "Also tagging as $FULL_IMAGE_NAME:latest..." + docker tag $IMAGE_NAME:latest $FULL_IMAGE_NAME:latest +fi + +echo "Logging in to Docker Hub..." +docker login + +echo "Pushing to Docker Hub..." +docker push $FULL_IMAGE_NAME:$VERSION + +if [ "$VERSION" != "latest" ]; then + docker push $FULL_IMAGE_NAME:latest +fi + +echo "Successfully published to Docker Hub!" +echo "Users can now pull with: docker pull $FULL_IMAGE_NAME:$VERSION" \ No newline at end of file