diff --git a/.claude/amber-config.yml b/.claude/amber-config.yml new file mode 100644 index 000000000..fe7cf2062 --- /dev/null +++ b/.claude/amber-config.yml @@ -0,0 +1,221 @@ +# Amber Background Agent Configuration +# Defines autonomous action policies for different issue types + +version: "1.0" + +# Risk-based automation policies +automation_policies: + + # LOW RISK: Auto-fix and create PR (no approval needed) + auto_fix: + enabled: true + branch_prefix: "amber/auto-fix" + pr_labels: ["auto-generated", "amber", "chore"] + require_tests_pass: true + + categories: + - name: "Code Formatting" + patterns: + - "gofmt violations" + - "black formatting" + - "prettier issues" + - "unused imports (Go, Python)" + commands: + go: ["gofmt -w .", "goimports -w ."] + python: ["black .", "isort ."] + typescript: ["npm run format"] + + - name: "Import Sorting" + patterns: + - "isort violations" + - "import order issues" + + - name: "Documentation Fixes" + patterns: + - "broken internal links" + - "outdated code examples in comments" + - "missing docstrings for public functions" + max_files_per_pr: 5 # Avoid massive doc PRs + + - name: "Dependency Patches" + patterns: + - "patch version updates (x.y.Z)" + - "security patches (dependabot alerts)" + require_ci_pass: true + auto_merge: false # Create PR but don't auto-merge + + # MEDIUM RISK: Create detailed proposal (requires approval) + propose_for_approval: + enabled: true + action: "create_github_issue" + labels: ["amber-proposal", "needs-review"] + + categories: + - name: "Refactoring" + patterns: + - "files exceeding 400 lines" + - "context.TODO() replacements" + - "repeated code patterns (DRY violations)" + proposal_template: | + ## Refactoring Proposal (Amber) + + **File:** {file_path} + **Current LOC:** {line_count} + **Issue:** {issue_description} + + ### Proposed Changes + {proposed_changes} + + ### Risk Assessment + - **Blast Radius:** {blast_radius} + - **Rollback Plan:** {rollback_plan} + - **Testing Strategy:** {testing_strategy} + + ### Before/After Structure + ``` + {structure_diff} + ``` + + **Estimated Effort:** {effort_hours} hours + **Priority:** {priority} + + --- + *Generated by Amber Background Agent* + + - name: "Test Coverage" + patterns: + - "missing contract tests" + - "untested error paths" + - "coverage below 60%" + action: "create_draft_pr" + include_test_skeleton: true + + - name: "Security Improvements" + patterns: + - "missing input validation" + - "unhandled error returns" + - "hardcoded credentials (non-critical)" + labels: ["security", "amber-proposal", "needs-security-review"] + + # HIGH RISK: Report only (manual decision required) + report_only: + enabled: true + action: "create_detailed_report" + notify_via: "github_issue" + labels: ["amber-alert", "requires-decision"] + + categories: + - name: "Breaking Changes" + patterns: + - "API contract modifications" + - "database schema changes" + - "public interface breaking changes" + severity: "critical" + + - name: "Security Vulnerabilities" + patterns: + - "authentication bypass potential" + - "SQL injection risk" + - "XSS vulnerabilities" + - "secrets exposure" + severity: "critical" + notify_team: "security" + + - name: "Architectural Changes" + patterns: + - "new service introduction" + - "technology stack changes" + - "cross-component dependencies" + severity: "high" + require_rfc: true + +# Constitution compliance checks +constitution_checks: + enabled: true + reference_file: "CLAUDE.md" + + principles: + - id: "principle_v_modularity" + name: "Component Modularity" + check: "file_size_limit" + threshold: 400 # lines + action: "propose_for_approval" + + - id: "principle_iii_context" + name: "Proper Context Usage" + check: "context_todo_usage" + pattern: "context.TODO()" + action: "propose_for_approval" + + - id: "principle_iv_testing" + name: "Test Coverage" + check: "test_file_existence" + require_test_for: + - "**/handlers/*.go" + - "**/services/*.go" + action: "propose_for_approval" + + - id: "principle_ii_auth" + name: "User-Scoped Auth" + check: "service_account_usage" + forbidden_pattern: "DynamicClient.*List|Get.*// user operation" + action: "report_only" # Security issue + +# Monitoring & reporting +monitoring: + schedule: + daily: + - "check_recent_commits" # Last 24 hours + - "run_linting_checks" + - "verify_ci_status" + + weekly: + - "full_codebase_health_check" + - "test_coverage_analysis" + - "dependency_audit" + + monthly: + - "architecture_review" + - "technical_debt_assessment" + - "security_audit" + + report_format: "markdown" + report_location: ".amber/reports/" + github_issues: true + +# Integration settings +integrations: + github: + enabled: true + auto_label: true + create_issues: true + create_prs: true + + ci_cd: + require_pass_before_merge: true + run_tests_on_auto_fix: true + + notifications: + slack_webhook: null # Configure if desired + email: null + +# Safety guardrails +safety: + max_auto_prs_per_day: 5 + max_files_per_auto_pr: 10 + require_review_for_auto_merge: true + never_push_to_main: true + always_create_branch: true + + excluded_paths: + - ".git/" + - "vendor/" + - "node_modules/" + - "*.lock" + - "*.sum" + +# Learning & improvement +learning: + track_false_positives: true + learn_from_rejected_proposals: true + adjust_thresholds_over_time: true diff --git a/.github/ISSUE_TEMPLATE/amber-auto-fix.yml b/.github/ISSUE_TEMPLATE/amber-auto-fix.yml new file mode 100644 index 000000000..417b409bf --- /dev/null +++ b/.github/ISSUE_TEMPLATE/amber-auto-fix.yml @@ -0,0 +1,60 @@ +name: ๐Ÿค– Amber Auto-Fix Request +description: Request Amber to automatically fix linting, formatting, or trivial issues +title: "[Amber] " +labels: ["amber:auto-fix", "automation"] +body: + - type: markdown + attributes: + value: | + ## Amber Auto-Fix Request + + Use this template to request **low-risk automated fixes** such as: + - Code formatting (gofmt, black, prettier) + - Unused import removal + - Linting violations + - Documentation formatting + + Amber will automatically create a PR to address this issue. + + - type: textarea + id: description + attributes: + label: Issue Description + description: Describe what needs to be fixed + placeholder: | + Example: "Frontend code has unused imports and doesn't pass eslint checks" + validations: + required: true + + - type: input + id: files + attributes: + label: Files to Fix (optional) + description: Specific files or directories to target + placeholder: "components/frontend/src/**/*.tsx" + + - type: dropdown + id: fix-type + attributes: + label: Fix Type + description: What kind of fix is needed? + options: + - Code Formatting + - Linting Violations + - Unused Imports + - Documentation Formatting + - All of the above + validations: + required: true + + - type: checkboxes + id: confirmation + attributes: + label: Confirmation + options: + - label: I understand this will create an automated PR + required: true + - label: The changes are low-risk and reversible + required: true + - label: All tests should continue to pass after fixes + required: true diff --git a/.github/ISSUE_TEMPLATE/amber-refactor.yml b/.github/ISSUE_TEMPLATE/amber-refactor.yml new file mode 100644 index 000000000..fa6b4c63d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/amber-refactor.yml @@ -0,0 +1,78 @@ +name: ๐Ÿ”ง Amber Refactoring Request +description: Request Amber to perform code refactoring (medium-risk changes) +title: "[Amber Refactor] " +labels: ["amber:refactor", "refactoring"] +body: + - type: markdown + attributes: + value: | + ## Amber Refactoring Request + + Use this template for **medium-risk refactoring** such as: + - Breaking large files into modules + - Extracting repeated code patterns + - Improving error handling + - Replacing deprecated patterns + + Amber will create a PR with the proposed refactoring. + + - type: textarea + id: current-state + attributes: + label: Current State + description: Describe the code that needs refactoring + placeholder: | + File: components/backend/handlers/sessions.go + Issue: 3,495 lines, violates Constitution Principle V (max 400 lines) + validations: + required: true + + - type: textarea + id: desired-state + attributes: + label: Desired State + description: What should the code look like after refactoring? + placeholder: | + Break into modules: + - sessions/lifecycle.go (create, delete) + - sessions/status.go (status updates) + - sessions/jobs.go (job management) + - sessions/validation.go (input validation) + validations: + required: true + + - type: textarea + id: constraints + attributes: + label: Constraints & Requirements + description: Any constraints Amber should follow + placeholder: | + - Must maintain backward compatibility + - No breaking changes to API + - All existing tests must pass + - Follow patterns in CLAUDE.md + validations: + required: true + + - type: dropdown + id: priority + attributes: + label: Priority + options: + - P0 - Critical (Constitution violation) + - P1 - High (Tech debt) + - P2 - Medium (Nice to have) + validations: + required: true + + - type: checkboxes + id: confirmation + attributes: + label: Confirmation + options: + - label: I have reviewed CLAUDE.md standards + required: true + - label: Backward compatibility is required + required: true + - label: I will review the generated PR before merging + required: true diff --git a/.github/ISSUE_TEMPLATE/amber-test-coverage.yml b/.github/ISSUE_TEMPLATE/amber-test-coverage.yml new file mode 100644 index 000000000..94f3662b7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/amber-test-coverage.yml @@ -0,0 +1,74 @@ +name: ๐Ÿงช Amber Test Coverage Request +description: Request Amber to add missing tests +title: "[Amber Tests] " +labels: ["amber:test-coverage", "testing"] +body: + - type: markdown + attributes: + value: | + ## Amber Test Coverage Request + + Use this template to request **test additions** for: + - Untested functions/handlers + - Low coverage areas + - Missing contract tests + - Edge case coverage + + Amber will create a PR with new tests following project conventions. + + - type: textarea + id: untested-code + attributes: + label: Untested Code + description: What code needs test coverage? + placeholder: | + File: components/backend/handlers/sessions.go + Functions: + - CreateSession (line 123) + - UpdateSessionStatus (line 456) + - ValidateSessionSpec (line 789) + validations: + required: true + + - type: dropdown + id: test-type + attributes: + label: Test Type + description: What kind of tests are needed? + options: + - Unit Tests + - Contract Tests (API endpoints) + - Integration Tests + - All of the above + validations: + required: true + + - type: textarea + id: test-scenarios + attributes: + label: Test Scenarios (optional) + description: Specific scenarios to test + placeholder: | + - Happy path: create session with valid spec + - Error: create session with missing API key + - Edge case: create session with very long prompt + - Race condition: concurrent status updates + + - type: input + id: target-coverage + attributes: + label: Target Coverage % + description: Desired test coverage percentage + placeholder: "60%" + + - type: checkboxes + id: confirmation + attributes: + label: Confirmation + options: + - label: Tests should follow patterns in CLAUDE.md + required: true + - label: Table-driven tests for Go, pytest for Python + required: true + - label: All new tests must pass + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..f943d3b9c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: true +contact_links: + - name: ๐Ÿ“š Amber Automation Documentation + url: https://github.com/jeremyeder/platform/blob/main/docs/amber-automation.md + about: Complete guide to using Amber for automated issue-to-PR workflows + - name: ๐Ÿš€ Amber Quickstart + url: https://github.com/jeremyeder/platform/blob/main/docs/amber-quickstart.md + about: Get started with Amber in 5 minutes + - name: ๐Ÿ’ฌ Discussions + url: https://github.com/jeremyeder/platform/discussions + about: Ask questions and discuss ideas with the community diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 000000000..651c744e9 --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,395 @@ +# GitHub Actions Workflows + +This directory contains automated workflows for the Ambient Code Platform. + +## Active Workflows + +### ๐Ÿค– Amber Issue-to-PR Handler (`amber-issue-handler.yml`) + +**Purpose**: Automatically processes GitHub issues and creates pull requests using the Amber background agent. + +**Triggers**: +- Issue labeled with `amber:auto-fix`, `amber:refactor`, or `amber:test-coverage` +- Issue comment containing `/amber execute` + +**What It Does**: +1. Parses issue for file paths, instructions, and context +2. Executes Amber agent with appropriate prompt +3. Creates feature branch with fixes/refactoring/tests +4. Opens pull request with changes +5. Links PR back to original issue + +**Requirements**: +- `ANTHROPIC_API_KEY` secret configured +- Workflow permissions: read/write for contents, issues, PRs + +**Documentation**: [Amber Automation Guide](../../docs/amber-automation.md) + +--- + +### ๐Ÿ—๏ธ Components Build & Deploy (`components-build-deploy.yml`) + +**Purpose**: Builds and deploys platform components on changes. + +**Triggers**: +- Push to `main` branch +- Pull requests affecting component directories + +**What It Does**: +1. Detects which components changed +2. Builds multi-platform Docker images (amd64, arm64) +3. Pushes to `quay.io/ambient_code` registry (main branch only) +4. Runs component-specific tests + +**Change Detection**: +- Frontend: `components/frontend/**` +- Backend: `components/backend/**` +- Operator: `components/operator/**` +- Claude Runner: `components/runners/claude-code-runner/**` + +--- + +### ๐Ÿงช E2E Tests (`e2e.yml`) + +**Purpose**: Runs end-to-end tests in Kind (Kubernetes in Docker). + +**Triggers**: +- Pull requests +- Manual workflow dispatch + +**What It Does**: +1. Sets up Kind cluster +2. Deploys full vTeam stack +3. Runs Cypress tests against UI +4. Reports results + +**Documentation**: [E2E Testing Guide](../../docs/testing/e2e-guide.md) + +--- + +### ๐Ÿ”ง Test Local Dev (`test-local-dev.yml`) + +**Purpose**: Validates local development setup works correctly. + +**Triggers**: +- Changes to dev scripts (`Makefile`, `dev-start.sh`, etc.) +- Manual workflow dispatch + +**What It Does**: +1. Simulates local development environment +2. Tests `make dev-start`, `make dev-stop` +3. Verifies CRC integration + +--- + +### ๐Ÿ”„ Dependabot Auto-Merge (`dependabot-auto-merge.yml`) + +**Purpose**: Automatically merges Dependabot dependency updates. + +**Triggers**: +- Dependabot PR creation + +**What It Does**: +1. Checks if PR is from Dependabot +2. Waits for CI to pass +3. Auto-merges patch/minor version updates +4. Requires manual review for major updates + +--- + +### ๐Ÿ”„ Amber Dependency Sync (`amber-dependency-sync.yml`) + +**Purpose**: Keeps Amber agent's dependency knowledge current. + +**Triggers**: +- Daily at 7 AM UTC +- Manual workflow dispatch + +**What It Does**: +1. Extracts dependency versions from go.mod, pyproject.toml, package.json +2. Updates `agents/amber.md` with current versions +3. Validates sync accuracy +4. Validates constitution compliance +5. Auto-commits changes + +**Documentation**: [Amber Automation Guide](../../docs/amber-automation.md) + +--- + +### ๐Ÿค Claude Code Integration (`claude.yml`) + +**Purpose**: Integrates Claude Code with GitHub workflows. + +**Triggers**: +- Issue/PR comments with @claude mentions +- Issue/PR opened or assigned + +**What It Does**: +- Enables Claude Code AI assistance in issues/PRs +- Provides AI-powered code review and suggestions +- Supports fork-compatible checkouts + +--- + +### ๐Ÿ” Claude Code Review (`claude-code-review.yml`) + +**Purpose**: Automated code reviews using Claude. + +**Triggers**: +- Pull requests opened or synchronized + +**What It Does**: +1. Checks out PR head (supports forks) +2. Minimizes old review comments +3. Runs comprehensive code review +4. Posts structured review (Blocker/Critical/Major/Minor issues) + +**Requirements**: +- `CLAUDE_CODE_OAUTH_TOKEN` secret configured + +--- + +### ๐Ÿ› ๏ธ Go Lint (`go-lint.yml`) + +**Purpose**: Go code quality enforcement. + +**Triggers**: +- Push to main +- Pull requests affecting Go code + +**What It Does**: +1. Detects changes to backend/operator Go code +2. Checks gofmt formatting +3. Runs go vet +4. Runs golangci-lint + +--- + +### ๐ŸŽจ Frontend Lint (`frontend-lint.yml`) + +**Purpose**: Frontend code quality enforcement. + +**Triggers**: +- Push to main +- Pull requests affecting TypeScript/JavaScript code + +**What It Does**: +1. Detects changes to frontend code +2. Runs ESLint +3. TypeScript type checking +4. Build validation (`npm run build`) + +--- + +### ๐Ÿš€ Production Release Deploy (`prod-release-deploy.yaml`) + +**Purpose**: Production releases with semver versioning. + +**Triggers**: +- Manual workflow dispatch only + +**What It Does**: +1. Calculates next version (major/minor/patch bump) +2. Generates changelog from git commits +3. Creates git tag and GitHub release +4. Builds all component images with release tag +5. Deploys to production OpenShift cluster + +**Requirements**: +- `PROD_OPENSHIFT_SERVER` and `PROD_OPENSHIFT_TOKEN` secrets + +--- + +### ๐Ÿ“š Documentation Deploy (`docs.yml`) + +**Purpose**: Deploy MkDocs documentation to GitHub Pages. + +**Triggers**: +- Push to main +- Manual workflow dispatch + +**What It Does**: +1. Builds docs with MkDocs in UBI9 container +2. Deploys to GitHub Pages + +--- + +## Workflow Permissions + +All workflows follow **principle of least privilege**: + +```yaml +permissions: + contents: read # Default for reading code + issues: write # Only for issue-handling workflows + pull-requests: write # Only for PR-creating workflows + packages: write # Only for image publishing +``` + +## Security Considerations + +### Secrets Required + +| Secret | Used By | Purpose | +|--------|---------|---------| +| `ANTHROPIC_API_KEY` | amber-issue-handler.yml | Claude API access | +| `CLAUDE_CODE_OAUTH_TOKEN` | claude-code-review.yml | Claude Code action authentication | +| `QUAY_USERNAME`, `QUAY_PASSWORD` | components-build-deploy.yml, prod-release-deploy.yaml | Quay.io registry access | +| `REDHAT_USERNAME`, `REDHAT_PASSWORD` | components-build-deploy.yml, prod-release-deploy.yaml | Red Hat registry access | +| `OPENSHIFT_SERVER`, `OPENSHIFT_TOKEN` | components-build-deploy.yml | OpenShift cluster access (dev) | +| `PROD_OPENSHIFT_SERVER`, `PROD_OPENSHIFT_TOKEN` | prod-release-deploy.yaml | OpenShift cluster access (prod) | +| `GITHUB_TOKEN` | All workflows | GitHub API access (auto-provided) | + +### Command Injection Prevention + +All workflows use **environment variables** to pass user input (issue titles, bodies, comments) to prevent command injection attacks. + +**Example (Safe)**: +```yaml +env: + ISSUE_TITLE: ${{ github.event.issue.title }} +run: echo "$ISSUE_TITLE" +``` + +**Anti-Pattern (Unsafe)**: +```yaml +run: echo "${{ github.event.issue.title }}" # โŒ Vulnerable to injection +``` + +**Reference**: [GitHub Actions Security Guide](https://github.blog/security/vulnerability-research/how-to-catch-github-actions-workflow-injections-before-attackers-do/) + +--- + +## Monitoring + +### View All Workflow Runs + +```bash +gh run list +``` + +### View Specific Workflow + +```bash +gh run list --workflow=amber-issue-handler.yml +``` + +### Watch Running Workflow + +```bash +gh run watch +``` + +### View Logs + +```bash +gh run view --log +``` + +--- + +## Troubleshooting + +### Workflow Not Triggering + +**Check**: +1. Workflow file syntax: `gh workflow list` +2. Trigger conditions match event +3. Workflow permissions enabled (Settings โ†’ Actions) + +**Debug**: +```bash +# View workflow status +gh workflow view amber-issue-handler.yml + +# Check recent runs +gh run list --workflow=amber-issue-handler.yml --limit 5 +``` + +### Workflow Failing + +**Common Issues**: +1. Missing secret (check Settings โ†’ Secrets) +2. Insufficient permissions (check workflow `permissions:`) +3. Syntax error in YAML (use `yamllint`) + +**Debug**: +```bash +# View failure logs +gh run view --log-failed + +# Re-run failed jobs +gh run rerun --failed +``` + +--- + +## Adding New Workflows + +### Checklist + +- [ ] Define clear trigger conditions (`on:`) +- [ ] Set minimal permissions (`permissions:`) +- [ ] Use env vars for user input (prevent injection) +- [ ] Add documentation to this README +- [ ] Test in fork before merging +- [ ] Add workflow badge to main README (optional) + +### Template + +```yaml +name: Your Workflow Name + +on: + # Define triggers + push: + branches: [main] + +permissions: + contents: read # Minimal permissions + +jobs: + your-job: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Your step + env: + # Use env vars for user input + INPUT: ${{ github.event.inputs.value }} + run: | + echo "$INPUT" +``` + +--- + +## Best Practices + +### โœ… Do + +- Use latest action versions (`actions/checkout@v4`) +- Set explicit permissions per workflow +- Pass user input via environment variables +- Cache dependencies (npm, pip, Go modules) +- Fail fast for critical errors + +### โŒ Don't + +- Use `permissions: write-all` (too broad) +- Interpolate user input directly in `run:` commands +- Hardcode secrets (use GitHub Secrets) +- Run workflows on every push (use path filters) +- Ignore security warnings from GitHub + +--- + +## Related Documentation + +- [Amber Automation Guide](../../docs/amber-automation.md) +- [E2E Testing Guide](../../docs/testing/e2e-guide.md) +- [GitHub Actions Docs](https://docs.github.com/en/actions) +- [Security Best Practices](https://docs.github.com/en/actions/security-for-github-actions) + +--- + +**Questions?** Create an issue with label `workflow:help` diff --git a/.github/workflows/ai-assessment-comment-labeler.yml b/.github/workflows/ai-assessment-comment-labeler.yml deleted file mode 100644 index 0418be829..000000000 --- a/.github/workflows/ai-assessment-comment-labeler.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: AI Assessment Comment Labeler - -on: - issues: - types: [labeled] - -permissions: - issues: write - models: read - contents: read - -jobs: - ai-assessment: - runs-on: ubuntu-latest - if: contains(github.event.label.name, 'ai-review') || contains(github.event.label.name, 'request ai review') - - steps: - - uses: actions/checkout@v5 - - uses: actions/setup-node@v6 - - name: Run AI assessment - uses: github/ai-assessment-comment-labeler@main - with: - token: ${{ secrets.GITHUB_TOKEN }} - issue_number: ${{ github.event.issue.number }} - issue_body: ${{ github.event.issue.body }} - ai_review_label: 'ai-review' - prompts_directory: './Prompts' - labels_to_prompts_mapping: 'bug,bug-assessment.prompt.yml|enhancement,feature-assessment.prompt.yml|question,general-assessment.prompt.yml|documentation,general-assessment.prompt.yml|default,general-assessment.prompt.yml' \ No newline at end of file diff --git a/.github/workflows/amber-issue-handler.yml b/.github/workflows/amber-issue-handler.yml new file mode 100644 index 000000000..3f87a4a83 --- /dev/null +++ b/.github/workflows/amber-issue-handler.yml @@ -0,0 +1,308 @@ +name: Amber Issue-to-PR Handler + +on: + issues: + types: [labeled, opened] + issue_comment: + types: [created] + +permissions: + contents: write + issues: write + pull-requests: write + +jobs: + amber-handler: + runs-on: ubuntu-latest + # Only run for specific labels or commands + if: | + (github.event.label.name == 'amber:auto-fix' || + github.event.label.name == 'amber:refactor' || + github.event.label.name == 'amber:test-coverage' || + contains(github.event.comment.body, '/amber execute')) + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Determine Amber action type + id: action-type + env: + LABEL_NAME: ${{ github.event.label.name }} + COMMENT_BODY: ${{ github.event.comment.body }} + run: | + # Parse label or comment to determine action + if [[ "$LABEL_NAME" == "amber:auto-fix" ]]; then + echo "type=auto-fix" >> $GITHUB_OUTPUT + echo "severity=low" >> $GITHUB_OUTPUT + elif [[ "$LABEL_NAME" == "amber:refactor" ]]; then + echo "type=refactor" >> $GITHUB_OUTPUT + echo "severity=medium" >> $GITHUB_OUTPUT + elif [[ "$LABEL_NAME" == "amber:test-coverage" ]]; then + echo "type=test-coverage" >> $GITHUB_OUTPUT + echo "severity=medium" >> $GITHUB_OUTPUT + elif [[ "$COMMENT_BODY" == *"/amber execute"* ]]; then + echo "type=execute-proposal" >> $GITHUB_OUTPUT + echo "severity=medium" >> $GITHUB_OUTPUT + else + echo "type=unknown" >> $GITHUB_OUTPUT + exit 1 + fi + + - name: Extract issue details + id: issue-details + uses: actions/github-script@v7 + with: + script: | + const issue = context.payload.issue; + + // Parse issue body for Amber-compatible context + const body = issue.body || ''; + + // Extract file paths mentioned in issue (safely) + const filePattern = /(?:File|Path):\s*`?([^\s`]+)`?/gi; + const files = [...body.matchAll(filePattern)].map(m => m[1]); + + // Extract specific instructions (safely) + const instructionPattern = /(?:Instructions?|Task):\s*\n([\s\S]*?)(?:\n#{2,}|\n---|\n\*\*|$)/i; + const instructionMatch = body.match(instructionPattern); + const instructions = instructionMatch ? instructionMatch[1].trim() : ''; + + // Set outputs (all values are safe - no command injection risk) + core.setOutput('issue_number', issue.number); + core.setOutput('issue_title', issue.title); + core.setOutput('issue_body', body); + core.setOutput('files', JSON.stringify(files)); + core.setOutput('instructions', instructions || issue.title); + + console.log('Parsed issue:', { + number: issue.number, + title: issue.title, + files: files, + instructions: instructions || issue.title + }); + + - name: Create Amber agent prompt + id: create-prompt + env: + ISSUE_NUMBER: ${{ steps.issue-details.outputs.issue_number }} + ISSUE_TITLE: ${{ steps.issue-details.outputs.issue_title }} + ISSUE_INSTRUCTIONS: ${{ steps.issue-details.outputs.instructions }} + ISSUE_FILES: ${{ steps.issue-details.outputs.files }} + ACTION_TYPE: ${{ steps.action-type.outputs.type }} + ACTION_SEVERITY: ${{ steps.action-type.outputs.severity }} + run: | + # Create prompt file using environment variables (safe from injection) + cat > /tmp/amber-prompt.md <<'EOF' + # Amber Agent Task + + You are Amber, an automated background agent. Execute the following task based on issue context. + + ## Issue Details + + **Issue Number:** #${ISSUE_NUMBER} + **Title:** ${ISSUE_TITLE} + **Action Type:** ${ACTION_TYPE} + **Severity:** ${ACTION_SEVERITY} + + ## Instructions + + ${ISSUE_INSTRUCTIONS} + + ## Files (if specified) + + ${ISSUE_FILES} + + ## Your Mission + + Based on the action type, perform the following: + + ### For `auto-fix` type: + 1. Identify the specific linting/formatting issues mentioned + 2. Run appropriate formatters (gofmt, black, prettier, etc.) + 3. Fix any trivial issues (unused imports, spacing, etc.) + 4. Ensure all changes pass existing tests + 5. Create a clean commit with conventional format + + ### For `refactor` type: + 1. Analyze the current code structure + 2. Implement the refactoring as described in the issue + 3. Ensure backward compatibility (no breaking changes) + 4. Add/update tests to cover refactored code + 5. Verify all existing tests still pass + + ### For `test-coverage` type: + 1. Analyze current test coverage for specified files + 2. Identify untested code paths + 3. Write contract tests following project standards (see CLAUDE.md) + 4. Ensure tests follow table-driven test pattern (Go) or pytest patterns (Python) + 5. Verify all new tests pass + + ### For `execute-proposal` type: + 1. Read the full issue body for the proposed implementation + 2. Execute the changes as specified in the proposal + 3. Follow the risk assessment and rollback plan provided + 4. Ensure all testing strategies are implemented + + ## Requirements + + - Follow all standards in CLAUDE.md + - Use conventional commit format: `type(scope): message` + - Run all linters BEFORE committing: + - Go: `gofmt -w .`, `golangci-lint run` + - Python: `black .`, `isort .`, `flake8` + - TypeScript: `npm run lint` + - Ensure ALL tests pass: `make test` (if Makefile exists) + - Create focused, minimal changes (no scope creep) + + ## Success Criteria + + - All linters pass with 0 warnings + - All existing tests pass + - New code follows project conventions + - Commit message is clear and follows conventional format + - Changes are focused on issue scope only + + ## Output Format + + After completing the work: + 1. Commit changes with conventional commit format + 2. Include reference to issue number in commit body + 3. Run all validation checks + + Execute this task now. + EOF + + # Substitute environment variables into the template + envsubst < /tmp/amber-prompt.md > /tmp/amber-prompt-final.md + + echo "prompt_file=/tmp/amber-prompt-final.md" >> $GITHUB_OUTPUT + + # Show prompt for debugging (safe - no secrets) + echo "=== Generated Prompt ===" + cat /tmp/amber-prompt-final.md + + - name: Execute Amber agent via Claude Code + id: amber-execute + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + ISSUE_NUMBER: ${{ steps.issue-details.outputs.issue_number }} + ISSUE_TITLE: ${{ steps.issue-details.outputs.issue_title }} + ACTION_TYPE: ${{ steps.action-type.outputs.type }} + PROMPT_FILE: ${{ steps.create-prompt.outputs.prompt_file }} + uses: anthropics/claude-code-action@v1 + with: + anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} + prompt_file: /tmp/amber-prompt-final.md + auto_commit: true + commit_message: | + fix(amber): address issue #${{ steps.issue-details.outputs.issue_number }} + + Automated fix by Amber agent for: ${{ steps.issue-details.outputs.issue_title }} + + Action type: ${{ steps.action-type.outputs.type }} + + ๐Ÿค– Generated with Amber Background Agent + + Resolves: #${{ steps.issue-details.outputs.issue_number }} + + - name: Create Pull Request + if: success() + env: + ISSUE_NUMBER: ${{ steps.issue-details.outputs.issue_number }} + ISSUE_TITLE: ${{ steps.issue-details.outputs.issue_title }} + ACTION_TYPE: ${{ steps.action-type.outputs.type }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + # Configure git + git config user.name "Amber Agent" + git config user.email "amber@ambient-code.ai" + + # Check if changes were made + if git diff --quiet HEAD; then + echo "No changes made by Amber" + echo "has_changes=false" >> $GITHUB_OUTPUT + exit 0 + fi + + # Create feature branch (sanitize title for branch name) + SANITIZED_TITLE=$(echo "$ISSUE_TITLE" | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]-' | cut -c1-50) + BRANCH_NAME="amber/issue-${ISSUE_NUMBER}-${SANITIZED_TITLE}" + + # Create and push branch + git checkout -b "$BRANCH_NAME" + git push -u origin "$BRANCH_NAME" + + # Create PR using gh CLI + gh pr create \ + --title "[Amber] Fix: ${ISSUE_TITLE}" \ + --body "## Automated Fix by Amber Agent + + This PR addresses issue #${ISSUE_NUMBER} using the Amber background agent. + + ### Changes Summary + - **Action Type:** ${ACTION_TYPE} + - **Triggered by:** Issue label/command + + ### Pre-merge Checklist + - [ ] All linters pass + - [ ] All tests pass + - [ ] Changes follow project conventions (CLAUDE.md) + - [ ] No scope creep beyond issue description + + ### Reviewer Notes + This PR was automatically generated. Please review: + 1. Code quality and adherence to standards + 2. Test coverage for changes + 3. No unintended side effects + + --- + ๐Ÿค– Generated with [Amber Background Agent](https://github.com/${GITHUB_REPOSITORY}/blob/main/.claude/amber-config.yml) + + Closes #${ISSUE_NUMBER}" \ + --label "amber-generated,auto-fix,${ACTION_TYPE}" \ + --base main + + # Get PR number and comment on issue + PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --json number --jq '.[0].number') + + gh issue comment "${ISSUE_NUMBER}" --body "๐Ÿค– Amber has created a pull request to address this issue: #${PR_NUMBER} + + The changes are ready for review. All automated checks will run on the PR." + + - name: Report failure + if: failure() + env: + ISSUE_NUMBER: ${{ steps.issue-details.outputs.issue_number }} + ACTION_TYPE: ${{ steps.action-type.outputs.type }} + RUN_ID: ${{ github.run_id }} + GITHUB_SERVER_URL: ${{ github.server_url }} + GITHUB_REPOSITORY: ${{ github.repository }} + uses: actions/github-script@v7 + with: + script: | + const issueNumber = parseInt(process.env.ISSUE_NUMBER); + const actionType = process.env.ACTION_TYPE; + const runId = process.env.RUN_ID; + const serverUrl = process.env.GITHUB_SERVER_URL; + const repository = process.env.GITHUB_REPOSITORY; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + body: `โš ๏ธ Amber encountered an error while processing this issue. + + **Action Type:** ${actionType} + **Workflow Run:** ${serverUrl}/${repository}/actions/runs/${runId} + + Please review the workflow logs for details. You may need to: + 1. Check if the issue description provides sufficient context + 2. Verify the specified files exist + 3. Ensure the changes are feasible for automation + + Manual intervention may be required for complex changes.` + }); diff --git a/.github/workflows/auto-assign-todo.yml b/.github/workflows/auto-assign-todo.yml deleted file mode 100644 index 55560e1e5..000000000 --- a/.github/workflows/auto-assign-todo.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Auto-assign Issues to Todo - -on: - issues: - types: [opened] - -permissions: - issues: write - repository-projects: write - contents: read - -jobs: - add-to-project-and-set-todo: - runs-on: ubuntu-latest - steps: - - name: Add issue to project - uses: actions/add-to-project@v1.0.2 - with: - project-url: https://github.com/orgs/red-hat-data-services/projects/12 - github-token: ${{ secrets.GITHUB_TOKEN }} - - - name: Set issue to Todo status - uses: actions/github-script@v8 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - console.log('Issue already added to project by previous step. Todo status assignment handled by GitHub project automation.'); - // Note: The actions/add-to-project action handles the basic addition - // Additional status field manipulation can be done here if needed - // but GitHub projects often have their own automation rules \ No newline at end of file diff --git a/.github/workflows/outcome-metrics.yml b/.github/workflows/outcome-metrics.yml deleted file mode 100644 index 1518da4c8..000000000 --- a/.github/workflows/outcome-metrics.yml +++ /dev/null @@ -1,100 +0,0 @@ -name: Outcome Metrics Dashboard - -on: - schedule: - - cron: '0 6 * * 1' # Weekly on Mondays at 6 AM UTC - workflow_dispatch: # Allow manual triggers - -jobs: - generate-metrics: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v5 - - - name: Generate outcome metrics report - uses: actions/github-script@v8 - with: - script: | - const { owner, repo } = context.repo; - - // Get all outcomes - const outcomes = await github.rest.search.issuesAndPullRequests({ - q: `repo:${owner}/${repo} is:issue label:outcome` - }); - - let metricsReport = `# ๐Ÿ“Š Outcome Metrics Report\n\n`; - metricsReport += `*Generated: ${new Date().toISOString().split('T')[0]}*\n\n`; - metricsReport += `## Summary\n\n`; - metricsReport += `- **Total Outcomes**: ${outcomes.data.total_count}\n`; - - let completedOutcomes = 0; - let activeOutcomes = 0; - let plannedOutcomes = 0; - - for (const outcome of outcomes.data.items) { - // Get epics for this outcome - const epics = await github.rest.search.issuesAndPullRequests({ - q: `repo:${owner}/${repo} is:issue label:epic "Parent Outcome: #${outcome.number}"` - }); - - const totalEpics = epics.data.total_count; - const closedEpics = epics.data.items.filter(epic => epic.state === 'closed').length; - const progressPercent = totalEpics > 0 ? Math.round((closedEpics / totalEpics) * 100) : 0; - - if (progressPercent === 100) { - completedOutcomes++; - } else if (progressPercent > 0) { - activeOutcomes++; - } else { - plannedOutcomes++; - } - - metricsReport += `\n## ${outcome.title}\n`; - metricsReport += `- **Progress**: ${closedEpics}/${totalEpics} epics (${progressPercent}%)\n`; - metricsReport += `- **Status**: ${outcome.state}\n`; - metricsReport += `- **Link**: [#${outcome.number}](${outcome.html_url})\n`; - - if (totalEpics > 0) { - metricsReport += `\n### Epics Breakdown\n`; - for (const epic of epics.data.items) { - const status = epic.state === 'closed' ? 'โœ…' : '๐Ÿ”„'; - metricsReport += `${status} [${epic.title}](${epic.html_url})\n`; - } - } - } - - metricsReport += `\n## Overall Status\n`; - metricsReport += `- **Completed**: ${completedOutcomes}\n`; - metricsReport += `- **Active**: ${activeOutcomes}\n`; - metricsReport += `- **Planned**: ${plannedOutcomes}\n`; - - // Create or update metrics issue - try { - const existingIssue = await github.rest.search.issuesAndPullRequests({ - q: `repo:${owner}/${repo} is:issue in:title "Outcome Metrics Dashboard"` - }); - - if (existingIssue.data.total_count > 0) { - // Update existing dashboard issue - await github.rest.issues.update({ - owner, - repo, - issue_number: existingIssue.data.items[0].number, - body: metricsReport - }); - console.log('Updated existing metrics dashboard'); - } else { - // Create new dashboard issue - await github.rest.issues.create({ - owner, - repo, - title: '๐Ÿ“Š Outcome Metrics Dashboard', - body: metricsReport, - labels: ['metrics', 'dashboard'] - }); - console.log('Created new metrics dashboard'); - } - } catch (error) { - console.error('Error managing metrics dashboard:', error); - } \ No newline at end of file diff --git a/.github/workflows/project-automation.yml b/.github/workflows/project-automation.yml deleted file mode 100644 index 3d3137eed..000000000 --- a/.github/workflows/project-automation.yml +++ /dev/null @@ -1,102 +0,0 @@ -name: Project Automation - -on: - issues: - types: [opened, edited, labeled, unlabeled, closed, reopened] - issue_comment: - types: [created] - -jobs: - auto-add-to-project: - runs-on: ubuntu-latest - if: github.event_name == 'issues' && github.event.action == 'opened' - steps: - - name: Add issue to project - uses: actions/add-to-project@v1.0.2 - with: - project-url: https://github.com/orgs/red-hat-data-services/projects/12 - github-token: ${{ secrets.GITHUB_TOKEN }} - - hierarchy-validation: - runs-on: ubuntu-latest - if: github.event_name == 'issues' && (github.event.action == 'opened' || github.event.action == 'labeled') - steps: - - name: Check hierarchy labels - uses: actions/github-script@v8 - with: - script: | - const { owner, repo, number } = context.issue; - const issue = await github.rest.issues.get({ - owner, - repo, - issue_number: number - }); - - const labels = issue.data.labels.map(l => l.name); - const hasOutcome = labels.includes('outcome'); - const hasEpic = labels.includes('epic'); - const hasStory = labels.includes('story'); - - // Validate hierarchy rules - const hierarchyCount = [hasOutcome, hasEpic, hasStory].filter(Boolean).length; - - if (hierarchyCount > 1) { - await github.rest.issues.createComment({ - owner, - repo, - issue_number: number, - body: 'โš ๏ธ **Hierarchy Validation**: Issues should have only one hierarchy label (outcome, epic, or story). Please remove conflicting labels.' - }); - } - - // Auto-assign project fields based on hierarchy - if (hasOutcome) { - console.log('Outcome detected - should be added to outcome view'); - } else if (hasEpic) { - console.log('Epic detected - should be linked to outcome'); - } else if (hasStory) { - console.log('Story detected - should be linked to epic'); - } - - update-outcome-progress: - runs-on: ubuntu-latest - if: github.event_name == 'issues' && (github.event.action == 'closed' || github.event.action == 'reopened') - steps: - - name: Update parent outcome progress - uses: actions/github-script@v8 - with: - script: | - const { owner, repo, number } = context.issue; - const issue = await github.rest.issues.get({ - owner, - repo, - issue_number: number - }); - - const labels = issue.data.labels.map(l => l.name); - const isEpic = labels.includes('epic'); - - if (isEpic && issue.data.body) { - // Look for parent outcome reference in the body - const outcomeMatch = issue.data.body.match(/\*\*Parent Outcome:\*\* #(\d+)/); - if (outcomeMatch) { - const outcomeNumber = parseInt(outcomeMatch[1]); - - // Get all epics for this outcome - const epics = await github.rest.search.issuesAndPullRequests({ - q: `repo:${owner}/${repo} is:issue label:epic "Parent Outcome: #${outcomeNumber}"` - }); - - const totalEpics = epics.data.total_count; - const closedEpics = epics.data.items.filter(epic => epic.state === 'closed').length; - const progressPercent = totalEpics > 0 ? Math.round((closedEpics / totalEpics) * 100) : 0; - - // Comment on outcome with progress update - await github.rest.issues.createComment({ - owner, - repo, - issue_number: outcomeNumber, - body: `๐Ÿ“Š **Progress Update**: ${closedEpics}/${totalEpics} epics completed (${progressPercent}%)` - }); - } - } \ No newline at end of file diff --git a/AMBER_SETUP.md b/AMBER_SETUP.md new file mode 100644 index 000000000..1d3b333c3 --- /dev/null +++ b/AMBER_SETUP.md @@ -0,0 +1,513 @@ +# Amber Issue-to-PR Automation - Setup Complete โœ… + +This document summarizes the Amber automation system installed in this repository. + +## What Was Installed + +### 1. GitHub Actions Workflow +**File**: `.github/workflows/amber-issue-handler.yml` + +**What It Does**: +- Monitors GitHub issues for specific labels (`amber:auto-fix`, `amber:refactor`, `amber:test-coverage`) +- Extracts instructions and file paths from issue body +- Executes Amber agent via Claude Code SDK +- Creates pull request with automated fixes +- Links PR back to original issue + +**Security Features**: +- Environment variable injection prevention (no command injection vulnerabilities) +- Minimal permissions (contents:write, issues:write, pull-requests:write) +- Token redaction in logs +- Follows GitHub security best practices + +--- + +### 2. Issue Templates +**Location**: `.github/ISSUE_TEMPLATE/` + +**Templates**: +1. **amber-auto-fix.yml** - Low-risk fixes (formatting, linting) +2. **amber-refactor.yml** - Medium-risk changes (breaking files, extracting patterns) +3. **amber-test-coverage.yml** - Test additions (unit/contract/integration) +4. **config.yml** - Template configuration with documentation links + +**Features**: +- Structured forms with validation +- Pre-filled labels for automatic triggering +- Clear instructions and examples +- Risk acknowledgment checkboxes + +--- + +### 3. Automation Configuration +**File**: `.claude/amber-config.yml` + +**Defines**: +- Risk-based automation policies (low/medium/high) +- Auto-fix categories (formatting, linting, docs) +- Proposal workflow for medium-risk changes +- Report-only mode for high-risk changes +- Constitution compliance checks +- Monitoring schedules (daily/weekly/monthly) + +**Key Settings**: +```yaml +max_auto_prs_per_day: 5 # Safety guardrail +require_tests_pass: true # Quality check +never_push_to_main: true # Branch protection +always_create_branch: true # Safe workflow +``` + +--- + +### 4. Documentation +**Files**: +1. **docs/amber-automation.md** - Complete automation guide (4,000+ words) + - How it works + - Available workflows + - Configuration + - Security + - Troubleshooting + - Best practices + - FAQ + +2. **docs/amber-quickstart.md** - Get started in 5 minutes + - Prerequisites + - Setup steps + - Three usage examples + - Monitoring commands + +3. **.github/workflows/README.md** - Workflows documentation + - All active workflows + - Permissions + - Security considerations + - Troubleshooting + +4. **CLAUDE.md** - Updated with Amber section + - Quick links to documentation + - Common workflows summary + +--- + +## Setup Required (One-Time) + +### 1. Add Anthropic API Key + +```bash +# Via GitHub CLI +gh secret set ANTHROPIC_API_KEY +# Paste your key: sk-ant-... + +# Or via GitHub UI: +# Settings โ†’ Secrets and variables โ†’ Actions โ†’ New repository secret +``` + +### 2. Enable GitHub Actions Permissions + +**Settings โ†’ Actions โ†’ General โ†’ Workflow permissions**: +- โœ… Read and write permissions +- โœ… Allow GitHub Actions to create and approve pull requests + +### 3. Verify Installation + +```bash +# Check workflow exists +gh workflow view amber-issue-handler.yml + +# Should show: "amber-issue-handler.yml (active)" +``` + +--- + +## Quick Test + +### Create Test Issue + +1. Go to **Issues โ†’ New Issue** +2. Select **๐Ÿค– Amber Auto-Fix Request** +3. Fill in: + ``` + Title: [Amber] Test automation + Description: Test Amber workflow with a trivial fix + Files: README.md + Fix Type: Code Formatting + ``` +4. Submit + +### Expected Outcome + +1. **~30 seconds**: GitHub Actions workflow starts +2. **~2 minutes**: Amber analyzes and creates branch +3. **~2-3 minutes**: PR is created and linked to issue + +### Verify + +```bash +# View the PR +gh pr list --label amber-generated + +# View workflow run +gh run list --workflow=amber-issue-handler.yml --limit 1 +``` + +--- + +## Usage Examples + +### Example 1: Fix Linting + +**Issue**: +```yaml +Title: [Amber] Fix Go formatting in backend +Label: amber:auto-fix +Files: components/backend/**/*.go +``` + +**Outcome**: PR with `gofmt -w .` applied + +--- + +### Example 2: Refactor Large File + +**Issue**: +```yaml +Title: [Amber Refactor] Break sessions.go into modules +Label: amber:refactor +Current State: handlers/sessions.go (3,495 lines) +Desired State: Break into lifecycle.go, status.go, jobs.go +``` + +**Outcome**: PR with modular file structure, all tests passing + +--- + +### Example 3: Add Tests + +**Issue**: +```yaml +Title: [Amber Tests] Add contract tests for Projects API +Label: amber:test-coverage +Untested Code: handlers/projects.go (CreateProject, DeleteProject) +Target Coverage: 60% +``` + +**Outcome**: PR with table-driven tests (Go convention) + +--- + +## Monitoring + +### View All Amber Activity + +```bash +# All Amber PRs +gh pr list --label amber-generated + +# Recent workflow runs +gh run list --workflow=amber-issue-handler.yml + +# Success rate +gh pr list --label amber-generated --state merged | wc -l +gh pr list --label amber-generated --state closed | wc -l +``` + +### Metrics to Track + +- **PR Merge Rate**: Target 90%+ (high-quality automation) +- **Time to Merge**: Faster than manual fixes +- **Issue Resolution Time**: Should decrease over time +- **Developer Satisfaction**: Gather feedback on usefulness + +--- + +## Configuration Tuning + +### Increase Automation Aggressiveness + +Edit `.claude/amber-config.yml`: + +```yaml +automation_policies: + auto_fix: + max_files_per_pr: 20 # Default: 10 + auto_merge: true # Default: false (requires approval) +``` + +### Add New Fix Categories + +```yaml +categories: + - name: "Import Optimization" + patterns: + - "unused imports in TypeScript" + - "import sorting violations" + commands: + typescript: ["npm run lint:fix"] +``` + +### Change Monitoring Schedule + +```yaml +monitoring: + schedule: + daily: + - "check_recent_commits" + - "run_security_scan" # Add custom check +``` + +--- + +## Troubleshooting + +### Workflow Not Triggering + +**Symptoms**: Issue labeled but no workflow run + +**Debug**: +```bash +# Check workflow is enabled +gh workflow view amber-issue-handler.yml + +# Check permissions +# Settings โ†’ Actions โ†’ General โ†’ Workflow permissions +# Should be "Read and write permissions" + +# Check secret exists +gh secret list | grep ANTHROPIC_API_KEY +``` + +--- + +### Amber Commented "Error" + +**Symptoms**: Workflow ran but commented error on issue + +**Actions**: +1. Click workflow run link in error comment +2. Review logs: `gh run view --log` +3. Common issues: + - Missing file paths in issue + - Vague instructions + - Changes too complex for automation + +**Fix**: Update issue with more context, re-label to re-trigger + +--- + +### PR Tests Failing + +**Symptoms**: Amber created PR but CI fails + +**Actions**: +1. Review PR diff manually +2. Amber should have run linters before committing +3. CI may have additional checks Amber doesn't know about +4. Add failing check to `.claude/amber-config.yml` + +--- + +## Next Steps + +### 1. Test with Low-Risk Issue (5 min) + +Create simple auto-fix issue to verify workflow + +### 2. Review Generated PR (10 min) + +Understand Amber's approach and code quality + +### 3. Add Custom Patterns (30 min) + +Extend `.claude/amber-config.yml` with project-specific patterns + +### 4. Train Team (1 hour) + +Share quickstart guide, demonstrate creating issues + +### 5. Monitor & Iterate (ongoing) + +Track metrics, gather feedback, tune configuration + +--- + +## Architecture Notes + +### Why GitHub Actions? + +- **Self-Service**: Any team member can trigger Amber via issues +- **Audit Trail**: All changes tracked via issues โ†’ PRs โ†’ commits +- **Access Control**: GitHub's built-in permissions system +- **No Infrastructure**: Runs on GitHub's hosted runners +- **Integration**: Native GitHub API access + +### Why Issue-Driven? + +- **Async Workflow**: Create issue, come back to PR later +- **Discussion**: Team can discuss approach in issue before Amber executes +- **Approval**: `/amber execute` comment requires explicit trigger +- **Linking**: PRs automatically close issues, creating traceability + +### Why Labels? + +- **Declarative**: Label = intent, no complex commands +- **Filterable**: Easy to find all `amber:*` issues +- **Automatable**: GitHub Actions triggers on label events +- **User-Friendly**: Point-and-click vs. CLI commands + +--- + +## Advanced Usage + +### Custom Amber Agents + +Extend workflow to support custom agents: + +```yaml +# In amber-issue-handler.yml +if: github.event.label.name == 'amber:custom-agent' +``` + +Then specify agent in issue body: + +```markdown +Agent: Steve (UX Designer) +Task: Create mockup for new feature page +``` + +### Integration with Other Tools + +Amber can integrate with: +- **Jira**: Comment on linked Jira ticket when PR created +- **Slack**: Notify channel of Amber activity +- **PagerDuty**: Create incident if Amber fails repeatedly +- **Datadog**: Send metrics on Amber performance + +Add integrations in workflow's final steps. + +--- + +## Security Considerations + +### Secrets Management + +- โœ… `ANTHROPIC_API_KEY` stored as GitHub secret (encrypted at rest) +- โœ… Never logged or exposed in workflow runs +- โœ… Only accessible to workflow, not forks +- โœ… Rotation: Update secret, no code changes required + +### Command Injection Prevention + +- โœ… All user input passed via environment variables +- โœ… No direct interpolation of `${{ github.event.* }}` +- โœ… Reviewed by security hook in Claude Code +- โœ… Follows GitHub's official security guidelines + +### Branch Protection + +- โœ… Amber never pushes to `main` (creates feature branches) +- โœ… All changes go through PR review +- โœ… CI must pass before merge +- โœ… Human approval required (no auto-merge by default) + +--- + +## Cost Estimate + +### Anthropic API Usage + +**Per Workflow Run**: +- Auto-fix: ~10K tokens = $0.03 +- Refactoring: ~50K tokens = $0.15 +- Test coverage: ~30K tokens = $0.09 + +**Monthly (example: 50 runs)**: +- 30 auto-fixes ร— $0.03 = $0.90 +- 15 refactorings ร— $0.15 = $2.25 +- 5 test additions ร— $0.09 = $0.45 +- **Total: ~$3.60/month** + +**ROI**: If each Amber run saves 30 minutes of developer time at $50/hour = $25 saved per run. 50 runs = $1,250 value for $3.60 cost. + +--- + +## Support + +### Documentation + +- [Complete Guide](docs/amber-automation.md) +- [Quickstart](docs/amber-quickstart.md) +- [Workflows README](.github/workflows/README.md) + +### Getting Help + +**Issues with Amber**: +1. Create issue with label `amber:help` +2. Include workflow run link +3. Describe expected vs. actual behavior + +**Feature Requests**: +- Title: `[Amber Feature Request] ...` +- Describe desired capability +- Include use case examples + +**Bugs**: +- Title: `[Amber Bug] ...` +- Include workflow run link +- Steps to reproduce + +--- + +## Success Metrics + +Track these to measure Amber's effectiveness: + +### Quantitative + +- **PR Merge Rate**: % of Amber PRs merged (target: 90%+) +- **Time to Merge**: Time from issue creation to PR merge +- **Developer Time Saved**: Estimated hours saved per week +- **Issue Resolution Rate**: % of issues successfully automated + +### Qualitative + +- **Developer Satisfaction**: Survey team on usefulness +- **Code Quality**: Review generated code quality +- **Adoption Rate**: % of eligible issues using Amber +- **Team Feedback**: Gather suggestions for improvement + +--- + +## Roadmap + +### Phase 1: Foundation (Current) + +- โœ… Basic auto-fix workflow +- โœ… Issue templates +- โœ… Documentation + +### Phase 2: Enhancement (Next) + +- [ ] Auto-merge for trusted patterns +- [ ] Slack notifications +- [ ] Metrics dashboard +- [ ] Custom agent support + +### Phase 3: Intelligence (Future) + +- [ ] Amber learns from rejected PRs +- [ ] Proactive issue creation (Amber finds issues) +- [ ] Multi-agent collaboration +- [ ] Predictive maintenance + +--- + +**Amber is ready to use!** ๐Ÿค– + +Create your first issue and experience automated development workflows. + +**Quick Links**: +- [Quickstart](docs/amber-quickstart.md) +- [Full Documentation](docs/amber-automation.md) +- [Create Auto-Fix Issue](../../issues/new?template=amber-auto-fix.yml) +- [Create Refactoring Issue](../../issues/new?template=amber-refactor.yml) +- [Create Test Coverage Issue](../../issues/new?template=amber-test-coverage.yml) diff --git a/CLAUDE.md b/CLAUDE.md index c026d9c4a..d003374cd 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,6 +8,20 @@ The **Ambient Code Platform** is a Kubernetes-native AI automation platform that > **Note:** This project was formerly known as "vTeam". Technical artifacts (image names, namespaces, API groups) still use "vteam" for backward compatibility. +### Amber Background Agent + +The platform includes **Amber**, a background agent that automates common development tasks via GitHub Issues. Team members can trigger automated fixes, refactoring, and test additions without requiring direct access to Claude Code. + +**Quick Links**: +- [Amber Quickstart](docs/amber-quickstart.md) - Get started in 5 minutes +- [Full Documentation](docs/amber-automation.md) - Complete automation guide +- [Amber Config](.claude/amber-config.yml) - Automation policies + +**Common Workflows**: +- ๐Ÿค– **Auto-Fix** (label: `amber:auto-fix`): Formatting, linting, trivial fixes +- ๐Ÿ”ง **Refactoring** (label: `amber:refactor`): Break large files, extract patterns +- ๐Ÿงช **Test Coverage** (label: `amber:test-coverage`): Add missing tests + ### Core Architecture The system follows a Kubernetes-native pattern with Custom Resources, Operators, and Job execution: @@ -779,12 +793,28 @@ Study these files to understand established patterns: - **Registry**: Pushes to `quay.io/ambient_code` on main branch - **PR builds**: Build-only, no push on pull requests -### Other Workflows +### Automation Workflows + +- **amber-issue-handler.yml**: Amber background agent - automated fixes via GitHub issue labels (`amber:auto-fix`, `amber:refactor`, `amber:test-coverage`) or `/amber execute` command +- **amber-dependency-sync.yml**: Daily sync of dependency versions to Amber agent knowledge base +- **claude.yml**: Claude Code integration - responds to `@claude` mentions in issues/PRs +- **claude-code-review.yml**: Automated code reviews on pull requests -- **claude.yml**: Claude Code integration +### Code Quality Workflows + +- **go-lint.yml**: Go code formatting, vetting, and linting (gofmt, go vet, golangci-lint) +- **frontend-lint.yml**: Frontend code quality (ESLint, TypeScript checking, build validation) + +### Deployment & Testing Workflows + +- **prod-release-deploy.yaml**: Production releases with semver versioning and changelog generation +- **e2e.yml**: End-to-end Cypress testing in kind cluster (see Testing Strategy section) - **test-local-dev.yml**: Local development environment validation -- **dependabot-auto-merge.yml**: Automated dependency updates -- **project-automation.yml**: GitHub project board automation + +### Utility Workflows + +- **docs.yml**: Deploy MkDocs documentation to GitHub Pages +- **dependabot-auto-merge.yml**: Auto-approve and merge Dependabot dependency updates ## Testing Strategy diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 44496032f..142e9b13a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -92,6 +92,36 @@ Before contributing, ensure you have: git remote add upstream https://github.com/ambient-code/vTeam.git ``` +### Install Git Hooks (Recommended) + +To prevent accidental commits to protected branches (`main`, `master`, `production`), install our git hooks: + +```bash +make setup-hooks +``` + +Or run the installation script directly: + +```bash +./scripts/install-git-hooks.sh +``` + +**What the hooks do:** + +- **pre-commit** - Blocks commits to `main`/`master`/`production` branches +- **pre-push** - Blocks pushes to `main`/`master`/`production` branches + +**Hooks are automatically installed** when you run `make dev-start`. + +If you need to override the hooks (e.g., for hotfixes): + +```bash +git commit --no-verify -m "hotfix: critical fix" +git push --no-verify origin main +``` + +See [scripts/git-hooks/README.md](scripts/git-hooks/README.md) for more details. + ## Development Workflow ### 1. Create a Feature Branch diff --git a/Makefile b/Makefile index c11088ade..f93040b76 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help setup-env build-all build-frontend build-backend build-operator build-runner deploy clean dev-frontend dev-backend lint test registry-login push-all dev-start dev-stop dev-test dev-logs-operator dev-restart-operator dev-operator-status dev-test-operator e2e-test e2e-setup e2e-clean +.PHONY: help setup-env build-all build-frontend build-backend build-operator build-runner deploy clean dev-frontend dev-backend lint test registry-login push-all dev-start dev-stop dev-test dev-logs-operator dev-restart-operator dev-operator-status dev-test-operator e2e-test e2e-setup e2e-clean setup-hooks remove-hooks # Default target help: ## Show this help message @@ -83,8 +83,18 @@ push-all: ## Push all images to registry $(CONTAINER_ENGINE) push $(REGISTRY)/$(OPERATOR_IMAGE) $(CONTAINER_ENGINE) push $(REGISTRY)/$(RUNNER_IMAGE) +# Git hooks for branch protection +setup-hooks: ## Install git hooks for branch protection + @./scripts/install-git-hooks.sh + +remove-hooks: ## Remove git hooks + @echo "Removing git hooks..." + @rm -f .git/hooks/pre-commit + @rm -f .git/hooks/pre-push + @echo "โœ… Git hooks removed" + # Local dev helpers (OpenShift Local/CRC-based) -dev-start: ## Start local dev (CRC + OpenShift + backend + frontend) +dev-start: setup-hooks ## Start local dev (CRC + OpenShift + backend + frontend) @bash components/scripts/local-dev/crc-start.sh dev-stop: ## Stop local dev processes diff --git a/README.md b/README.md index 5dbd50cbb..9cd49b9e4 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,20 @@ The **Ambient Code Platform** is an AI automation platform that combines Claude - **Multi-Agent Workflows**: Specialized AI agents model realistic software team dynamics - **Kubernetes Native**: Built with Custom Resources, Operators, and proper RBAC for enterprise deployment - **Real-time Monitoring**: Live status updates and job execution tracking +- **๐Ÿค– Amber Background Agent**: Automated issue-to-PR workflows via GitHub Actions ([quickstart](docs/amber-quickstart.md)) + +### Amber: Self-Service Automation + +**Amber** is a background agent that handles GitHub issues automatically: + +- ๐Ÿค– **Auto-Fix**: Create issue with `amber:auto-fix` label โ†’ Amber creates PR with linting/formatting fixes +- ๐Ÿ”ง **Refactoring**: Label issue `amber:refactor` โ†’ Amber breaks large files, extracts patterns +- ๐Ÿงช **Test Coverage**: Use `amber:test-coverage` โ†’ Amber adds missing tests + +**Quick Links**: +- [5-Minute Quickstart](docs/amber-quickstart.md) +- [Complete Guide](docs/amber-automation.md) +- [Create Auto-Fix Issue](../../issues/new?template=amber-auto-fix.yml) ## Architecture diff --git a/docs/amber-automation.md b/docs/amber-automation.md new file mode 100644 index 000000000..55c48ae75 --- /dev/null +++ b/docs/amber-automation.md @@ -0,0 +1,436 @@ +# Amber Issue-to-PR Automation + +## Overview + +Amber is a background agent that automatically handles GitHub issues and creates pull requests. This system allows team members to trigger automated fixes, refactoring, and test additions without requiring direct access to Claude Code. + +## How It Works + +```mermaid +graph LR + A[Create Issue] --> B[Add Label] + B --> C[GHA Triggers] + C --> D[Amber Executes] + D --> E[Create PR] + E --> F[Review & Merge] +``` + +1. **Create Issue**: Team member creates an issue using one of the Amber templates +2. **Add Label**: Apply appropriate label (`amber:auto-fix`, `amber:refactor`, `amber:test-coverage`) +3. **GHA Triggers**: GitHub Actions workflow detects label and starts Amber +4. **Amber Executes**: Amber analyzes the issue and makes changes +5. **Create PR**: Amber creates a pull request with the changes +6. **Review & Merge**: Team reviews and merges the PR + +## Available Workflows + +### ๐Ÿค– Auto-Fix (Low Risk) + +**Trigger Label**: `amber:auto-fix` + +**Use For**: +- Code formatting (gofmt, black, prettier) +- Linting violations +- Unused import removal +- Documentation formatting + +**Template**: `.github/ISSUE_TEMPLATE/amber-auto-fix.yml` + +**Example**: +```yaml +Title: [Amber] Fix frontend linting errors +Label: amber:auto-fix +Body: + Issue: Frontend code fails eslint checks + Files: components/frontend/src/**/*.tsx + Fix Type: Linting Violations +``` + +**Expected Outcome**: PR with automated formatting/linting fixes, all tests pass + +--- + +### ๐Ÿ”ง Refactoring (Medium Risk) + +**Trigger Label**: `amber:refactor` + +**Use For**: +- Breaking large files into modules +- Extracting repeated patterns +- Replacing `context.TODO()` with proper context +- Improving error handling + +**Template**: `.github/ISSUE_TEMPLATE/amber-refactor.yml` + +**Example**: +```yaml +Title: [Amber Refactor] Break sessions.go into modules +Label: amber:refactor +Body: + Current State: handlers/sessions.go is 3,495 lines + Desired State: Break into lifecycle.go, status.go, jobs.go, validation.go + Constraints: Maintain backward compatibility, all tests pass + Priority: P0 +``` + +**Expected Outcome**: PR with refactored code, detailed migration notes, all tests pass + +--- + +### ๐Ÿงช Test Coverage (Medium Risk) + +**Trigger Label**: `amber:test-coverage` + +**Use For**: +- Adding missing unit tests +- Contract tests for API endpoints +- Edge case coverage +- Improving test coverage percentage + +**Template**: `.github/ISSUE_TEMPLATE/amber-test-coverage.yml` + +**Example**: +```yaml +Title: [Amber Tests] Add contract tests for sessions API +Label: amber:test-coverage +Body: + Untested Code: components/backend/handlers/sessions.go + Test Type: Contract Tests (API endpoints) + Test Scenarios: + - Happy path: create session with valid spec + - Error: missing API key + - Edge case: very long prompt + Target Coverage: 60% +``` + +**Expected Outcome**: PR with new tests following project conventions (table-driven for Go) + +--- + +## Advanced Usage + +### Manual Trigger via Comment + +You can also trigger Amber by commenting on an existing issue: + +``` +/amber execute +``` + +This tells Amber to execute the proposal described in the issue body. + +**Use Case**: After discussing a refactoring approach in an issue, comment `/amber execute` to have Amber implement it. + +--- + +### Issue Format Requirements + +For Amber to work effectively, structure your issue body like this: + +```markdown +## Problem +[Describe what needs to be fixed] + +## Files +File: `path/to/file.go` +File: `path/to/another.py` + +## Instructions +[Step-by-step instructions for Amber] + +## Success Criteria +- [ ] All linters pass +- [ ] All tests pass +- [ ] Follows CLAUDE.md standards +``` + +**Key Fields**: +- `File:` or `Path:` - Amber extracts file paths automatically +- `Instructions:` or `Task:` - Main instructions section +- Success criteria checklist + +--- + +## Configuration + +Amber's behavior is controlled by: + +1. **Workflow**: `.github/workflows/amber-issue-handler.yml` +2. **Config**: `.claude/amber-config.yml` (automation policies) +3. **Project Standards**: `CLAUDE.md` (Amber follows all project conventions) + +### Risk Levels + +Amber classifies changes by risk: + +| Risk | Actions | Auto-Merge | Examples | +|------|---------|------------|----------| +| **Low** | Auto-fix, create PR | No (requires review) | Formatting, linting | +| **Medium** | Create PR with proposal | No | Refactoring, test additions | +| **High** | Report only, no PR | N/A | Breaking changes, security issues | + +--- + +## Security + +The workflow follows **strict security practices**: + +1. **No Command Injection**: All user input (issue titles, bodies) passed via environment variables +2. **Token Scoping**: `GITHUB_TOKEN` has minimal permissions (contents:write, issues:write, pull-requests:write) +3. **Anthropic API Key**: Stored as GitHub secret (`ANTHROPIC_API_KEY`) +4. **Branch Protection**: Never pushes to `main`, always creates feature branches + +**Reference**: [GitHub Actions Security Guide](https://github.blog/security/vulnerability-research/how-to-catch-github-actions-workflow-injections-before-attackers-do/) + +--- + +## Monitoring + +### View Workflow Runs + +```bash +# Via GitHub CLI +gh run list --workflow=amber-issue-handler.yml + +# Watch specific run +gh run watch + +# View logs +gh run view --log +``` + +### Amber-Generated PRs + +All PRs created by Amber have: +- **Title**: `[Amber] Fix: ` +- **Labels**: `amber-generated`, `auto-fix`, `` +- **Body**: Detailed summary with links back to original issue + +--- + +## Troubleshooting + +### Amber Workflow Didn't Trigger + +**Possible Causes**: +1. Wrong label applied (must be exact: `amber:auto-fix`, not `amber auto-fix`) +2. Issue not in correct repository +3. `ANTHROPIC_API_KEY` secret not configured + +**Debug**: +```bash +gh run list --workflow=amber-issue-handler.yml --limit 5 +``` + +--- + +### Amber Created PR but Tests Failed + +**Expected Behavior**: Amber runs linters/tests before committing, but CI may have additional checks. + +**Actions**: +1. Review PR, identify failing test +2. Add comment to PR: `/amber fix-tests` +3. Amber will update the PR with fixes + +**Alternative**: Close PR, update original issue with additional context, re-trigger Amber + +--- + +### Amber Encountered Error + +Amber will comment on the issue with error details: + +``` +โš ๏ธ Amber encountered an error while processing this issue. + +**Action Type:** refactor +**Workflow Run:** [link to logs] + +Please review the workflow logs for details. +``` + +**Common Issues**: +- Issue description lacks sufficient context +- Specified files don't exist +- Changes too complex for automation (requires manual intervention) + +--- + +## Best Practices + +### โœ… Good Issue Examples + +**Auto-Fix**: +```markdown +Title: [Amber] Fix Go formatting in backend handlers +Label: amber:auto-fix + +## Problem +Backend handlers fail gofmt checks after recent commits. + +## Files +File: `components/backend/handlers/*.go` + +## Fix Type +Code Formatting +``` + +**Refactoring**: +```markdown +Title: [Amber Refactor] Extract git operations from sessions.go +Label: amber:refactor + +## Current State +File: `components/backend/handlers/sessions.go` (line 1200-1800) +Issue: Git operations mixed with session handling logic + +## Desired State +Create new file: `components/backend/git/session_operations.go` +Move git clone, fork, PR creation functions + +## Constraints +- Maintain current API (no breaking changes) +- Add unit tests for extracted functions +- All existing tests must pass +``` + +**Test Coverage**: +```markdown +Title: [Amber Tests] Add contract tests for Projects API +Label: amber:test-coverage + +## Untested Code +File: `components/backend/handlers/projects.go` +Functions: CreateProject, DeleteProject, ListProjects + +## Test Scenarios +- Happy path: create project with valid name +- Error: create project with duplicate name +- Error: create project with invalid characters +- Edge: list projects when none exist + +## Target Coverage +60% for projects.go +``` + +--- + +### โŒ Avoid These Patterns + +**Too Vague**: +```markdown +Title: Fix stuff +Label: amber:auto-fix + +Make the code better. +``` +*Issue*: No specific files, instructions, or success criteria + +**Too Broad**: +```markdown +Title: Refactor entire backend +Label: amber:refactor + +Rewrite all backend code to be perfect. +``` +*Issue*: Scope too large, no clear boundaries + +**Security Risk**: +```markdown +Title: Update API keys in code +Label: amber:auto-fix + +Hardcode new API keys in handlers. +``` +*Issue*: Amber will refuse (security violation) + +--- + +## Extending Amber + +### Adding New Workflow Types + +1. **Update workflow** (`.github/workflows/amber-issue-handler.yml`): + ```yaml + if: | + github.event.label.name == 'amber:your-new-type' + ``` + +2. **Create issue template** (`.github/ISSUE_TEMPLATE/amber-your-type.yml`) + +3. **Update config** (`.claude/amber-config.yml`): + ```yaml + automation_policies: + your_new_type: + enabled: true + categories: + - name: "Your New Type" + patterns: ["pattern1", "pattern2"] + ``` + +4. **Document** in this file + +--- + +## Metrics & Reporting + +Track Amber's effectiveness: + +```bash +# Count Amber-generated PRs +gh pr list --label amber-generated --state all + +# Amber success rate (merged vs. closed) +gh pr list --label amber-generated --state merged | wc -l +gh pr list --label amber-generated --state closed | wc -l + +# Average time from issue creation to PR merge +# (requires custom script or GitHub API) +``` + +**Goal**: 90% of Amber PRs merged without modification + +--- + +## FAQ + +**Q: Can Amber handle multiple files in one PR?** +A: Yes, specify multiple files in the issue body. Amber will modify all relevant files. + +**Q: Can I trigger Amber without an issue?** +A: No, issues provide context and audit trail. For ad-hoc tasks, create a temporary issue. + +**Q: What happens if Amber's PR conflicts with other work?** +A: Standard git conflict resolution. Review the PR, resolve conflicts manually, or close and re-trigger after merging other work. + +**Q: Can Amber create breaking changes?** +A: No, Amber is configured to reject breaking changes. It will comment on the issue if it detects a breaking change request. + +**Q: How much does Amber cost (API usage)?** +A: Depends on task complexity. Typical auto-fix: ~10K tokens ($0.03), refactoring: ~50K tokens ($0.15), test coverage: ~30K tokens ($0.09). Monitor via Anthropic dashboard. + +--- + +## Related Documentation + +- [Amber Configuration](.claude/amber-config.yml) - Automation policies +- [Project Standards](../CLAUDE.md) - Conventions Amber follows +- [GitHub Actions Security](https://docs.github.com/en/actions/security-for-github-actions) - Official security guide + +--- + +## Support + +**Issues with Amber automation**: +1. Check workflow logs: `gh run view --log` +2. Review issue format requirements (above) +3. Create issue with label `amber:help` for manual review + +**Feature Requests**: +Create issue titled `[Amber Feature Request] ...` describing desired capability. + +--- + +**Last Updated**: 2025-11-21 +**Maintained By**: Platform Team diff --git a/docs/amber-quickstart.md b/docs/amber-quickstart.md new file mode 100644 index 000000000..e9581847b --- /dev/null +++ b/docs/amber-quickstart.md @@ -0,0 +1,344 @@ +# Amber Issue-to-PR Automation - Quickstart + +Get Amber handling GitHub issues in 5 minutes. + +## Prerequisites + +- GitHub repository with Actions enabled +- Anthropic API key + +## Setup (One-Time) + +### 1. Add Anthropic API Key to GitHub Secrets + +```bash +# Via GitHub CLI +gh secret set ANTHROPIC_API_KEY + +# Or via GitHub UI: +# Settings โ†’ Secrets and variables โ†’ Actions โ†’ New repository secret +# Name: ANTHROPIC_API_KEY +# Value: sk-ant-... +``` + +### 2. Enable GitHub Actions Permissions + +**Settings โ†’ Actions โ†’ General โ†’ Workflow permissions**: +- โœ… Read and write permissions +- โœ… Allow GitHub Actions to create and approve pull requests + +### 3. Verify Workflow Exists + +```bash +ls .github/workflows/amber-issue-handler.yml +# Should exist - if not, check installation +``` + +## Usage + +### Method 1: Create Issue with Template (Recommended) + +1. **Go to Issues โ†’ New Issue** +2. **Select Template**: + - ๐Ÿค– Amber Auto-Fix Request + - ๐Ÿ”ง Amber Refactoring Request + - ๐Ÿงช Amber Test Coverage Request +3. **Fill Out Form** +4. **Submit Issue** + +Amber will automatically trigger and create a PR. + +--- + +### Method 2: Add Label to Existing Issue + +1. **Create or open an issue** +2. **Add one of these labels**: + - `amber:auto-fix` + - `amber:refactor` + - `amber:test-coverage` +3. **Amber triggers immediately** + +--- + +### Method 3: Comment Trigger + +On any existing issue, comment: + +``` +/amber execute +``` + +Amber will execute the proposal described in the issue body. + +--- + +## Example: Fix Linting Errors + +### Step 1: Create Issue + +**Title**: `[Amber] Fix Go formatting in backend` + +**Label**: `amber:auto-fix` + +**Body**: +```markdown +## Problem +Backend handlers fail gofmt checks. + +## Files +File: `components/backend/handlers/*.go` + +## Fix Type +Code Formatting +``` + +### Step 2: Wait for Amber + +- GitHub Actions workflow starts (~30 seconds) +- Amber analyzes code and applies fixes (~1-2 minutes) +- PR is created automatically + +### Step 3: Review PR + +```bash +# View the PR +gh pr list --label amber-generated + +# Review changes +gh pr view 123 + +# Merge if good +gh pr merge 123 --squash +``` + +**Done!** Linting errors fixed automatically. + +--- + +## Example: Refactor Large File + +### Step 1: Create Issue + +**Title**: `[Amber Refactor] Break sessions.go into modules` + +**Label**: `amber:refactor` + +**Body**: +```markdown +## Current State +File: `components/backend/handlers/sessions.go` +Issue: 3,495 lines, violates Constitution Principle V + +## Desired State +Break into modules: +- sessions/lifecycle.go (create, delete) +- sessions/status.go (status updates) +- sessions/jobs.go (job management) +- sessions/validation.go (input validation) + +## Constraints +- Maintain backward compatibility +- All existing tests must pass +- Follow CLAUDE.md standards + +## Priority +P0 - Critical +``` + +### Step 2: Amber Creates Detailed PR + +- Analyzes current structure +- Creates modular file structure +- Updates imports across codebase +- Ensures all tests pass +- Creates PR with before/after comparison + +### Step 3: Review & Merge + +```bash +# Review the refactoring +gh pr view 124 --web + +# Check CI status +gh pr checks 124 + +# Merge when ready +gh pr merge 124 --squash +``` + +--- + +## Example: Add Missing Tests + +### Step 1: Create Issue + +**Title**: `[Amber Tests] Add contract tests for sessions API` + +**Label**: `amber:test-coverage` + +**Body**: +```markdown +## Untested Code +File: `components/backend/handlers/sessions.go` +Functions: +- CreateSession (line 123) +- UpdateSessionStatus (line 456) + +## Test Type +Contract Tests (API endpoints) + +## Test Scenarios +- Happy path: create session with valid spec +- Error: missing API key +- Error: invalid namespace +- Edge case: very long prompt (>10K chars) + +## Target Coverage +60% +``` + +### Step 2: Amber Generates Tests + +- Creates `handlers/sessions_test.go` +- Writes table-driven tests (Go convention) +- Covers happy paths and error cases +- Ensures all tests pass + +### Step 3: Verify Coverage + +```bash +# Check test coverage +cd components/backend +go test -coverprofile=coverage.out ./handlers +go tool cover -func=coverage.out | grep sessions.go + +# Should show ~60% coverage +``` + +--- + +## Monitoring Amber + +### View All Amber PRs + +```bash +gh pr list --label amber-generated +``` + +### View Workflow Runs + +```bash +gh run list --workflow=amber-issue-handler.yml +``` + +### Check Specific Run + +```bash +# Get run ID from issue comment or Actions tab +gh run view 123456789 --log +``` + +--- + +## Troubleshooting + +### Amber Didn't Trigger + +**Check**: +1. Label is exact: `amber:auto-fix` (not `amber auto-fix`) +2. Secret `ANTHROPIC_API_KEY` is set +3. Workflow permissions enabled (Settings โ†’ Actions) + +**Debug**: +```bash +gh run list --workflow=amber-issue-handler.yml --limit 5 +``` + +### PR Tests Failed + +**Action**: Review PR, add feedback comment, Amber can update PR + +### Amber Commented "Error" + +**Action**: Read error message, update issue with more context, re-trigger + +--- + +## Configuration + +### Adjust Amber's Behavior + +Edit `.claude/amber-config.yml`: + +```yaml +# Change risk thresholds +automation_policies: + auto_fix: + max_files_per_pr: 10 # Change to 20 for larger auto-fixes + +# Add new patterns + categories: + - name: "Your Custom Pattern" + patterns: ["custom pattern"] +``` + +### Disable Amber Temporarily + +```bash +# Disable workflow +gh workflow disable amber-issue-handler.yml + +# Re-enable +gh workflow enable amber-issue-handler.yml +``` + +--- + +## Best Practices + +### โœ… Do + +- Use specific file paths when possible +- Provide clear success criteria +- Start with small, low-risk tasks (auto-fix) +- Review all PRs before merging + +### โŒ Don't + +- Request breaking changes (Amber will reject) +- Provide vague instructions ("make it better") +- Skip PR review (always review before merge) +- Hardcode secrets (Amber will refuse) + +--- + +## Next Steps + +1. **Try auto-fix first**: Create issue with `amber:auto-fix` label +2. **Review generated PR**: Understand Amber's approach +3. **Graduate to refactoring**: Try `amber:refactor` for tech debt +4. **Add tests**: Use `amber:test-coverage` to improve coverage +5. **Monitor metrics**: Track PR merge rate, time-to-merge + +--- + +## Full Documentation + +- [Complete Guide](amber-automation.md) - Detailed documentation +- [Amber Config](.claude/amber-config.yml) - Automation policies +- [Project Standards](../CLAUDE.md) - Conventions Amber follows + +--- + +## Support + +**Questions?** Create issue with label `amber:help` + +**Feature Requests?** Title issue `[Amber Feature Request] ...` + +**Bugs?** Title issue `[Amber Bug] ...` with workflow run link + +--- + +**You're ready to use Amber!** Create your first issue and watch the automation magic happen. ๐Ÿค– diff --git a/docs/diagrams/amber-workflow.md b/docs/diagrams/amber-workflow.md new file mode 100644 index 000000000..2befe90cb --- /dev/null +++ b/docs/diagrams/amber-workflow.md @@ -0,0 +1,323 @@ +# Amber Issue-to-PR Workflow Diagrams + +## High-Level Flow + +```mermaid +graph TB + A[Developer Creates Issue] --> B{Uses Template?} + B -->|Yes| C[Template Auto-Labels] + B -->|No| D[Manually Add Label] + C --> E[GitHub Actions Triggered] + D --> E + E --> F[Amber Agent Executes] + F --> G{Changes Made?} + G -->|Yes| H[Create Feature Branch] + G -->|No| I[Comment: No Changes Needed] + H --> J[Run Linters & Tests] + J --> K{All Pass?} + K -->|Yes| L[Commit Changes] + K -->|No| M[Comment: Errors Found] + L --> N[Push Branch] + N --> O[Create Pull Request] + O --> P[Link PR to Issue] + P --> Q[Team Review] + Q --> R{Approved?} + R -->|Yes| S[Merge PR] + R -->|No| T[Request Changes] + S --> U[Auto-Close Issue] +``` + +## Detailed Workflow Steps + +```mermaid +sequenceDiagram + participant Dev as Developer + participant GH as GitHub + participant GHA as GitHub Actions + participant Amber as Amber Agent + participant CI as CI/CD + + Dev->>GH: Create issue with label + GH->>GHA: Trigger workflow (on: issues.labeled) + GHA->>GHA: Extract issue details + Note over GHA: Parse title, body, files + GHA->>Amber: Execute with prompt + Note over Amber: Analyze codebase + Amber->>Amber: Apply fixes/refactoring + Amber->>GHA: Return changes + GHA->>GHA: Run linters (gofmt, black, etc.) + alt Linters Pass + GHA->>GHA: Run tests + alt Tests Pass + GHA->>GH: Create feature branch + GHA->>GH: Commit changes + GHA->>GH: Push branch + GHA->>GH: Create pull request + GH->>Dev: Notify: PR created + Dev->>GH: Review PR + GH->>CI: Run CI checks + CI->>GH: Report results + Dev->>GH: Approve & merge + GH->>GH: Auto-close issue + else Tests Fail + GHA->>GH: Comment: Test failures + end + else Linters Fail + GHA->>GH: Comment: Linting errors + end +``` + +## Risk-Based Decision Tree + +```mermaid +graph TD + A[Amber Analyzes Issue] --> B{Risk Level?} + B -->|Low Risk| C[Auto-Fix Category] + B -->|Medium Risk| D[Proposal Category] + B -->|High Risk| E[Report-Only Category] + + C --> C1{Changes Type} + C1 -->|Formatting| C2[Run formatters: gofmt, black] + C1 -->|Linting| C3[Run linters: golangci-lint] + C1 -->|Imports| C4[Remove unused imports] + C2 --> C5[Create PR] + C3 --> C5 + C4 --> C5 + C5 --> C6[Require Review] + C6 --> C7{Review Pass?} + C7 -->|Yes| C8[Merge PR] + C7 -->|No| C9[Close PR] + + D --> D1{Proposal Type} + D1 -->|Refactoring| D2[Break files, extract patterns] + D1 -->|Tests| D3[Add unit/contract tests] + D1 -->|Error Handling| D4[Improve error handling] + D2 --> D5[Create detailed PR] + D3 --> D5 + D4 --> D5 + D5 --> D6[Require Approval] + D6 --> D7{Approved?} + D7 -->|Yes| D8[Merge PR] + D7 -->|No| D9[Close PR] + + E --> E1{Report Type} + E1 -->|Security| E2[Create security issue] + E1 -->|Breaking Change| E3[Create RFC] + E1 -->|Architecture| E4[Schedule review] + E2 --> E5[Notify security team] + E3 --> E5 + E4 --> E5 + E5 --> E6[Manual Decision Required] +``` + +## Label-Triggered Workflows + +```mermaid +graph LR + A[Issue Created] --> B{Label Applied} + B -->|amber:auto-fix| C[Auto-Fix Workflow] + B -->|amber:refactor| D[Refactor Workflow] + B -->|amber:test-coverage| E[Test Coverage Workflow] + B -->|Other labels| F[No Action] + + C --> C1[Parse issue for files] + C1 --> C2[Run formatters/linters] + C2 --> C3[Create PR with fixes] + + D --> D1[Parse current/desired state] + D1 --> D2[Analyze code structure] + D2 --> D3[Implement refactoring] + D3 --> D4[Update tests] + D4 --> D5[Create PR with changes] + + E --> E1[Parse untested code] + E1 --> E2[Identify test scenarios] + E2 --> E3[Generate tests] + E3 --> E4[Verify tests pass] + E4 --> E5[Create PR with tests] +``` + +## Comment-Triggered Workflow + +```mermaid +graph TD + A[Developer Comments on Issue] --> B{Contains /amber execute?} + B -->|Yes| C[Extract Proposal from Issue Body] + B -->|No| D[No Action] + C --> E[Verify Approval in Issue] + E --> F{Approved?} + F -->|Yes| G[Execute Proposal] + F -->|No| H[Comment: Requires Approval] + G --> I[Apply Changes] + I --> J[Create PR] + J --> K[Link to Issue] +``` + +## Error Handling Flow + +```mermaid +graph TD + A[Amber Executes] --> B{Changes Applied?} + B -->|No| C[No files matched pattern] + C --> D[Comment: No changes needed] + + B -->|Yes| E{Linters Pass?} + E -->|No| F[Linting errors found] + F --> G[Comment: Linting failed] + G --> H[Attach error logs] + + E -->|Yes| I{Tests Pass?} + I -->|No| J[Test failures found] + J --> K[Comment: Tests failed] + K --> L[Attach test output] + + I -->|Yes| M{Create Branch?} + M -->|Error| N[Git operation failed] + N --> O[Comment: Branch creation error] + + M -->|Success| P{Push Branch?} + P -->|Error| Q[Push failed] + Q --> R[Comment: Push error] + + P -->|Success| S{Create PR?} + S -->|Error| T[PR creation failed] + T --> U[Comment: PR creation error] + + S -->|Success| V[Success!] + V --> W[Comment: PR created] +``` + +## Multi-File Refactoring Example + +```mermaid +graph LR + A[sessions.go
3495 lines] --> B[Amber Analyzes] + B --> C{Extract Modules} + + C --> D[lifecycle.go
CreateSession
DeleteSession] + C --> E[status.go
UpdateStatus
GetStatus] + C --> F[jobs.go
CreateJob
MonitorJob] + C --> G[validation.go
ValidateSpec
SanitizeInput] + + D --> H[Update imports] + E --> H + F --> H + G --> H + + H --> I[Run tests] + I --> J{All Pass?} + J -->|Yes| K[Create PR] + J -->|No| L[Rollback changes] +``` + +## Constitution Compliance Check + +```mermaid +graph TD + A[Amber Reviews Changes] --> B{Constitution Check} + + B --> C[Principle I: Kubernetes-Native] + C --> D{Uses CRDs/Operators?} + D -->|Yes| E1[โœ“ Pass] + D -->|No| E2[โœ— Fail: Report issue] + + B --> F[Principle II: Security-First] + F --> G{User-scoped auth?} + G -->|Yes| H1[โœ“ Pass] + G -->|No| H2[โœ— Fail: Add RBAC checks] + + B --> I[Principle III: Type Safety] + I --> J{No context.TODO?} + J -->|Yes| K1[โœ“ Pass] + J -->|No| K2[โœ— Fail: Fix context usage] + + B --> L[Principle IV: Testing] + L --> M{Tests exist?} + M -->|Yes| N1[โœ“ Pass] + M -->|No| N2[โœ— Fail: Add tests] + + B --> O[Principle V: Modularity] + O --> P{Files < 400 lines?} + P -->|Yes| Q1[โœ“ Pass] + P -->|No| Q2[โœ— Fail: Refactor required] + + E1 --> R[All Checks Complete] + H1 --> R + K1 --> R + N1 --> R + Q1 --> R + R --> S{All Pass?} + S -->|Yes| T[Create PR] + S -->|No| U[Create proposal issue] +``` + +## Monitoring Dashboard (Conceptual) + +```mermaid +graph TB + subgraph Metrics + A[PR Merge Rate
90%+] + B[Avg Time to Merge
< 2 hours] + C[Developer Time Saved
10 hours/week] + D[Issue Resolution
95%] + end + + subgraph Activity + E[Auto-Fix PRs
30/month] + F[Refactoring PRs
15/month] + G[Test PRs
5/month] + end + + subgraph Health + H[Success Rate
85%] + I[Error Rate
10%] + J[Skipped
5%] + end + + Metrics --> K[Overall Health: Excellent] + Activity --> K + Health --> K +``` + +## Integration Points + +```mermaid +graph LR + A[Amber Core] --> B[GitHub API] + A --> C[Anthropic API] + A --> D[Git Operations] + A --> E[Testing Frameworks] + A --> F[Linting Tools] + + B --> B1[Issues] + B --> B2[Pull Requests] + B --> B3[Comments] + B --> B4[Labels] + + C --> C1[Claude Sonnet 4.5] + C --> C2[Extended Thinking] + + D --> D1[Clone] + D --> D2[Branch] + D --> D3[Commit] + D --> D4[Push] + + E --> E1[Go: go test] + E --> E2[Python: pytest] + E --> E3[TypeScript: jest] + + F --> F1[Go: gofmt, golangci-lint] + F --> F2[Python: black, isort, flake8] + F --> F3[TypeScript: eslint, prettier] +``` + +--- + +## Legend + +- **Rectangle**: Process/Action +- **Diamond**: Decision Point +- **Oval**: Start/End State +- **Parallelogram**: Input/Output +- **Solid Arrow**: Sequential Flow +- **Dashed Arrow**: Conditional Flow diff --git a/scripts/git-hooks/README.md b/scripts/git-hooks/README.md new file mode 100644 index 000000000..b8ab75b00 --- /dev/null +++ b/scripts/git-hooks/README.md @@ -0,0 +1,280 @@ +# Git Hooks for Branch Protection + +This directory contains git hooks that enforce the feature branch workflow to prevent accidental commits and pushes to protected branches. + +## What's Included + +### `pre-commit` + +Runs before every `git commit` and blocks commits to protected branches: + +- `main` +- `master` +- `production` + +**Error message example:** + +``` +โš ๏ธ Attempting to commit directly to 'main' +โŒ Direct commits to 'main' are not allowed. + +๐Ÿ’ก Create a feature branch instead: + git checkout -b feature/your-feature-name + git checkout -b fix/bug-description + git checkout -b issue-123-description + +๐Ÿ”ง Or force commit (not recommended): + git commit --no-verify -m 'your message' +``` + +### `pre-push` + +Runs before every `git push` and blocks pushes to protected branches: + +- Blocks if you're currently on a protected branch +- Blocks if you're pushing to a protected remote branch + +**Error message example:** + +``` +โš ๏ธ Attempting to push directly to 'main' +โŒ Direct pushes to 'main' are not allowed. + +๐Ÿ’ก Use the pull request workflow instead: + 1. Create a feature branch: git checkout -b feature/your-feature + 2. Push your feature branch: git push origin feature/your-feature + 3. Open a pull request on GitHub + +๐Ÿ”ง Or force push (not recommended): + git push --no-verify +``` + +## Installation + +### Automatic Installation (Recommended) + +Hooks are automatically installed when you run: + +```bash +make dev-start +``` + +### Manual Installation + +If you need to install hooks manually: + +```bash +./scripts/install-git-hooks.sh +``` + +Or via Makefile: + +```bash +make setup-hooks +``` + +### Verify Installation + +Check that symlinks exist in `.git/hooks/`: + +```bash +ls -la .git/hooks/ | grep -E 'pre-commit|pre-push' +``` + +You should see symlinks pointing to `../../scripts/git-hooks/pre-commit` and `pre-push`. + +## Usage + +### Normal Workflow (Hooks Active) + +```bash +# Create a feature branch +git checkout -b feature/my-feature + +# Make changes and commit (hook allows this) +git add . +git commit -m "feat: add new feature" + +# Push to feature branch (hook allows this) +git push origin feature/my-feature + +# Try to commit to main (hook blocks this) +git checkout main +git commit -m "oops" # โŒ Blocked by pre-commit hook +``` + +### Override When Necessary + +In rare cases where you need to commit/push to a protected branch (e.g., hotfix, CI automation): + +```bash +# Override pre-commit hook +git commit --no-verify -m "hotfix: critical security patch" + +# Override pre-push hook +git push --no-verify origin main +``` + +**โš ๏ธ Use `--no-verify` sparingly!** It bypasses all safety checks. + +## Uninstallation + +To remove the git hooks: + +```bash +make remove-hooks +``` + +Or manually: + +```bash +rm .git/hooks/pre-commit +rm .git/hooks/pre-push +``` + +Backed-up hooks (if any existed before installation) are saved as `.git/hooks/pre-commit.backup`. + +## How It Works + +### Symlinks + +The installation script creates symlinks from `.git/hooks/` to `scripts/git-hooks/`: + +``` +.git/hooks/pre-commit โ†’ ../../scripts/git-hooks/pre-commit +.git/hooks/pre-push โ†’ ../../scripts/git-hooks/pre-push +``` + +**Benefits:** + +- Changes to hook scripts automatically apply (no reinstall needed) +- Hooks are tracked in git (in `scripts/git-hooks/`) +- Easy to update and maintain + +### Hook Execution Flow + +**Pre-commit:** + +1. Git runs `.git/hooks/pre-commit` before creating commit +2. Hook checks current branch with `git rev-parse --abbrev-ref HEAD` +3. If branch is protected โ†’ exit code 1 (block commit) +4. If branch is allowed โ†’ exit code 0 (proceed) + +**Pre-push:** + +1. Git runs `.git/hooks/pre-push` before pushing +2. Hook receives push targets via stdin (local ref, remote ref) +3. Checks both current branch and target branch +4. If either is protected โ†’ exit code 1 (block push) +5. If both are allowed โ†’ exit code 0 (proceed) + +## Customization + +### Add More Protected Branches + +Edit the `PROTECTED_BRANCHES` list in both hook files: + +```python +PROTECTED_BRANCHES: List[str] = ["main", "master", "production", "release"] +``` + +### Change Suggested Branch Prefixes + +Edit the `SUGGESTED_PREFIXES` list in `pre-commit`: + +```python +SUGGESTED_PREFIXES: List[str] = [ + "feature/", + "fix/", + "docs/", + "refactor/", + "test/", + "issue-", + "jira-", # Add your custom prefixes +] +``` + +### Disable Hooks Temporarily + +Instead of uninstalling, you can temporarily disable: + +```bash +# Disable pre-commit +mv .git/hooks/pre-commit .git/hooks/pre-commit.disabled + +# Re-enable +mv .git/hooks/pre-commit.disabled .git/hooks/pre-commit +``` + +Or use `--no-verify` for individual operations. + +## Troubleshooting + +### Hook Not Running + +**Check if hook is executable:** + +```bash +ls -l .git/hooks/pre-commit +# Should show: lrwxr-xr-x (symlink with execute permissions) +``` + +**Verify symlink target:** + +```bash +readlink .git/hooks/pre-commit +# Should show: ../../scripts/git-hooks/pre-commit +``` + +**Reinstall hooks:** + +```bash +make remove-hooks +make setup-hooks +``` + +### Python Not Found + +Hooks require Python 3.11+ (project standard). Verify: + +```bash +python3 --version +``` + +If Python is not in your PATH, update the shebang in hook files: + +```python +#!/usr/bin/env python3.11 # Specific version +``` + +### Hook Fails with Error + +Run the hook manually to see detailed errors: + +```bash +python3 scripts/git-hooks/pre-commit +python3 scripts/git-hooks/pre-push < /dev/null +``` + +### Backed-Up Hook Lost + +If the installer backed up your previous hook, restore it: + +```bash +mv .git/hooks/pre-commit.backup .git/hooks/pre-commit +``` + +## Contributing + +When modifying hooks: + +1. Test thoroughly on both protected and non-protected branches +2. Ensure error messages are clear and actionable +3. Follow project Python standards (black, isort, type hints) +4. Update this README if behavior changes + +## References + +- [Git Hooks Documentation](https://git-scm.com/docs/githooks) +- [CONTRIBUTING.md](../../CONTRIBUTING.md) - Project contribution guide +- [Makefile](../../Makefile) - Development commands diff --git a/scripts/git-hooks/pre-commit b/scripts/git-hooks/pre-commit new file mode 100755 index 000000000..d1f131ba9 --- /dev/null +++ b/scripts/git-hooks/pre-commit @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +""" +Git pre-commit hook to enforce feature branch workflow. + +Prevents commits to protected branches (main, master, production). +Developers can override with --no-verify if absolutely necessary. +""" + +import subprocess +import sys +from typing import List + + +PROTECTED_BRANCHES: List[str] = ["main", "master", "production"] + +SUGGESTED_PREFIXES: List[str] = [ + "feature/", + "fix/", + "docs/", + "refactor/", + "test/", + "issue-", +] + + +def get_current_branch() -> str: + """Get the current git branch name.""" + try: + result = subprocess.run( + ["git", "rev-parse", "--abbrev-ref", "HEAD"], + capture_output=True, + text=True, + check=True, + ) + return result.stdout.strip() + except subprocess.CalledProcessError as e: + print(f"โŒ Failed to detect git branch: {e}") + sys.exit(1) + + +def suggest_branch_names() -> str: + """Generate helpful branch name suggestions.""" + suggestions = [ + "๐Ÿ’ก Create a feature branch instead:", + " git checkout -b feature/your-feature-name", + " git checkout -b fix/bug-description", + " git checkout -b issue-123-description", + "", + "๐Ÿ”ง Or force commit (not recommended):", + " git commit --no-verify -m 'your message'", + ] + return "\n".join(suggestions) + + +def main() -> int: + """ + Main hook logic. + + Returns: + 0 if commit should proceed + 1 if commit should be blocked + """ + current_branch = get_current_branch() + + if current_branch in PROTECTED_BRANCHES: + print(f"\nโš ๏ธ Attempting to commit directly to '{current_branch}'") + print(f"โŒ Direct commits to '{current_branch}' are not allowed.\n") + print(suggest_branch_names()) + return 1 + + # Allow commit + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/git-hooks/pre-push b/scripts/git-hooks/pre-push new file mode 100755 index 000000000..6eb4a55dc --- /dev/null +++ b/scripts/git-hooks/pre-push @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +""" +Git pre-push hook to enforce feature branch workflow. + +Prevents pushing directly to protected branches (main, master, production). +Developers can override with --no-verify if absolutely necessary. +""" + +import subprocess +import sys +from typing import List, Tuple + + +PROTECTED_BRANCHES: List[str] = ["main", "master", "production"] + + +def get_current_branch() -> str: + """Get the current git branch name.""" + try: + result = subprocess.run( + ["git", "rev-parse", "--abbrev-ref", "HEAD"], + capture_output=True, + text=True, + check=True, + ) + return result.stdout.strip() + except subprocess.CalledProcessError as e: + print(f"โŒ Failed to detect git branch: {e}") + sys.exit(1) + + +def parse_push_info() -> List[Tuple[str, str]]: + """ + Parse git push information from stdin. + + Returns list of (local_ref, remote_ref) tuples. + """ + push_info = [] + for line in sys.stdin: + parts = line.strip().split() + if len(parts) >= 2: + local_ref = parts[0] # e.g., refs/heads/main + remote_ref = parts[1] # e.g., refs/heads/main + push_info.append((local_ref, remote_ref)) + return push_info + + +def get_branch_from_ref(ref: str) -> str: + """Extract branch name from git ref.""" + if ref.startswith("refs/heads/"): + return ref.replace("refs/heads/", "") + return ref + + +def main() -> int: + """ + Main hook logic. + + Returns: + 0 if push should proceed + 1 if push should be blocked + """ + current_branch = get_current_branch() + + # Check if current branch is protected + if current_branch in PROTECTED_BRANCHES: + print(f"\nโš ๏ธ Attempting to push directly to '{current_branch}'") + print(f"โŒ Direct pushes to '{current_branch}' are not allowed.\n") + print("๐Ÿ’ก Use the pull request workflow instead:") + print(" 1. Create a feature branch: git checkout -b feature/your-feature") + print(" 2. Push your feature branch: git push origin feature/your-feature") + print(" 3. Open a pull request on GitHub\n") + print("๐Ÿ”ง Or force push (not recommended):") + print(" git push --no-verify\n") + return 1 + + # Check push targets from stdin + push_info = parse_push_info() + for local_ref, remote_ref in push_info: + remote_branch = get_branch_from_ref(remote_ref) + if remote_branch in PROTECTED_BRANCHES: + print(f"\nโš ๏ธ Attempting to push to protected branch '{remote_branch}'") + print(f"โŒ Direct pushes to '{remote_branch}' are not allowed.\n") + print("๐Ÿ’ก Use the pull request workflow instead:") + print(f" 1. Push to a feature branch: git push origin {current_branch}") + print(" 2. Open a pull request on GitHub\n") + print("๐Ÿ”ง Or force push (not recommended):") + print(" git push --no-verify\n") + return 1 + + # Allow push + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/scripts/install-git-hooks.sh b/scripts/install-git-hooks.sh new file mode 100755 index 000000000..49dcb8627 --- /dev/null +++ b/scripts/install-git-hooks.sh @@ -0,0 +1,93 @@ +#!/usr/bin/env bash +# +# Install git hooks for branch protection +# +# This script creates symlinks from .git/hooks/ to scripts/git-hooks/ +# for automated branch protection enforcement. + +set -e + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Determine repository root +REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" +if [ -z "$REPO_ROOT" ]; then + echo -e "${RED}โŒ Not in a git repository${NC}" + exit 1 +fi + +HOOKS_SOURCE_DIR="$REPO_ROOT/scripts/git-hooks" +HOOKS_TARGET_DIR="$REPO_ROOT/.git/hooks" + +# Ensure source directory exists +if [ ! -d "$HOOKS_SOURCE_DIR" ]; then + echo -e "${RED}โŒ Hooks source directory not found: $HOOKS_SOURCE_DIR${NC}" + exit 1 +fi + +# Ensure target directory exists +mkdir -p "$HOOKS_TARGET_DIR" + +# List of hooks to install +HOOKS=("pre-commit" "pre-push") + +echo "๐Ÿ”ง Installing git hooks for branch protection..." +echo "" + +installed_count=0 +skipped_count=0 + +for hook in "${HOOKS[@]}"; do + source_path="$HOOKS_SOURCE_DIR/$hook" + target_path="$HOOKS_TARGET_DIR/$hook" + + # Check if source exists + if [ ! -f "$source_path" ]; then + echo -e "${YELLOW}โš ๏ธ Source hook not found: $source_path (skipping)${NC}" + continue + fi + + # Check if target already exists + if [ -e "$target_path" ]; then + # Check if it's already a symlink to our hook + if [ -L "$target_path" ] && [ "$(readlink "$target_path")" = "$source_path" ]; then + echo -e "${GREEN}โœ“${NC} $hook already installed (symlink exists)" + skipped_count=$((skipped_count + 1)) + continue + else + echo -e "${YELLOW}โš ๏ธ $hook already exists (backing up to ${hook}.backup)${NC}" + mv "$target_path" "${target_path}.backup" + fi + fi + + # Create symlink + ln -s "$source_path" "$target_path" + echo -e "${GREEN}โœ“${NC} Installed $hook" + installed_count=$((installed_count + 1)) +done + +echo "" +echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" +if [ $installed_count -gt 0 ]; then + echo -e "${GREEN}โœ… Successfully installed $installed_count hook(s)${NC}" +fi +if [ $skipped_count -gt 0 ]; then + echo -e "${GREEN}โœ“${NC} $skipped_count hook(s) already installed" +fi +echo "โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”" +echo "" +echo "๐Ÿ“‹ Installed hooks:" +echo " โ€ข pre-commit - Prevents commits to main/master/production" +echo " โ€ข pre-push - Prevents pushes to main/master/production" +echo "" +echo "๐Ÿ’ก To override a hook when needed:" +echo " git commit --no-verify" +echo " git push --no-verify" +echo "" +echo "๐Ÿ—‘๏ธ To uninstall hooks:" +echo " make remove-hooks" +echo ""