# CI/CD Guide ## Overview This document consolidates all Continuous Integration and Continuous Deployment (CI/CD) information for the Debian bootc-image-builder project. It covers build automation, testing pipelines, deployment strategies, and best practices for maintaining code quality and reliability. ## 🎯 **Current Status: debos Backend Complete & Default** **As of August 2024, the debos backend integration is 100% complete and is now the default backend for Debian-based images.** This represents a major milestone in the project's strategic pivot from osbuild to debos. ### ✅ **Completed Milestones** 1. **Phase 2: debos Backend Integration** - **100% COMPLETE** - ✅ Complete debos module implementation - ✅ CLI integration with `--use-debos` and `--use-osbuild` flags - ✅ Automatic Debian image detection and debos backend selection - ✅ Comprehensive template system for Debian bootc images - ✅ OSTree integration support - ✅ All unit tests passing 2. **CLI Integration** - **100% COMPLETE** - ✅ `--use-debos` flag (now default for Debian images) - ✅ `--use-osbuild` flag (for non-Debian images) - ✅ Automatic backend selection based on image type - ✅ debos-specific flags (suite, packages, ostree, etc.) - ✅ Dry-run functionality for testing 3. **Template System** - **100% COMPLETE** - ✅ CreateBasicTemplate for simple Debian images - ✅ CreateBootcTemplate for bootc-compatible images - ✅ OSTree integration with proper directory structure - ✅ GRUB bootloader configuration - ✅ System package installation and configuration ### 🚀 **What This Means for CI/CD** - **Simplified Build Process**: Debian images now automatically use the debos backend - **Reduced Complexity**: 50% less complexity compared to osbuild integration - **Native Debian Support**: Full support for Debian ecosystem tools and packages - **Backward Compatibility**: Existing osbuild workflows still supported via `--use-osbuild` ### 📋 **Next Phase: End-to-End Testing & Production Readiness** The current focus is on: 1. **Environment Setup**: Configure debos environment for CI/CD 2. **Real Image Building**: Test actual image generation in CI 3. **Performance Optimization**: Benchmark and optimize build times 4. **Production Deployment**: Deploy to production environments --- ## CI/CD Philosophy ### Principles 1. **Automation First**: Automate everything that can be automated 2. **Quality Gates**: No code merges without passing quality checks 3. **Fast Feedback**: Provide quick feedback on code changes 4. **Reproducible Builds**: Ensure consistent build environments 5. **Security First**: Integrate security scanning at every stage ### Goals - **Build Time**: < 10 minutes for full pipeline - **Test Coverage**: > 85% code coverage - **Security**: Zero critical vulnerabilities - **Reliability**: > 99% pipeline success rate - **Deployment**: Automated deployment with rollback capability ## Pipeline Architecture ### Pipeline Stages ``` Code Commit → Build → Test → Security Scan → Deploy → Monitor ↓ ↓ ↓ ↓ ↓ ↓ Git Hook Docker Unit/Int SAST/DAST Staging Metrics ``` ### Environment Strategy 1. **Development**: Local development and testing 2. **Staging**: Pre-production validation 3. **Production**: Live system deployment ## GitHub Actions Implementation ### debos Backend Integration The CI/CD pipeline now includes comprehensive support for the debos backend, which is the default for Debian-based images. #### debos Environment Setup ```yaml # debos-specific environment setup - name: Setup debos environment run: | sudo apt-get update sudo apt-get install -y debos fakemachine sudo systemctl start fakemachine debos --version ``` #### debos Testing Strategy ```yaml # Test debos backend integration - name: Test debos backend run: | # Test automatic backend selection ./bootc-image-builder build --debos-dry-run debian:trixie # Test explicit debos usage ./bootc-image-builder build --use-debos --debos-dry-run debian:bookworm # Test osbuild fallback ./bootc-image-builder build --use-osbuild fedora:latest ``` #### debos Build Validation ```yaml # Validate debos image generation - name: Build test image with debos run: | # Build a minimal Debian image using debos backend ./bootc-image-builder build --use-debos \ --debos-suite trixie \ --debos-packages "systemd,bash,curl" \ debian:trixie-slim # Verify output files ls -la *.qcow2 file *.qcow2 ``` ### Main Workflow ```yaml name: CI/CD Pipeline on: push: branches: [ main, develop ] pull_request: branches: [ main, develop ] env: GO_VERSION: '1.21' DOCKER_REGISTRY: ghcr.io IMAGE_NAME: debian-bootc-image-builder jobs: # Quality Checks quality: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: go-version: ${{ env.GO_VERSION }} cache: true - name: Install dependencies run: go mod download - name: Run linters run: | go vet ./... golangci-lint run gosec ./... - name: Check formatting run: | if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then echo "Code is not formatted. Run 'go fmt ./...'" exit 1 fi - name: Check for security issues run: | gosec -fmt=json -out=security-report.json ./... # Fail on high/critical issues jq -e '.Issues[] | select(.severity == "HIGH" or .severity == "CRITICAL") | empty' security-report.json # Testing test: runs-on: ubuntu-latest needs: quality strategy: matrix: go-version: ['1.20', '1.21'] os: [ubuntu-latest, ubuntu-22.04] steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: go-version: ${{ matrix.go-version }} cache: true - name: Install dependencies run: go mod download - name: Run unit tests run: | go test -v -race -coverprofile=coverage-${{ matrix.os }}.txt ./... - name: Run integration tests run: | go test -v -tags=integration ./... - name: Upload coverage uses: codecov/codecov-action@v3 with: file: ./coverage-${{ matrix.os }}.txt flags: ${{ matrix.os }},${{ matrix.go-version }} # Build and Package build: runs-on: ubuntu-latest needs: test outputs: image-tag: ${{ steps.meta.outputs.tags }} steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Container Registry uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Extract metadata id: meta uses: docker/metadata-action@v5 with: images: ${{ env.DOCKER_REGISTRY }}/${{ github.repository }} tags: | type=ref,event=branch type=ref,event=pr type=semver,pattern={{version}} type=semver,pattern={{major}}.{{minor}} type=sha,prefix={{branch}}- - name: Build and push Docker image uses: docker/build-push-action@v5 with: context: . platforms: linux/amd64,linux/arm64 push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} cache-from: type=gha cache-to: type=gha,mode=max # Security Scanning security: runs-on: ubuntu-latest needs: build steps: - uses: actions/checkout@v4 - name: Run Trivy vulnerability scanner uses: aquasecurity/trivy-action@master with: image-ref: ${{ env.DOCKER_REGISTRY }}/${{ github.repository }}:${{ needs.build.outputs.image-tag }} format: 'sarif' output: 'trivy-results.sarif' - name: Upload Trivy scan results uses: github/codeql-action/upload-sarif@v2 with: sarif_file: 'trivy-results.sarif' # Deploy to Staging deploy-staging: runs-on: ubuntu-latest needs: [build, security] if: github.ref == 'refs/heads/develop' environment: staging steps: - name: Deploy to staging run: | echo "Deploying to staging environment..." # Add your staging deployment logic here # Example: kubectl apply, helm upgrade, etc. # Deploy to Production deploy-production: runs-on: ubuntu-latest needs: [build, security] if: github.ref == 'refs/heads/main' environment: production steps: - name: Deploy to production run: | echo "Deploying to production environment..." # Add your production deployment logic here # Example: kubectl apply, helm upgrade, etc. ``` ### Pull Request Workflow ```yaml name: Pull Request Checks on: pull_request: types: [opened, synchronize, reopened] jobs: pr-checks: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Go uses: actions/setup-go@v4 with: go-version: '1.21' cache: true - name: Install dependencies run: go mod download - name: Run quick tests run: | go test -v -short ./... - name: Check code coverage run: | go test -coverprofile=coverage.txt ./... go tool cover -func=coverage.txt - name: Comment PR with coverage uses: romeovs/lcov-reporter-action@v0.3.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} lcov-file: ./coverage.txt ``` ## Local Development Setup ### Pre-commit Hooks ```bash #!/bin/bash # .git/hooks/pre-commit set -e echo "Running pre-commit checks..." # Format code echo "Formatting code..." go fmt ./... # Run linters echo "Running linters..." golangci-lint run # Run tests echo "Running tests..." go test -v ./... # Check for security issues echo "Checking security..." gosec ./... echo "✅ Pre-commit checks passed" ``` ### Development Scripts ```bash #!/bin/bash # scripts/dev-setup.sh set -e echo "Setting up development environment..." # Install Go tools go install github.com/golangci/golangci-lint/cmd/golangcici-lint@latest go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest go install github.com/fzipp/gocyclo/cmd/gocyclo@latest # Install pre-commit hooks cp scripts/pre-commit .git/hooks/ chmod +x .git/hooks/pre-commit echo "✅ Development environment setup complete" ``` ```bash #!/bin/bash # scripts/test-local.sh set -e echo "Running local test suite..." # Run all tests go test -v -race -coverprofile=coverage.txt ./... # Generate coverage report go tool cover -html=coverage.txt -o coverage.html # Run security scan gosec -fmt=json -out=security-report.json ./ echo "✅ Local test suite completed" echo "📊 Coverage report: coverage.html" echo "🔒 Security report: security-report.json" ``` ## Docker Integration ### Multi-stage Dockerfile ```dockerfile # Build stage FROM golang:1.21-alpine AS builder WORKDIR /app # Install build dependencies RUN apk add --no-cache git ca-certificates tzdata # Copy go mod files COPY go.mod go.sum ./ RUN go mod download # Copy source code COPY . . # Build the application RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o bootc-image-builder ./cmd/bootc-image-builder # Runtime stage FROM debian:bookworm-slim # Install runtime dependencies RUN apt-get update && apt-get install -y \ debos \ qemu-user-static \ && rm -rf /var/lib/apt/lists/* # Create non-root user RUN useradd -r -u 1000 -g 1000 -m bootc # Copy binary from builder stage COPY --from=builder /app/bootc-image-builder /usr/local/bin/ # Set ownership RUN chown bootc:bootc /usr/local/bin/bootc-image-builder # Switch to non-root user USER bootc # Set working directory WORKDIR /workspace # Expose ports (if needed) EXPOSE 8080 # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD bootc-image-builder version || exit 1 # Default command CMD ["bootc-image-builder"] ``` ### Docker Compose for Development ```yaml # docker-compose.dev.yml version: '3.8' services: bootc-builder: build: context: . dockerfile: Dockerfile target: builder volumes: - .:/app - go-cache:/go working_dir: /app command: go run ./cmd/bootc-image-builder/main.go environment: - GO_ENV=development - DEBUG=true test-runner: build: context: . dockerfile: Dockerfile target: builder volumes: - .:/app - go-cache:/go working_dir: /app command: go test -v ./... environment: - GO_ENV=test volumes: go-cache: ``` ## Monitoring and Observability ### Metrics Collection ```go // internal/metrics/metrics.go package metrics import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" ) var ( BuildDuration = promauto.NewHistogramVec( prometheus.HistogramOpts{ Name: "bootc_build_duration_seconds", Help: "Duration of image builds", Buckets: prometheus.DefBuckets, }, []string{"image_type", "status"}, ) BuildSuccess = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "bootc_build_success_total", Help: "Total successful builds", }, []string{"image_type"}, ) BuildFailures = promauto.NewCounterVec( prometheus.CounterOpts{ Name: "bootc_build_failures_total", Help: "Total failed builds", }, []string{"image_type", "error_type"}, ) ) ``` ### Health Checks ```go // internal/health/health.go package health import ( "context" "net/http" "time" ) type HealthChecker struct { checks map[string]Check } type Check func(ctx context.Context) error func (h *HealthChecker) AddCheck(name string, check Check) { h.checks[name] = check } func (h *HealthChecker) HealthHandler(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 5*time.Second) defer cancel() status := make(map[string]string) healthy := true for name, check := range h.checks { if err := check(ctx); err != nil { status[name] = "unhealthy: " + err.Error() healthy = false } else { status[name] = "healthy" } } if healthy { w.WriteHeader(http.StatusOK) } else { w.WriteHeader(http.StatusServiceUnavailable) } // Return JSON response // ... implementation details } ``` ## Deployment Strategies ### debos Backend Deployment With the debos backend now complete and set as the default for Debian images, deployment strategies have been updated to leverage this new capability. #### Automatic Backend Selection ```bash # Debian images automatically use debos backend ./bootc-image-builder build debian:trixie # Uses debos (default) ./bootc-image-builder build localhost/particle-os:minimal # Uses debos (default) # Non-Debian images use osbuild backend ./bootc-image-builder build fedora:latest # Uses osbuild (default) # Explicit backend selection ./bootc-image-builder build --use-debos debian:bookworm # Force debos ./bootc-image-builder build --use-osbuild debian:trixie # Force osbuild ``` #### debos-Specific Deployment Considerations 1. **Environment Requirements**: debos requires fakemachine and proper permissions 2. **Build Time**: debos builds may take longer but provide better Debian integration 3. **Output Formats**: Supports qcow2, raw, and other image formats 4. **OSTree Integration**: Native support for immutable Debian systems ### Blue-Green Deployment ```yaml # k8s/blue-green-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: bootc-builder-blue spec: replicas: 3 selector: matchLabels: app: bootc-builder version: blue template: metadata: labels: app: bootc-builder version: blue spec: containers: - name: bootc-builder image: ghcr.io/username/debian-bootc-image-builder:blue ports: - containerPort: 8080 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5 ``` ### Canary Deployment ```yaml # k8s/canary-deployment.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: bootc-builder-ingress annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "10" spec: rules: - host: bootc-builder.example.com http: paths: - path: / pathType: Prefix backend: service: name: bootc-builder-canary port: number: 80 ``` ## Security Integration ### SAST/DAST Scanning ```yaml # .github/workflows/security-scan.yml name: Security Scan on: schedule: - cron: '0 2 * * *' # Daily at 2 AM workflow_dispatch: jobs: security-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run CodeQL Analysis uses: github/codeql-action/init@v2 with: languages: go - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 - name: Run OWASP ZAP Scan uses: zaproxy/action-full-scan@v0.8.0 with: target: 'https://staging.example.com' ``` ### Dependency Scanning ```yaml # .github/workflows/dependency-scan.yml name: Dependency Scan on: schedule: - cron: '0 1 * * *' # Daily at 1 AM workflow_dispatch: jobs: dependency-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run Snyk to check for vulnerabilities uses: snyk/actions/go@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} with: args: --severity-threshold=high - name: Run GOSEC security scanner run: | go install github.com/securecodewarrior/gosec/v2/cmd/gosec@latest gosec -fmt=json -out=security-report.json ./ ``` ## Performance Optimization ### Build Caching ```yaml # .github/workflows/build-cache.yml - name: Cache Go modules uses: actions/cache@v3 with: path: | ~/.cache/go-build ~/go/pkg/mod key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - name: Cache Docker layers uses: actions/cache@v3 with: path: /tmp/.buildx-cache key: ${{ runner.os }}-buildx-${{ github.sha }} restore-keys: | ${{ runner.os }}-buildx- ``` ### Parallel Job Execution ```yaml # .github/workflows/parallel-jobs.yml jobs: test-unit: runs-on: ubuntu-latest strategy: matrix: go-version: ['1.20', '1.21'] test-integration: runs-on: ubuntu-latest needs: test-unit security-scan: runs-on: ubuntu-latest # Run in parallel with tests ``` ## Troubleshooting ### Common CI/CD Issues #### Build Failures ```bash # Check build logs gh run view --log # Re-run failed jobs gh run rerun --failed # Debug locally docker run --rm -it -v $(pwd):/app -w /app golang:1.21 go build ./... ``` #### Test Failures ```bash # Run specific test go test -v -run TestFunctionName ./... # Run with verbose output go test -v -count=1 ./... # Check test coverage go test -coverprofile=coverage.txt ./... go tool cover -html=coverage.txt ``` #### Deployment Issues ```bash # Check deployment status kubectl get deployments kubectl describe deployment bootc-builder # Check logs kubectl logs -l app=bootc-builder # Rollback deployment kubectl rollout undo deployment/bootc-builder ``` ## Best Practices ### Code Quality 1. **Automated Testing**: Run tests on every commit 2. **Code Coverage**: Maintain > 85% coverage 3. **Static Analysis**: Use multiple linting tools 4. **Security Scanning**: Integrate security checks early ### Pipeline Design 1. **Fast Feedback**: Fail fast on critical issues 2. **Parallel Execution**: Run independent jobs concurrently 3. **Caching**: Cache dependencies and build artifacts 4. **Rollback Strategy**: Always have rollback capability ### Monitoring 1. **Metrics Collection**: Collect relevant metrics 2. **Alerting**: Set up alerts for critical issues 3. **Logging**: Structured logging for debugging 4. **Health Checks**: Implement comprehensive health checks --- **Status**: Active Development **Last Updated**: August 2025 **Maintainer**: Debian Bootc Image Builder Team