name: Integration Test Template

on:
  workflow_call:
    inputs:
      test:
        required: true
        type: string
      postgres_flag:
        required: false
        type: string
        default: ""
      database_name:
        required: true
        type: string

jobs:
  test:
    runs-on: ubuntu-latest
    env:
      # Github does not allow us to access secrets in pull requests,
      # so this env var is used to check if we have the secret or not.
      # If we have the secrets, meaning we are running on push in a fork,
      # there might be secrets available for more debugging.
      # If TS_OAUTH_CLIENT_ID and TS_OAUTH_SECRET is set, then the job
      # will join a debug tailscale network, set up SSH and a tmux session.
      # The SSH will be configured to use the SSH key of the Github user
      # that triggered the build.
      HAS_TAILSCALE_SECRET: ${{ secrets.TS_OAUTH_CLIENT_ID }}
    steps:
      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
        with:
          fetch-depth: 2
      - name: Tailscale
        if: ${{ env.HAS_TAILSCALE_SECRET }}
        uses: tailscale/github-action@a392da0a182bba0e9613b6243ebd69529b1878aa # v4.1.0
        with:
          oauth-client-id: ${{ secrets.TS_OAUTH_CLIENT_ID }}
          oauth-secret: ${{ secrets.TS_OAUTH_SECRET }}
          tags: tag:gh
      - name: Setup SSH server for Actor
        if: ${{ env.HAS_TAILSCALE_SECRET }}
        uses: alexellis/setup-sshd-actor@master
      - name: Download headscale image
        uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
        with:
          name: headscale-image
          path: /tmp/artifacts
      - name: Download tailscale HEAD image
        uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
        with:
          name: tailscale-head-image
          path: /tmp/artifacts
      - name: Download hi binary
        uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
        with:
          name: hi-binary
          path: /tmp/artifacts
      - name: Download Go cache
        uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
        with:
          name: go-cache
          path: /tmp/artifacts
      - name: Download postgres image
        if: ${{ inputs.postgres_flag == '--postgres=1' }}
        uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
        with:
          name: postgres-image
          path: /tmp/artifacts
      - name: Load Docker images, Go cache, and prepare binary
        run: |
          gunzip -c /tmp/artifacts/headscale-image.tar.gz | docker load
          gunzip -c /tmp/artifacts/tailscale-head-image.tar.gz | docker load
          if [ -f /tmp/artifacts/postgres-image.tar.gz ]; then
            gunzip -c /tmp/artifacts/postgres-image.tar.gz | docker load
          fi
          chmod +x /tmp/artifacts/hi
          docker images
          # Extract Go cache to host directories for bind mounting
          mkdir -p /tmp/go-cache
          tar -xzf /tmp/artifacts/go-cache.tar.gz -C /tmp/go-cache
          ls -la /tmp/go-cache/ /tmp/go-cache/.cache/
      - name: Run Integration Test
        env:
          HEADSCALE_INTEGRATION_HEADSCALE_IMAGE: headscale:${{ github.sha }}
          HEADSCALE_INTEGRATION_TAILSCALE_IMAGE: tailscale-head:${{ github.sha }}
          HEADSCALE_INTEGRATION_POSTGRES_IMAGE: ${{ inputs.postgres_flag == '--postgres=1' && format('postgres:{0}', github.sha) || '' }}
          HEADSCALE_INTEGRATION_GO_CACHE: /tmp/go-cache/go
          HEADSCALE_INTEGRATION_GO_BUILD_CACHE: /tmp/go-cache/.cache/go-build
        run: /tmp/artifacts/hi run --stats --ts-memory-limit=300 --hs-memory-limit=1500 "^${{ inputs.test }}$" \
          --timeout=120m \
          ${{ inputs.postgres_flag }}
      # Sanitize test name for artifact upload (replace invalid characters: " : < > | * ? \ / with -)
      - name: Sanitize test name for artifacts
        if: always()
        id: sanitize
        run: echo "name=${TEST_NAME//[\":<>|*?\\\/]/-}" >> $GITHUB_OUTPUT
        env:
          TEST_NAME: ${{ inputs.test }}
      - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
        if: always()
        with:
          name: ${{ inputs.database_name }}-${{ steps.sanitize.outputs.name }}-logs
          path: "control_logs/*/*.log"
      - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
        if: always()
        with:
          name: ${{ inputs.database_name }}-${{ steps.sanitize.outputs.name }}-artifacts
          path: control_logs/
      - name: Setup a blocking tmux session
        if: ${{ env.HAS_TAILSCALE_SECRET }}
        uses: alexellis/block-with-tmux-action@master
