name: "OSDC: Pre-merge"

on:
  merge_group:
    branches: [main]
  workflow_dispatch:

permissions:
  id-token: write
  contents: read
  actions: write

# Workflow-level concurrency. Serializes the ENTIRE battery (fast + slow)
# per workflow invocation against meta-staging-aws-uw1. cancel-in-progress: false
# so a later run waits for the prior run's slow jobs to finish before
# deploy/smoke/integration even start — protects test fixtures from
# interleaving.
concurrency:
  group: osdc-staging
  cancel-in-progress: false

jobs:
  # ------------------------------------------------------------------
  # Path filter: skip expensive jobs when no OSDC files changed.
  # The marker job (pre-merge-ok) still runs and reports green so the
  # merge queue's required check resolves.
  # ------------------------------------------------------------------
  changes:
    runs-on: ubuntu-latest
    timeout-minutes: 5
    outputs:
      osdc: ${{ github.event_name == 'workflow_dispatch' || steps.code.outputs.code == 'true' || steps.workflows.outputs.workflows == 'true' }}
    steps:
      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

      # predicate-quantifier is per-step. This step uses 'every' so the
      # negations act as AND-exclusions: matches osdc/** files that are NOT
      # tests. Test-only changes already run via osdc-test.yml on the PR,
      # so they shouldn't trigger the arc-staging battery.
      - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
        id: code
        with:
          predicate-quantifier: 'every'
          filters: |
            code:
              - 'osdc/**'
              # Skip staging deploy when the only osdc/ changes are tests.
              # Unit tests already run on the PR via osdc-test.yml; spinning
              # up meta-staging-aws-uw1 adds nothing for a test-only fix.
              - '!osdc/**/test_*.py'
              - '!osdc/**/*_test.py'
              - '!osdc/**/tests/**'

      # Separate step with default ('some') quantifier so these workflow
      # paths OR together independently of the code-vs-tests logic above.
      - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
        id: workflows
        with:
          filters: |
            workflows:
              - '.github/workflows/osdc-deploy-prod.yml'
              - '.github/workflows/osdc-pre-merge.yml'
              - '.github/workflows/_osdc-deploy.yml'
              - '.github/workflows/_osdc-slow-tests.yml'

  # ------------------------------------------------------------------
  # Fast set: deploy + smoke + integration. Gates the merge queue
  # via the pre-merge-ok marker job below.
  # ------------------------------------------------------------------
  deploy-fast:
    needs: changes
    if: needs.changes.outputs.osdc == 'true'
    uses: ./.github/workflows/_osdc-deploy.yml
    with:
      cluster: meta-staging-aws-uw1
      # Environment gate: the staging role trusts only tokens with
      # environment:osdc-staging in the sub, which blocks fork PRs.
      environment: osdc-staging
      taint_nodes: true
      restart_listeners: true
    # secrets: inherit is required for the reusable workflow to pick up
    # osdc-staging environment secrets (META_AWS_ACC_ID, META_AWS_DEPLOY_ROLE,
    # CANARY_GITHUB_TOKEN). Without it, secrets.* resolves to empty strings.
    secrets: inherit

  # ------------------------------------------------------------------
  # Slow set: load-test + compactor + janitor. Informational only —
  # NOT a merge queue gate. Runs after the fast set succeeds on the
  # same already-deployed staging cluster. The workflow-level
  # concurrency group ensures no other workflow touches staging
  # until these finish.
  # ------------------------------------------------------------------
  slow-tests:
    needs: [changes, deploy-fast]
    if: needs.changes.outputs.osdc == 'true' && needs.deploy-fast.result == 'success'
    uses: ./.github/workflows/_osdc-slow-tests.yml
    with:
      cluster: meta-staging-aws-uw1
      environment: osdc-staging
    secrets: inherit

  # ------------------------------------------------------------------
  # Marker job: the SOLE required status check on the merge queue.
  # Reports green when either:
  #   (a) no osdc changes (path filter excluded), OR
  #   (b) deploy-fast succeeded.
  # slow-tests result is NOT considered — they're informational.
  # if: always() is required so this job still runs (and reports) when
  # deploy-fast is skipped by the path filter; otherwise the required
  # check never reports and the merge queue times out.
  # ------------------------------------------------------------------
  pre-merge-ok:
    needs: [changes, deploy-fast]
    if: always()
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - name: Evaluate gate
        run: |
          set -euo pipefail
          changes_result="${{ needs.changes.result }}"
          deploy_result="${{ needs.deploy-fast.result }}"
          osdc="${{ needs.changes.outputs.osdc }}"

          if [[ "$changes_result" != "success" ]]; then
            echo "::error::changes job did not succeed (result: $changes_result). Cannot evaluate gate."
            exit 1
          fi

          if [[ "$osdc" == "false" ]]; then
            echo "No osdc changes — gate passes trivially."
            exit 0
          fi
          if [[ "$osdc" != "true" ]]; then
            echo "::error::unexpected osdc filter output: '$osdc' (expected 'true' or 'false'). Failing closed."
            exit 1
          fi
          if [[ "$deploy_result" == "success" ]]; then
            echo "Fast jobs passed (deploy + smoke + integration)."
            exit 0
          fi
          echo "::error::deploy-fast result was '$deploy_result' (expected 'success')."
          exit 1
