forked from claude-did-this/claude-hub
* fix: merge entrypoint scripts and fix auto-tagging tool permissions - Merged duplicate claudecode-entrypoint.sh and claudecode-tagging-entrypoint.sh scripts - Added dynamic tool selection based on OPERATION_TYPE environment variable - Fixed auto-tagging permissions to include required Bash(gh:*) commands - Removed 95% code duplication between entrypoint scripts - Simplified claudeService.ts to use unified entrypoint - Auto-tagging now uses: Read,GitHub,Bash(gh issue edit:*),Bash(gh issue view:*),Bash(gh label list:*) - General operations continue to use full tool set 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: update Dockerfile to use unified entrypoint script - Remove references to deleted claudecode-tagging-entrypoint.sh - Update build process to use single unified entrypoint script * fix: remove unnecessary async from promisify mock to fix lint error * feat: add Husky pre-commit hooks with Prettier as primary formatter - Added Husky for Git pre-commit hooks - Configured eslint-config-prettier to avoid ESLint/Prettier conflicts - Prettier handles all formatting, ESLint handles code quality only - Pre-commit hooks: Prettier format, ESLint check, TypeScript check - Updated documentation with pre-commit hook setup - All code quality issues resolved * feat: consolidate workflows and fix permission issues with clean Docker runners - Replace 3 complex workflows with 2 lean ones (pull-request.yml, main.yml) - Add Docker runner configuration for clean, isolated builds - Remove file permission hacks - use ephemeral containers instead - Split workload: GitHub-hosted for tests/security, self-hosted for Docker builds - Add comprehensive pre-commit configuration for security - Update documentation to be more pragmatic - Fix credential file permissions and security audit 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: allow Husky prepare script to fail in production builds 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: update CI badge to reference new main.yml workflow 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
6.0 KiB
6.0 KiB
CI/CD Guidelines and Standards
This document defines the standards and best practices for our CI/CD pipelines. All workflows must adhere to these guidelines to ensure production-quality, maintainable, and secure automation.
Core Principles
- Security First: Never expose secrets, use least privilege, scan for vulnerabilities
- Efficiency: Minimize build times, use caching effectively, avoid redundant work
- Reliability: Proper error handling, clear failure messages, rollback capabilities
- Maintainability: DRY principles, clear naming, comprehensive documentation
- Observability: Detailed logs, status reporting, metrics collection
Workflow Standards
Naming Conventions
- Workflow files: Use kebab-case (e.g.,
deploy-production.yml) - Workflow names: Use title case (e.g.,
Deploy to Production) - Job names: Use descriptive names without redundancy (e.g.,
test, nottest-job) - Step names: Start with verb, be specific (e.g.,
Build Docker image, notBuild)
Environment Variables
env:
# Use repository variables with fallbacks
DOCKER_REGISTRY: ${{ vars.DOCKER_REGISTRY || 'docker.io' }}
APP_NAME: ${{ vars.APP_NAME || github.event.repository.name }}
# Never hardcode:
# - URLs (use vars.PRODUCTION_URL)
# - Usernames (use vars.DOCKER_USERNAME)
# - Organization names (use vars.ORG_NAME)
# - Ports (use vars.APP_PORT)
Triggers
on:
push:
branches: [main] # Production deployments
tags: ['v*.*.*'] # Semantic version releases
pull_request:
branches: [main, develop] # CI checks only, no deployments
Security
- Permissions: Always specify minimum required permissions
permissions:
contents: read
packages: write
security-events: write
- Secret Handling: Never create .env files with secrets
# BAD - Exposes secrets in logs
- run: echo "API_KEY=${{ secrets.API_KEY }}" > .env
# GOOD - Use GitHub's environment files
- run: echo "API_KEY=${{ secrets.API_KEY }}" >> $GITHUB_ENV
- Credential Scanning: All workflows must pass credential scanning
- name: Scan for credentials
run: ./scripts/security/credential-audit.sh
Error Handling
- Deployment Scripts: Always include error handling
- name: Deploy application
run: |
set -euo pipefail # Exit on error, undefined vars, pipe failures
./deploy.sh || {
echo "::error::Deployment failed"
./rollback.sh
exit 1
}
- Health Checks: Verify deployments succeeded
- name: Verify deployment
run: |
for i in {1..30}; do
if curl -f "${{ vars.APP_URL }}/health"; then
echo "Deployment successful"
exit 0
fi
sleep 10
done
echo "::error::Health check failed after 5 minutes"
exit 1
Caching Strategy
- Dependencies: Use built-in caching
- uses: actions/setup-node@v4
with:
cache: 'npm'
cache-dependency-path: package-lock.json
- Docker Builds: Use GitHub Actions cache
- uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max
Docker Builds
- Multi-platform: Only for production releases
platforms: ${{ github.event_name == 'release' && 'linux/amd64,linux/arm64' || 'linux/amd64' }}
- Tagging Strategy:
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
Deployment Strategy
- Staging: Automatic deployment from main branch
- Production: Manual approval required, only from tags
- Rollback: Automated rollback on health check failure
Job Dependencies
jobs:
test:
runs-on: ubuntu-latest
build:
needs: test
if: success() # Explicit success check
deploy:
needs: [test, build]
if: success() && github.ref == 'refs/heads/main'
Common Patterns
Conditional Docker Builds
# Only build when Docker files or source code changes
changes:
runs-on: ubuntu-latest
outputs:
docker: ${{ steps.filter.outputs.docker }}
steps:
- uses: dorny/paths-filter@v3
id: filter
with:
filters: |
docker:
- 'Dockerfile*'
- 'src/**'
- 'package*.json'
build:
needs: changes
if: needs.changes.outputs.docker == 'true'
Deployment with Notification
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy
id: deploy
run: ./deploy.sh
- name: Notify status
if: always()
uses: 8398a7/action-slack@v3
with:
status: ${{ steps.deploy.outcome }}
text: |
Deployment to ${{ github.event.deployment.environment }}
Status: ${{ steps.deploy.outcome }}
Version: ${{ github.ref_name }}
Anti-Patterns to Avoid
- No hardcoded values: Everything should be configurable
- No ignored errors: Use proper error handling, not
|| true - No unnecessary matrix builds: Only test multiple versions in CI, not deploy
- No secrets in logs: Use masks and secure handling
- No missing health checks: Always verify deployments
- No duplicate workflows: Use reusable workflows for common tasks
- No missing permissions: Always specify required permissions
Workflow Types (Simplified)
1. Pull Request (pull-request.yml)
- Fast feedback loop
- Lint, unit tests, basic security
- Docker build only if relevant files changed
2. Main Pipeline (main.yml)
- Complete testing and deployment
- Coverage reporting, security scans
- Docker builds and publishing
Checklist for New Workflows
- Uses environment variables instead of hardcoded values
- Specifies minimum required permissions
- Includes proper error handling
- Has health checks for deployments
- Uses caching effectively
- Follows naming conventions
- Includes security scanning
- Has clear documentation
- Avoids anti-patterns
- Tested in a feature branch first