# CI/CD Workflow Architecture ## πŸ—ΊοΈ Overview The dance-lessons-coach project uses a **multi-workflow architecture** for better separation of concerns, maintainability, and flexibility. ## πŸ“ Workflow Files ### 1. `ci-cd.yaml` - Main CI/CD Pipeline **Purpose**: Run tests, build binaries, and generate documentation **Triggers**: - Push to `main`, `ci/**`, `feature/**`, `fix/**`, `refactor/**` branches - Pull requests to `main` branch - Manual workflow dispatch **Jobs**: 1. **build-cache** - Build and cache Docker build environment 2. **ci-pipeline** - Run tests, build binaries, generate Swagger docs 3. **trigger-docker-push** - Trigger separate Docker workflow on main branch **Key Features**: - Runs in container environment with all build tools - Generates Swagger documentation - Runs BDD and unit tests with PostgreSQL - Updates badges and version information - Triggers Docker workflow only on main branch ### 2. `docker-push.yaml` - Docker Image Publishing **Purpose**: Build and push Docker images to registry **Triggers**: - Manual workflow dispatch only (no automatic triggers) - Triggered by `ci-cd.yaml` on main branch **Jobs**: 1. **docker-push** - Build production Docker image and push to registry **Key Features**: - Runs on host environment (access to Docker daemon) - Uses dependency hash from build-cache - Builds minimal Alpine-based production image - Pushes multiple tags (version, latest, commit SHA) ## πŸ”§ Architecture Benefits ### 1. Clear Separation of Concerns - **CI/CD Pipeline**: Testing and artifact generation - **Docker Publishing**: Image building and registry operations ### 2. Proper Environment Isolation - **CI jobs run in container**: Consistent build environment - **Docker jobs run on host**: Access to Docker daemon ### 3. Flexible Testing - Can trigger Docker workflow independently for testing - No complex conditional logic in main workflow - Easier to debug and maintain ### 4. Better Security - Docker operations isolated in separate workflow - Clear dependency between test success and deployment - Manual trigger capability for emergency situations ## πŸš€ Usage Examples ### Trigger Full CI/CD Pipeline ```bash # Automatically triggered on push to main branch # Or manually: ./scripts/gitea-client.sh trigger-workflow arcodange dance-lessons-coach ci-cd.yaml main ``` ### Trigger Docker Push Manually ```bash # Get dependency hash from build-cache job first DEPS_HASH="abc123def456" # Trigger Docker workflow manually ./scripts/gitea-client.sh trigger-workflow arcodange dance-lessons-coach docker-push.yaml main --deps_hash $DEPS_HASH ``` ### Workflow Dispatch Parameters (docker-push.yaml) - `deps_hash` (required): Dependency hash from build-cache job - `ref` (optional): Git reference (branch/tag), defaults to current ## πŸ”— Workflow Dependencies ```mermaid graph TD A[Push to main] --> B[ci-cd.yaml] B --> C[build-cache job] B --> D[ci-pipeline job] D --> E[trigger-docker-push job] E --> F[docker-push.yaml] F --> G[docker-push job] G --> H[Docker Registry] ``` ## πŸ“‹ Best Practices ### 1. Always Run CI First - Docker workflow should only be triggered after CI passes - Maintains quality gate before deployment ### 2. Use Dependency Hash - Ensures consistent builds across workflows - Pass hash from build-cache to docker-push ### 3. Manual Testing - Use separate Docker workflow for testing image builds - Avoids polluting main branch with test images ### 4. Monitor Both Workflows - CI/CD workflow for test results and artifacts - Docker workflow for image build and push status ## 🎯 Docker Build Strategy Decision ### πŸ† Chosen Approach: Attempt 2 (Standard Dockerfile) After extensive testing of multiple approaches, we selected **Attempt 2** as the optimal Docker build strategy. #### ⚑ Why Attempt 2 Won: **1. Simplicity (60% smaller workflow)** - 73 lines vs 158 lines in complex approaches - No inline Dockerfile generation - Standard `docker build -f docker/Dockerfile .` command **2. Better Performance** - No artifact/cache action overhead - Natural Docker layer caching works optimally - Faster execution without complex variable substitutions **3. Superior Reliability** - Proven standard Docker build process - Easier to debug and maintain - Fewer moving parts = fewer failures **4. Better Maintainability** - Uses standard Dockerfile (easier to understand) - No complex YAML templating - Clear separation of concerns #### πŸ—‘οΈ Why We Rejected Other Approaches: **Attempt 1 (Inline Dockerfile):** - Complex YAML templating - Harder to debug and maintain - No significant performance benefit **Attempt 3 (Build Cache Image):** - Added complexity with cache management - Slower due to artifact actions overhead - More prone to cache invalidation issues **Attempt 4 (Template File):** - Added unnecessary file management - No clear advantage over standard Dockerfile - More complex workflow ### πŸ“Š Performance Comparison: | Approach | Lines of Code | Complexity | Reliability | Maintainability | |----------|---------------|------------|-------------|-----------------| | **Attempt 2** | 73 | Low | High | Excellent | | Attempt 1 | 158 | High | Medium | Poor | | Attempt 3 | 125 | Medium | Medium | Fair | | Attempt 4 | 110 | Medium | High | Good | ### πŸ”§ Implementation Details: **Standard Dockerfile Approach:** ```yaml - name: Build and push Docker image run: | docker build -t dance-lessons-coach -f docker/Dockerfile . docker tag dance-lessons-coach "$IMAGE_NAME" docker push "$IMAGE_NAME" ``` **Key Benefits:** - Uses multi-stage builds for optimization - Standard Docker layer caching works naturally - Easy to understand and modify - Proven reliability in production ## 🎯 Future Enhancements ### Potential Improvements: - Add workflow status badges to README - Implement workflow chaining with outputs - Add matrix builds for multiple architectures - Implement canary deployment workflow - Add rollback capability ### Architecture Considerations: - Keep workflows focused on single responsibilities - Maintain clear separation between test and deploy - Document all workflow triggers and conditions - Monitor workflow execution times and optimize ## πŸ“ Maintenance ### Adding New Jobs: - Add to appropriate workflow based on responsibility - CI-related jobs β†’ `ci-cd.yaml` - Docker-related jobs β†’ `docker-push.yaml` ### Modifying Triggers: - Update trigger conditions in respective workflow files - Test changes thoroughly before merging ### Debugging: - Check workflow logs in Gitea Actions - Use `gitea-client.sh diagnose-job` for detailed analysis - Monitor workflow dependencies and execution order ## πŸ”’ Security ### Secrets Management: - Docker registry credentials stored in Gitea secrets - Never hardcode credentials in workflow files - Use GitHub token for workflow dispatch ### Access Control: - Only authorized users can trigger workflows - Manual approval required for production deployments - Audit logs available for all workflow executions This architecture provides a clean, maintainable, and secure CI/CD pipeline that scales well with project growth while maintaining clear separation of concerns.