# Starter CD pipeline for the tasks-app: GitHub Actions flavor, extending the Module 14 CI file.
#
# The whole idea: CD is not a new system. It is MORE STAGES on the SAME pipeline, after the checks
# pass. The lint/test gates below are the Module 14 pipeline, unchanged. Everything from the
# `build-and-publish` job down is new in this module.
#
# Where this file goes: .github/workflows/cd.yml (or fold it into your existing ci.yml). On GitLab,
# the same shape is stages in .gitlab-ci.yml with `needs:`/`rules:`; Forgejo/Gitea use Actions-
# compatible YAML. The concept (gated stages from merge to running) is identical everywhere.
#
# VERIFY BEFORE PUBLISH: action versions, the registry login/build-push action names, and the
# manual-approval mechanism all drift. Check current forge docs at build time (see README checklist).

name: CD

on:
  push:
    branches: [main]      # only a MERGE to main triggers a deploy
  pull_request:           # PRs still run the gates, but never deploy

jobs:
  # ---- The Module 14 gates: nothing ships without passing these first. ----------------------------
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - uses: actions/setup-python@v6
        with:
          python-version: "3.12"
      - run: pip install pytest ruff
      - run: ruff check .          # lint
      - run: pytest -q             # test
      # In a real pipeline a security-scan job (Module 15) would also gate here.

  # ---- Build the artifact ONCE and publish it. The unit of deploy is an immutable, SHA-tagged image.
  build-and-publish:
    needs: check                   # only runs if the gates passed
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7

      # Log in to your container registry (Module 16's images need a durable home, like a Git remote
      # is for commits). Registry/credentials are provider-specific; supply them as secrets,
      # never inline (Module 17).
      # - uses: docker/login-action@v3
      #   with:
      #     registry: ${{ vars.REGISTRY }}
      #     username: ${{ secrets.REGISTRY_USER }}
      #     password: ${{ secrets.REGISTRY_TOKEN }}

      # Build and push, tagging with the commit SHA (immutable + traceable) and :staging (moving).
      # - uses: docker/build-push-action@v6
      #   with:
      #     push: true
      #     tags: |
      #       ${{ vars.REGISTRY }}/tasks-app:${{ github.sha }}
      #       ${{ vars.REGISTRY }}/tasks-app:staging
      - run: echo "build + push tasks-app:${{ github.sha }} (wire up the registry steps above)"

  # ---- Deploy to a NON-prod environment automatically. Safe to do on every merge. ----------------
  deploy-staging:
    needs: build-and-publish
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      # The five deploy steps live in deploy.sh in this folder. On a real target this would run the
      # platform's deploy (kubectl / platform CLI / compose) against the SHA-tagged image, inject
      # runtime config + secrets (Module 17), health-check, and roll back on failure.
      - run: echo "deploy tasks-app:${{ github.sha }} to STAGING, health-check, roll back if red"

  # ---- THIS JOB IS THE DELIVERY-vs-DEPLOYMENT SWITCH. ---------------------------------------------
  #
  # As written, `environment: production` requires a human to approve before this job runs (set a
  # required reviewer on the 'production' environment in the forge). That is CONTINUOUS DELIVERY:
  # the artifact is auto-built and staged; a person clicks to ship to prod.
  #
  # Delete the `environment:` block and this becomes CONTINUOUS DEPLOYMENT: merge -> prod, no human.
  # Only remove it once you trust your review + CI + security gates (Modules 10/14/15) more than you
  # trust the click. On GitLab the equivalent switch is `when: manual` vs. automatic.
  deploy-prod:
    needs: deploy-staging
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    environment: production        # <-- required-reviewer gate = delivery. Remove = deployment.
    steps:
      - run: echo "deploy tasks-app:${{ github.sha }} to PRODUCTION (gated on human approval)"
