# Nova Reusable Deploy Workflow (dev environment)
#
# This reusable workflow implements the central deployment pipeline contract:
#   pipelines/contract.yml (validated against schemas/deploy-pipeline.schema.json)
#
# The same contract is implemented by .github/workflows/deploy.yml (GitHub
# Actions, production). Both files must be byte-identical — the only
# declared difference is the forge/runtime, not the stages or commands.
#
# Consumer repos invoke this workflow via a versioned tag (floating MAJOR + MINOR):
#   uses: nova/.github/workflows/deploy.yml@v1.19
#   uses: acdl/.github/workflows/deploy.yml@v1.9  (GitHub)
#
# Unversioned references (@main, bare) are discouraged — the consumer's setup
# must be immutable + resilient. The versioned tag is the only immutability
# lever (version constraints cannot be expressed inside the contract).
#
# What this workflow does:
#   1. Checks out the consumer repo (the repo that invoked the workflow).
#   2. Checks out the ACDL platform repo into the workspace (platform/).
#      This is the run-time fetch — consumers never clone the platform repo.
#   3. Installs runtime deps: Python 3.12, Terraform 1.9.*, Checkov.
#   4. Configures AWS auth (OIDC default; static-key override via secrets).
#   5. Runs scripts/run_platform.sh against the consumer's contract path.
#   6. Uploads artifacts (emitted Terraform, Checkov JSON, confidence JSON,
#      platform log) for auditability.
#
# Inputs:
#   contract  — path to the consumer's contract YAML (default .nova/contract.yml)
#   mode      — full | plan-only | check-only (default full; dev = full apply,
#               higher environments hold for HITL — the calling repo or the
#               forge environment gate enforces that)
#
# Auth (zero-trust default — see README.md#credentials--zero-trust):
#   OIDC federation is the default. permissions: id-token: write lets the
#   forge mint a short-lived STS token. The role-to-assume is scoped by the
#   consumer's repository identity (ABAC) — the workflow assumes the role
#   that matches repo:org/consumer-repo:ref:refs/heads/main, and the session
#   policy restricts view/update to resources tagged acdl:owner=<consumer-repo>.
#
#   Override (where OIDC is unavailable, e.g. pending
#   upstream forge OIDC support): set NOVA_AWS_ACCESS_KEY_ID + NOVA_AWS_SECRET_ACCESS_KEY
#   as repository secrets. The platform-managed scheduled pipeline rotates
#   the key on a daily cadence. When .env.secrets is used locally instead,
#   rotating the key out of band is the consumer's responsibility.
name: nova-deploy

on:
  workflow_call:
    inputs:
      contract:
        description: Path to the consumer contract YAML (in the consumer repo)
        type: string
        default: .nova/contract.yml
      mode:
        description: Pipeline mode — full (apply), plan-only, check-only, or decommission
        type: string
        default: full
      changeRequestId:
        description: Change request ID (required for decommission mode — validated against CMDB)
        type: string
        default: ""
      environment:
        description: Target environment override (dev/qa/prod/dr); when empty, the contract's environment field is used
        type: string
        default: ""

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - name: Check out consumer repo
        uses: actions/checkout@v4

      - name: Check out ACDL platform repo
        uses: actions/checkout@v4
        with:
          repository: acdl/acdl
          path: platform
          ref: v1.25

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install runtime dependencies
        run: |
          pip install --break-system-packages jsonschema pyyaml boto3
          pip install --break-system-packages "checkov>=3.2,<4"

      - name: Install Terraform 1.9.*
        run: |
          wget -qO- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp.gpg
          echo "deb [signed-by=/usr/share/keyrings/hashicorp.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list
          sudo apt-get update && sudo apt-get install -y terraform=1.9.*

      - name: Configure AWS credentials (OIDC default + static-key override)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          # P4 (REQ-163): IAM role renamed acdl-deploy- → nova-deploy-.
          role-to-assume: ${{ secrets.NOVA_AWS_ACCESS_KEY_ID == '' && format('arn:aws:iam::{0}:role/nova-deploy-{1}', secrets.NOVA_AWS_ACCOUNT_ID, github.repository_id) || '' }}
          aws-region: ${{ secrets.AWS_DEFAULT_REGION || 'us-east-1' }}
          access-key-id: ${{ secrets.NOVA_AWS_ACCESS_KEY_ID }}
          secret-access-key: ${{ secrets.NOVA_AWS_SECRET_ACCESS_KEY }}

      - name: Run the platform pipeline
        working-directory: ${{ github.workspace }}
        env:
          NOVA_CONSUMER_REPO: ${{ github.repository }}
        run: |
          MODE_FLAG=""
          case "${{ inputs.mode }}" in
            full) MODE_FLAG="" ;;
            plan-only) MODE_FLAG="--plan-only" ;;
            check-only) MODE_FLAG="--check-only" ;;
            decommission)
              if [ -z "${{ inputs.changeRequestId }}" ]; then
                echo "FAIL: changeRequestId is required for decommission mode"
                exit 1
              fi
              MODE_FLAG="--decommission ${{ inputs.changeRequestId }}"
              ;;
            *) echo "Unknown mode: ${{ inputs.mode }}"; exit 1 ;;
          esac
          ENV_FLAG=""
          if [ -n "${{ inputs.environment }}" ]; then
            ENV_FLAG="--environment ${{ inputs.environment }}"
          fi
          bash platform/scripts/run_platform.sh $MODE_FLAG $ENV_FLAG "${{ inputs.contract }}"

      - name: Post stage summary comment to PR
        if: success() && github.event_name == 'pull_request'
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          GITHUB_REPOSITORY: ${{ github.repository }}
          GITHUB_REF: ${{ github.ref }}
        run: |
          bash platform/scripts/post_stage_comment.sh deploy pass '{"mode":"${{ inputs.mode }}","runId":"${{ github.run_id }}"}'

      - name: Report error to platform team (on failure)
        if: failure()
        env:
          AWS_DEFAULT_REGION: us-east-1
        run: |
          aws lambda invoke-function-url \
            --function-url "${{ secrets.NOVA_LAMBDA_URL }}" \
            --cli-binary-format raw-in-base64-out \
            --payload "$(python3 -c "import json,os; print(json.dumps({'action':'report_error','consumerRepo':os.environ.get('GITHUB_REPOSITORY',''),'contractId':'${{ github.run_id }}','error':'Deploy pipeline failed. See run logs.','runUrl':'${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}','environment':'dev'}))")" \
            /dev/null || true

      - name: Upload emitted Terraform
        uses: actions/upload-artifact@v4
        with:
          name: nova-terraform
          path: /tmp/nova_platform_run/tf/*.tf
          if-no-files-found: warn

      - name: Upload platform log
        uses: actions/upload-artifact@v4
        with:
          name: nova-platform-log
          path: platform/logs/
          if-no-files-found: warn