name: Run artisan command on liderra.ru

# Universal artisan-runner для прод-команд пока прямой SSH с dev-машины
# заблокирован YC backbone-фильтром. Заказчик пишет команду строкой в
# workflow_dispatch input, workflow проверяет её по whitelist, выполняет на
# проде под sudo -u www-data, выводит результат в job summary.
#
# Whitelist охватывает read-only / dry-run / status команды без подтверждения
# плюс несколько mutating команд с обязательным confirm_apply=true.
#
# Любая команда вне whitelist'а → fail before SSH.
#
# Использует тот же LIDERRA_SSH_KEY что и deploy.yml/ssh-diagnose.yml.

on:
  workflow_dispatch:
    inputs:
      command:
        description: 'artisan-команда (например: supplier:rekey-orphans --dry-run)'
        required: true
        type: string
      confirm_apply:
        description: 'Подтверждаю выполнение mutating-команды (обязательно true для команд без --dry-run)'
        required: false
        default: false
        type: boolean

jobs:
  run:
    name: ${{ github.event.inputs.command }}
    runs-on: ubuntu-latest
    timeout-minutes: 15

    env:
      LIDERRA_HOST: 111.88.246.137
      LIDERRA_USER: ubuntu
      CMD: ${{ github.event.inputs.command }}
      CONFIRM: ${{ github.event.inputs.confirm_apply }}

    steps:
      - name: Whitelist check
        run: |
          set -euo pipefail
          CMD_TRIM=$(echo "$CMD" | sed 's/^ *//;s/ *$//')
          echo "Requested: '$CMD_TRIM'"

          # Group 1 — read-only / dry-run / inspection: всегда разрешены
          READ_ONLY_RE='^(migrate:status|route:list|schedule:list|queue:listen --help|about|env:show|config:show|cache:table|view:cache|optimize:status|snapshot:backfill( --date=20[2-9][0-9]-[0-1][0-9]-[0-3][0-9])?|scheduler:check-heartbeats|incidents:watch-failures( --threshold-spike=[0-9]+)?( --threshold-daily=[0-9]+)?( --persistent-hours=[0-9]+)?|supplier:rekey-orphans --dry-run|audit:verify-chains|audit:rebuild-chain --partition=[a-z_0-9]+ --from-id=[0-9]+ --dry-run|deals:backfill-region-city --dry-run)( *)$'

          # Group 2 — mutating: требуют confirm_apply=true
          MUTATING_RE='^(supplier:rekey-orphans|cache:clear|view:clear|config:clear|route:clear|optimize:clear|optimize|queue:restart|partitions:create-months( --months=[0-9]+)?|partitions:drop-old|audit:rebuild-chain --partition=[a-z_0-9]+ --from-id=[0-9]+( --force)?|deals:backfill-region-city)( *)$'

          if [[ "$CMD_TRIM" =~ $READ_ONLY_RE ]]; then
            echo "::notice::Command in read-only whitelist — proceeding."
            exit 0
          fi

          if [[ "$CMD_TRIM" =~ $MUTATING_RE ]]; then
            if [[ "$CONFIRM" != "true" ]]; then
              echo "::error::Mutating command '$CMD_TRIM' requires confirm_apply=true. Re-run with confirm_apply checked."
              exit 1
            fi
            echo "::warning::Mutating command authorized via confirm_apply=true."
            exit 0
          fi

          echo "::error::Command '$CMD_TRIM' is NOT in whitelist. Allowed read-only patterns: $READ_ONLY_RE. Allowed mutating: $MUTATING_RE. Add to whitelist if needed."
          exit 1

      - name: Setup SSH key
        run: |
          mkdir -p ~/.ssh
          echo "${{ secrets.LIDERRA_SSH_KEY }}" > ~/.ssh/liderra_deploy
          chmod 600 ~/.ssh/liderra_deploy
          ssh-keyscan -H ${{ env.LIDERRA_HOST }} >> ~/.ssh/known_hosts 2>/dev/null

      - name: Run artisan on prod
        run: |
          set -o pipefail
          CMD_B64=$(printf '%s' "$CMD" | base64 -w0)
          ssh -i ~/.ssh/liderra_deploy ${{ env.LIDERRA_USER }}@${{ env.LIDERRA_HOST }} \
            "CMD_B64='$CMD_B64' bash -s" <<'REMOTE' | tee /tmp/artisan-output.log
            set +e
            CMD=$(echo "$CMD_B64" | base64 -d)
            cd /var/www/liderra/app
            echo "=== Running: php artisan $CMD on $(hostname) at $(date -u) ==="
            sudo -u www-data php artisan $CMD 2>&1
            RC=$?
            echo
            echo "=== Exit code: $RC ==="
            exit $RC
          REMOTE

      - name: Print summary
        if: always()
        run: |
          {
            echo "## artisan \`$CMD\`"
            echo
            echo "- Host: $LIDERRA_HOST"
            echo "- Confirm: $CONFIRM"
            echo "- Triggered by: ${{ github.actor }}"
            echo
            echo '```'
            cat /tmp/artisan-output.log 2>/dev/null || echo "(no output captured)"
            echo '```'
          } >> "$GITHUB_STEP_SUMMARY"

      - name: Upload output as artifact
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: artisan-output
          path: /tmp/artisan-output.log
          retention-days: 30

      - name: Cleanup SSH key
        if: always()
        run: rm -f ~/.ssh/liderra_deploy
