name: crabbox

on:
  workflow_dispatch:
    inputs:
      ref:
        description: "Git ref to hydrate"
        required: false
        type: string
      crabbox_id:
        description: "Crabbox lease ID"
        required: true
        type: string
      crabbox_runner_label:
        description: "Dynamic Crabbox runner label"
        required: true
        type: string
      crabbox_job:
        description: "Hydration job identifier expected by Crabbox"
        required: false
        default: "hydrate"
        type: string
      crabbox_keep_alive_minutes:
        description: "Minutes to keep the hydrated job alive"
        required: false
        default: "90"
        type: string

permissions:
  contents: read

jobs:
  hydrate:
    runs-on: [self-hosted, "${{ inputs.crabbox_runner_label }}"]
    timeout-minutes: 120
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ inputs.ref || github.ref }}
      - uses: actions/setup-python@v5
        with:
          python-version: "3.11"
      - name: Hydrate
        run: |
          python -m pip install --upgrade pip
          python -m pip install -e ".[dev]"
          if [ -f package-lock.json ]; then npm ci; fi
          if [ -f pnpm-lock.yaml ]; then corepack enable && pnpm install --frozen-lockfile; fi
          if [ -f go.mod ]; then go mod download; fi
      - name: Mark Crabbox ready
        shell: bash
        run: |
          job="${{ inputs.crabbox_job }}"
          if [ -z "$job" ]; then job=hydrate; fi
          mkdir -p "$HOME/.crabbox/actions"
          state="$HOME/.crabbox/actions/${{ inputs.crabbox_id }}.env"
          env_file="$HOME/.crabbox/actions/${{ inputs.crabbox_id }}.env.sh"
          services_file="$HOME/.crabbox/actions/${{ inputs.crabbox_id }}.services"
          write_export() {
            key="$1"
            value="${!key-}"
            if [ -n "$value" ]; then
              printf 'export %s=%q\n' "$key" "$value"
            fi
          }
          {
            for key in CI GITHUB_ACTIONS GITHUB_WORKSPACE GITHUB_REPOSITORY GITHUB_RUN_ID GITHUB_RUN_NUMBER GITHUB_RUN_ATTEMPT GITHUB_REF GITHUB_REF_NAME GITHUB_SHA GITHUB_EVENT_NAME GITHUB_ACTOR GITHUB_JOB RUNNER_OS RUNNER_ARCH RUNNER_TEMP RUNNER_TOOL_CACHE; do
              write_export "$key"
            done
          } > "${env_file}.tmp"
          mv "${env_file}.tmp" "$env_file"
          {
            echo "# Docker containers visible from the hydrated runner"
            docker ps --format '{{.Names}}\t{{.Image}}\t{{.Ports}}' 2>/dev/null || true
          } > "${services_file}.tmp"
          mv "${services_file}.tmp" "$services_file"
          tmp="${state}.tmp"
          {
            echo "WORKSPACE=${GITHUB_WORKSPACE}"
            echo "RUN_ID=${GITHUB_RUN_ID}"
            echo "JOB=${job}"
            echo "ENV_FILE=${env_file}"
            echo "SERVICES_FILE=${services_file}"
            echo "READY_AT=$(date -u +%Y-%m-%dT%H:%M:%SZ)"
          } > "$tmp"
          mv "$tmp" "$state"
      - name: Keep Crabbox job alive
        shell: bash
        run: |
          minutes="${{ inputs.crabbox_keep_alive_minutes }}"
          case "$minutes" in
            ''|*[!0-9]*) minutes=90 ;;
          esac
          stop="$HOME/.crabbox/actions/${{ inputs.crabbox_id }}.stop"
          deadline=$(( $(date +%s) + minutes * 60 ))
          while [ "$(date +%s)" -lt "$deadline" ]; do
            if [ -f "$stop" ]; then
              exit 0
            fi
            sleep 15
          done
