# .github/workflows/workflow.yml # # CI/CD pipeline: build Docker image -> push to ghaymah Container Registry -> # auto-deploy to staging -> manual approval gate -> deploy to production. # name: Build and Deploy to Ghaymah on: push: branches: [main, develop] pull_request: branches: [main] env: GHAYMAH_REGISTRY: registry.ghaymah.systems IMAGE_NAME: ${{ github.repository }} jobs: # --------------------------------------------------------------------- # 1) Build & push image (runs on every push to main/develop, and on PRs # for build validation only — PRs never push or deploy). # --------------------------------------------------------------------- build: name: Build & Push Image runs-on: ubuntu-latest permissions: contents: read outputs: image_tag: ${{ steps.meta.outputs.tag }} steps: - name: Checkout code uses: actions/checkout@v4 - name: Set image tag id: meta run: echo "tag=${GITHUB_SHA::12}" >> "$GITHUB_OUTPUT" - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Log in to Ghaymah Container Registry if: github.event_name == 'push' uses: docker/login-action@v3 with: registry: ${{ env.GHAYMAH_REGISTRY }} username: ${{ secrets.GHAYMAH_REGISTRY_USER }} password: ${{ secrets.GHAYMAH_REGISTRY_TOKEN }} - name: Build image uses: docker/build-push-action@v6 with: context: ./q1-deploy-monitor push: ${{ github.event_name == 'push' }} tags: | ${{ env.GHAYMAH_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.tag }} ${{ env.GHAYMAH_REGISTRY }}/${{ env.IMAGE_NAME }}:latest cache-from: type=gha cache-to: type=gha,mode=max - name: Scan image for vulnerabilities if: github.event_name == 'push' uses: aquasecurity/trivy-action@0.24.0 with: image-ref: ${{ env.GHAYMAH_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.tag }} severity: CRITICAL,HIGH exit-code: "1" # --------------------------------------------------------------------- # 2) Auto-deploy to STAGING — no approval needed, fast feedback loop. # Only runs on pushes to `develop`. # --------------------------------------------------------------------- deploy-staging: name: Deploy to Staging needs: build if: github.ref == 'refs/heads/develop' && github.event_name == 'push' runs-on: ubuntu-latest environment: name: staging url: https://myapp-staging.ghaymah.systems steps: - name: Install Ghaymah CLI run: curl -fsSL https://ghaymah.systems/cli/install.sh | sh - name: Authenticate CLI run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" - name: Deploy image to staging app run: | ghaymah deploy \ --app myapp-staging \ --image "${{ env.GHAYMAH_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build.outputs.image_tag }}" \ --plan g3.small # --------------------------------------------------------------------- # 3) Deploy to PRODUCTION — gated behind a manual approval. # GitHub Environments with required reviewers = the approval gate. # Only triggers on pushes to `main` (protected branch, PR-merge only). # --------------------------------------------------------------------- deploy-production: name: Deploy to Production (manual approval required) needs: build if: github.ref == 'refs/heads/main' && github.event_name == 'push' runs-on: ubuntu-latest environment: name: production # configure this environment in GitHub repo settings # Settings -> Environments -> production -> Required reviewers url: https://myapp.ghaymah.systems steps: - name: Install Ghaymah CLI run: curl -fsSL https://ghaymah.systems/cli/install.sh | sh - name: Authenticate CLI run: ghaymah auth login --token "${{ secrets.GHAYMAH_API_TOKEN }}" - name: Deploy image to production app run: | ghaymah deploy \ --app myapp \ --image "${{ env.GHAYMAH_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build.outputs.image_tag }}" \ --plan g5.large \ --strategy rolling - name: Post-deploy health check run: | sleep 10 curl -f https://myapp.ghaymah.systems/health || (echo "Health check failed after deploy" && exit 1)