Files
harbor-ci-cd-demo/.gitea/workflows/ci-cd.yml
stephenminakian 86eba16061
All checks were successful
CI/CD Pipeline - Build, Test, and Deploy / 🏗️ Build & Push Image (push) Successful in 13s
CI/CD Pipeline - Build, Test, and Deploy / 🧹 Cleanup (push) Successful in 1s
Debug sbom upload
2025-07-03 09:17:46 -06:00

256 lines
8.2 KiB
YAML

name: CI/CD Pipeline - Build, Test, and Deploy
on:
push:
branches: [main, master, develop]
pull_request:
branches: [main, master]
workflow_dispatch:
env:
NODE_VERSION: '18'
REGISTRY: ${{ secrets.HARBOR_REGISTRY }}
IMAGE_NAME: infrastructure/monitoring-dashboard
jobs:
# Job 1: Lint and Test
# test:
# name: 🧪 Test & Lint
# runs-on: ubuntu-latest
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Setup Node.js
# uses: actions/setup-node@v4
# with:
# node-version: ${{ env.NODE_VERSION }}
# cache: 'npm'
# - name: Install dependencies
# run: npm ci
# - name: Run linting
# run: npm run lint
# - name: Run tests
# run: npm run test:coverage
# - name: Upload test results
# uses: actions/upload-artifact@v3
# if: always()
# with:
# name: test-results
# path: |
# coverage/
# test-results.xml
# # Job 2: Security Scan
# security:
# name: 🔒 Security Scan
# runs-on: ubuntu-latest
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Setup Node.js
# uses: actions/setup-node@v4
# with:
# node-version: ${{ env.NODE_VERSION }}
# cache: 'npm'
# - name: Install dependencies
# run: npm ci
# - name: Run security audit
# run: npm audit --audit-level=high
# - name: Check for vulnerabilities
# run: |
# if npm audit --audit-level=moderate --json | jq '.vulnerabilities | length' | grep -v '^0$'; then
# echo "Vulnerabilities found!"
# npm audit --audit-level=moderate
# exit 1
# fi
# Job 3: Build and Push Docker Image
build:
name: 🏗️ Build & Push Image
runs-on: ubuntu-latest
# needs: [test, security]
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
# outputs:
# image-tag: ${{ steps.meta.outputs.tags }}
# image-digest: ${{ steps.build.outputs.digest }}
steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Set up Docker Buildx
# uses: docker/setup-buildx-action@v3
# - name: Login to Harbor Registry
# uses: docker/login-action@v3
# with:
# registry: ${{ env.REGISTRY }}
# username: ${{ secrets.HARBOR_USERNAME }}
# password: ${{ secrets.HARBOR_TOKEN }}
# - name: Extract metadata
# id: meta
# uses: docker/metadata-action@v5
# with:
# images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
# tags: |
# type=ref,event=branch
# type=ref,event=pr
# type=sha,prefix={{branch}}-
# type=raw,value=latest,enable={{is_default_branch}}
# type=raw,value={{date 'YYYYMMDD-HHmmss'}}
# - name: Build and push Docker image
# id: build
# 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=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
# cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max
- name: Generate SBOM
run: |
# Install syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# Login to registry - use the REGISTRY variable for the URL
echo "${{ secrets.HARBOR_TOKEN }}" | docker login ${{ env.REGISTRY }} -u '${{ secrets.HARBOR_USERNAME }}' --password-stdin
# Generate SBOM using latest tag
syft ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest -o spdx-json > sbom.spdx.json
# Verify SBOM was created
if [ ! -f sbom.spdx.json ]; then
echo "Failed to generate SBOM"
exit 1
fi
echo "SBOM generated successfully"
- name: Upload SBOM to Harbor
run: |
# Install ORAS
curl -LO https://github.com/oras-project/oras/releases/download/v1.1.0/oras_1.1.0_linux_amd64.tar.gz
tar -xzf oras_1.1.0_linux_amd64.tar.gz
sudo mv oras /usr/local/bin/
# Push SBOM as an artifact to Harbor
oras push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-sbom \
--artifact-type application/spdx+json \
sbom.spdx.json:application/spdx+json
echo "SBOM uploaded successfully to Harbor"
# Job 4: Image Security Scan
# scan:
# name: 🛡️ Image Security Scan
# runs-on: ubuntu-latest
# needs: build
# if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
# steps:
# - name: Login to Harbor Registry
# uses: docker/login-action@v3
# with:
# registry: ${{ env.REGISTRY }}
# username: ${{ secrets.HARBOR_USERNAME }}
# password: ${{ secrets.HARBOR_TOKEN }}
# - name: Run Trivy vulnerability scanner
# uses: aquasecurity/trivy-action@master
# with:
# image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# format: 'sarif'
# output: 'trivy-results.sarif'
# - name: Upload Trivy scan results
# uses: actions/upload-artifact@v3
# with:
# name: trivy-scan-results
# path: trivy-results.sarif
# - name: Check for HIGH/CRITICAL vulnerabilities
# uses: aquasecurity/trivy-action@master
# with:
# image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
# format: 'json'
# output: 'trivy-results.json'
# exit-code: '1'
# severity: 'HIGH,CRITICAL'
# # Job 5: Deploy to Development
# deploy-dev:
# name: 🚀 Deploy to Development
# runs-on: ubuntu-latest
# needs: [build, scan]
# if: github.ref == 'refs/heads/develop'
# environment: development
# steps:
# - name: Deploy to development environment
# run: |
# echo "🚀 Deploying to development environment"
# echo "Image: ${{ needs.build.outputs.image-tag }}"
# echo "Digest: ${{ needs.build.outputs.image-digest }}"
# # Add actual deployment commands here
# # For example: kubectl, docker-compose, or API calls
# # Job 6: Deploy to Production
# deploy-prod:
# name: 🏭 Deploy to Production
# runs-on: ubuntu-latest
# needs: [build, scan]
# if: github.ref == 'refs/heads/main' || github.ref == 'refs/heads/master'
# environment: production
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Deploy to production
# run: |
# echo "🏭 Deploying to production environment"
# echo "Image: ${{ needs.build.outputs.image-tag }}"
# echo "Digest: ${{ needs.build.outputs.image-digest }}"
# # Example deployment script
# # In a real scenario, you might:
# # 1. SSH to your server
# # 2. Pull the new image
# # 3. Update docker-compose.yml
# # 4. Restart the service
# # 5. Run health checks
# - name: Health check after deployment
# run: |
# echo "🔍 Running post-deployment health checks"
# # Add health check commands here
# # curl -f http://your-app-url/health || exit 1
# - name: Notify deployment success
# run: |
# echo "✅ Deployment completed successfully!"
# echo "🌐 Application URL: https://your-domain.com"
# echo "📊 Monitoring: https://your-domain.com/health/detailed"
# Job 7: Cleanup
cleanup:
name: 🧹 Cleanup
runs-on: ubuntu-latest
needs: [deploy-dev, deploy-prod]
if: always()
steps:
- name: Clean up old images
run: |
echo "🧹 Cleaning up old container images"
# Add cleanup logic here
# For example, remove images older than 30 days