CI/CD Template Repository
September 10, 2026 Β· View on GitHub
A reusable, enterprise-grade GitHub Actions CI/CD template for .NET and Python applications. Designed for trunk-based development with full security gates, automated versioning, and release management.
π― Features
Core Capabilities
- Multi-language support: Auto-detection for .NET and Python projects
- Reusable workflows: Use
workflow_callpatternβno copy/paste needed - Security gates: SCA β SBOM β CodeQL β DAST β Production
- Automated versioning: Semantic versioning from Conventional Commits
- Container-first: Multi-platform Docker builds with layer caching
- Deployment automation: Staging + Production with health checks & rollback
- Monitoring: Periodic image scanning + continuous health monitoring
Pipeline Stages
-
CI (Continuous Integration)
- Language detection
- Build & test
- Code coverage
- SCA (Software Composition Analysis)
- SBOM generation (CycloneDX)
- Code quality (CodeQL + SonarQube)
-
Build (Docker Packaging)
- Multi-platform builds (amd64, arm64)
- Layer caching
- SBOM attachment
- Image signing
-
Deploy (Staging)
- Docker Compose deployment
- Health checks
- Smoke tests
- Log aggregation
-
DAST (Dynamic Application Security Testing)
- OWASP ZAP full scan
- Severity-based gating
- SARIF conversion
- Issue auto-creation
-
Approval (Manual Gate)
- Production approval environment
- Reviewer signoff
-
Deploy (Production)
- Pre-deployment checks
- Blue-green deployment support
- Health verification
- Rollback capability
-
Monitor (Continuous Monitoring)
- Health checks
- Compliance verification
- Synthetic tests
- SBOM traceability
-
Version (Release Automation)
- Conventional Commit analysis
- Semantic version calculation
- Version file updates
- Automated PR creation
-
Release (Tag Creation)
- Git tag creation
- Release notes generation
- GitHub Release publishing
-
Scan (Periodic Image Scanning)
- Grype vulnerability scanning
- Issue auto-triage
- SARIF upload
- Non-blocking gate
π Quick Start
For Template Repository Maintainers
-
Clone and configure:
git clone https://github.com/DEBARPAN2000/CI-CD.git cd CI-CD -
Verify workflows:
ls .github/workflows/ # Should show: ci.yml, docker-build-push.yml, dast-smoke.yml, etc. -
Customize (optional):
- Edit
.github/workflows/main-pipeline.ymlfor your defaults - Update
docker/Dockerfile.dotnetanddocker/Dockerfile.pythonfor your base images
- Edit
For Consumer Repositories
Step 1: Copy Example Workflow
Choose your stack:
For .NET projects:
# Copy .NET example to your repo
cp examples/dotnet-consumer-workflow.yml .github/workflows/ci-cd-pipeline.yml
For Python projects:
# Copy Python example to your repo
cp examples/python-consumer-workflow.yml .github/workflows/ci-cd-pipeline.yml
Step 2: Update Workflow References
Replace DEBARPAN2000 with your organization:
uses: YOUR-ORG/CI-CD/.github/workflows/ci.yml@main
Step 3: Configure Secrets
Set these at org or repo level:
Required for all repos:
GITHUB_TOKEN(built-in, auto-available)
Optional for enhanced scanning:
SONAR_HOST_URL: SonarQube server URLSONAR_TOKEN: SonarQube project token
For private registries:
REGISTRY_USERNAME: Docker registry userREGISTRY_PASSWORD: Docker registry password
Step 4: Create Deployment Configuration
Add to your repo root:
docker-compose.staging.yml:
version: '3.8'
services:
app:
image: ${IMAGE_REF:-ghcr.io/org/app:latest}
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 3
docker-compose.yml (production):
version: '3.8'
services:
app:
image: ${IMAGE_REF:-ghcr.io/org/app:latest}
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 10s
timeout: 5s
retries: 5
environment:
- ASPNETCORE_URLS=http://+:8080
Step 5: Add Branch Protection Rules
For main branch:
- β
Require status checks to pass:
CI (.NET)orCI (Python) - β Require at least 1 approval review
- β Dismiss stale PR approvals
- β Require branches to be up to date before merging
Step 6: Configure GitHub Environments
Staging environment (Settings β Environments β New environment):
- Name:
staging - Deployment branches:
main - No approval required
Production environment:
- Name:
production - Deployment branches:
main - β Require reviewers (2+ recommended)
- Reviewers: Select trusted team members
Production approval gate:
- Name:
production-approval - Deployment branches:
main - β Require reviewers
- Reviewers: Release managers
Step 7: Test Workflow
Push to main and monitor:
git push origin main
# Watch Actions tab for workflow execution
π Workflow Inputs Reference
CI Workflow (ci.yml)
- language: 'auto' | 'dotnet' | 'python' # Default: auto
- dotnet-version: '8.0.x' # .NET SDK version
- dotnet-project: '.' # Project root
- python-version: '3.12' # Python version
- python-workdir: '.' # Working directory
- python-test-command: '' # Override pytest
- lint-command: '' # Custom linter
- run-sonarqube: false # Enable SonarQube
- sonar-project-key: '' # SQ project key
Docker Build (docker-build-push.yml)
- language: 'auto' | 'dotnet' | 'python'
- registry: 'ghcr.io' # Container registry
- image-owner: '' # Defaults to github.repository_owner for GHCR, omitted otherwise
- image-name: 'my-app' # Image name (repo name if empty)
- image-tag: 'latest' # Image tag
- build-context: '.' # Docker build context
- dockerfile-path: '' # Custom Dockerfile path
- dotnet-version: '8.0' # For template Dockerfile
- python-version: '3.12' # For template Dockerfile
Deploy Staging (deploy-staging.yml)
- image-ref: '' # Optional full image reference override
- registry: 'ghcr.io' # Used when image-ref is omitted
- image-owner: '' # Defaults to github.repository_owner for GHCR, omitted otherwise
- image-name: '' # Defaults to repo name (lowercased for GHCR)
- image-tag: '' # Defaults to github.sha
- environment-name: 'staging'
- compose-file: 'docker-compose.staging.yml'
- compose-service: 'app'
- health-check-url: 'http://localhost/health'
- health-check-max-retries: '30'
- health-check-delay: '10'
DAST Scan (dast-smoke.yml)
- target-url: (required) # URL to scan
- dast-threshold: 'medium' | 'high' | 'critical'
- smoke-endpoints: '/health,/api/status' # Comma-separated
Deploy Production (deploy-production.yml)
- image-ref: '' # Optional full image reference override
- registry: 'ghcr.io' # Used when image-ref is omitted
- image-owner: '' # Defaults to github.repository_owner for GHCR, omitted otherwise
- image-name: '' # Defaults to repo name (lowercased for GHCR)
- image-tag: '' # Defaults to github.sha
- environment-name: 'production'
- compose-file: 'docker-compose.yml'
- compose-service: 'app'
- health-check-url: 'http://localhost/health'
- health-check-max-retries: '30'
- health-check-delay: '10'
For non-GHCR registries, set image-owner when the repository path includes a namespace or owner segment; leave it empty only for top-level image paths.
Version Bump (version-bump.yml)
- language: 'auto' | 'dotnet' | 'python'
- version-file-dotnet: 'Directory.Build.props'
- version-file-python: 'pyproject.toml'
- base-branch: 'main'
Release Tag (release-tag.yml)
- language: 'auto'
- version-file-dotnet: 'Directory.Build.props'
- version-file-python: 'pyproject.toml'
- release-notes-file: 'CHANGELOG.md'
Periodic Scan (image-periodic-scan.yml)
- registry: 'ghcr.io'
- image-name: (required)
- tags-to-scan: 'latest,v1.0.0' # Comma-separated
- fail-on-critical: false # Don't block release
Continuous Monitoring (continuous-monitoring.yml)
- image-ref: '' # Optional full image reference override
- registry: 'ghcr.io' # Used when image-ref is omitted
- image-owner: '' # Defaults to github.repository_owner for GHCR, omitted otherwise
- image-name: '' # Defaults to repo name (lowercased for GHCR)
- image-tag: '' # Defaults to github.sha
- monitoring-url: 'http://localhost/health'
- check-interval: '60' # seconds
- max-checks: '3'
- sbom-file: '' # Optional
π Security Considerations
Secrets Management
- Store secrets in GitHub org/repo settings
- Use environment-specific secrets for production
- Rotate credentials regularly
- Never commit
.envor credential files
DAST Configuration
- Adjust
dast-thresholdbased on risk profile - Periodic scans don't block releases (info-only)
- Critical findings auto-create GitHub issues
- Review findings in Security tab
Image Scanning
- Grype scans run on schedule (weekly recommended)
- Non-blocking to allow patch cycles
- Vulnerability trends tracked over time
Branch Protection
- Require at least 1 approval before merge
- Status checks: All CI jobs must pass
- Enforce latest main before merge
π Pipeline Flow
PR/Push to main
β
[1] CI (build, test, SBOM, CodeQL)
β
[2] Docker Build (multi-platform, cache)
β
[3] Deploy Staging (health checks)
β
[4] DAST Scan (OWASP ZAP)
β
[5] β³ Approval Gate (manual)
β
[6] Deploy Production (blue-green, rollback)
β
[7] Continuous Monitoring (health, compliance)
β
[8] Version Bump (semver from commits, auto-PR)
β
[9] Release Tag (git tag, release notes)
β
[10] Periodic Scan (scheduled, non-blocking)
π οΈ Troubleshooting
Workflow Not Triggering
- β
Ensure branch is
main - β
Check
.github/workflows/exists - β Verify workflow YAML syntax
- β Check branch protection rules
DAST Scan Failures
- β Ensure staging deployment is healthy
- β Verify health endpoint is responding
- β Check ZAP timeout settings (10-15 min typical)
- β
Lower
dast-thresholdtolowfor debugging
Docker Build Failures
- β Check Dockerfile exists or use templates
- β Verify build arguments match Dockerfile
- β Ensure registry credentials are set
- β Check image naming conventions (lowercase)
Version Bump Issues
- β Ensure main branch has version file (Directory.Build.props or pyproject.toml)
- β
Verify Conventional Commit format:
feat:,fix:,BREAKING CHANGE: - β Check git token has permissions to create PRs
Health Check Timeouts
- β
Increase
health-check-max-retries - β
Check container logs:
docker-compose logs app - β Verify health endpoint is responding within 60s
- β Check port mappings in docker-compose
π Advanced Usage
Custom SonarQube Integration
- Set org secrets:
SONAR_HOST_URL,SONAR_TOKEN - Enable in workflow:
run-sonarqube: true sonar-project-key: 'my-org/my-project' - SonarQube will scan and report code quality
Custom Linting
Override with lint-command:
lint-command: 'pylint src/ && black --check src/'
Custom Test Commands
Override with python-test-command or dotnet-test-command:
python-test-command: 'pytest tests/ --cov=src --cov-report=xml'
Private Registry
Use custom registry URL and credentials:
registry: 'docker.io' # or private registry
REGISTRY_USERNAME: ${{ secrets.DOCKER_USERNAME }}
REGISTRY_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
Scheduled Periodic Scans
Create a .github/workflows/scheduled-scan.yml:
on:
schedule:
- cron: '0 2 * * 0' # Weekly Sunday 2 AM
jobs:
scan:
uses: YOUR-ORG/CI-CD/.github/workflows/image-periodic-scan.yml@main
with:
image-name: ghcr.io/your-org/your-app:latest
π Template Maintenance
Updating the Template
Push changes to main branch. Consumer repos will automatically use latest via @main ref.
To use a specific version:
uses: DEBARPAN2000/CI-CD/.github/workflows/ci.yml@v1.0.0
Contributing Improvements
- Test locally first
- Document breaking changes
- Update examples
- Tag releases with semantic versioning
π Support
- Documentation: See
/docsfolder - Examples: See
/examplesfolder - Issues: GitHub Issues in this repo
- Contact: Reach out to the DevOps team
π License
MIT License - See LICENSE file
β Checklist for Consumer Repos
- Copy example workflow to
.github/workflows/ - Update
uses:references for your org - Create
docker-compose.staging.yml - Create
docker-compose.yml - Set GitHub secrets (SONAR_HOST_URL, SONAR_TOKEN)
- Configure GitHub environments (staging, production)
- Set branch protection rules for
main - Add health check endpoint (
GET /health) - Test workflow on feature branch
- Merge to
mainand verify full pipeline - Monitor first few releases
- Adjust thresholds and timeouts as needed