# Cloonar TYPO3 Staged Deployment Workflow
# 
# Staged deployment: build → deploy to stage → run E2E tests → switch release
# 
# Usage in project's .forgejo/workflows/deploy.yaml:
#   name: Deploy
#   on:
#     push:
#       branches: [main]
#   jobs:
#     deploy:
#       uses: Cloonar/ci-templates/.forgejo/workflows/typo3-staged-deploy.yaml@main
#       with:
#         stage_url: https://myproject.cloonar.dev
#         php_version: '8.3'
#       secrets:
#         stage_key: ${{ secrets.STAGE_KEY }}
#         prod_key: ${{ secrets.PROD_KEY }}

name: TYPO3 Staged Deploy

on:
  workflow_call:
    inputs:
      stage_url:
        description: 'Staging URL for E2E tests'
        required: true
        type: string
      php_version:
        description: 'PHP version'
        required: false
        type: string
        default: '8.3'
      node_version:
        description: 'Node.js version'
        required: false
        type: string
        default: '20'
      build_frontend:
        description: 'Run npm build'
        required: false
        type: boolean
        default: false
      run_e2e_tests:
        description: 'Run Playwright E2E tests'
        required: false
        type: boolean
        default: true
      e2e_path:
        description: 'Path to E2E tests'
        required: false
        type: string
        default: 'tests/e2e'
      deployer_file:
        description: 'Path to deploy.php'
        required: false
        type: string
        default: './build/deploy.php'
      deploy_production:
        description: 'Also deploy to production after stage succeeds'
        required: false
        type: boolean
        default: false
    secrets:
      stage_key:
        description: 'SSH key for staging'
        required: true
      prod_key:
        description: 'SSH key for production'
        required: false

env:
  COMPOSER_ALLOW_SUPERUSER: 1

jobs:
  # ===========================================================================
  # Build
  # ===========================================================================
  build:
    name: Build
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ inputs.php_version }}
          tools: composer

      - name: Setup Node.js
        if: ${{ inputs.build_frontend }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node_version }}
          cache: 'npm'

      - name: Install PHP dependencies
        run: composer install --prefer-dist --no-progress --no-dev --ignore-platform-reqs

      - name: Install Node dependencies & build
        if: ${{ inputs.build_frontend }}
        run: |
          npm ci
          npm run build

      - name: Create artifact
        run: |
          tar -czf build.tar.gz \
            bin public packages config vendor build composer.json composer.lock \
            $([ -d "node_modules" ] && echo "node_modules") \
            $([ -d "dist" ] && echo "dist") \
            2>/dev/null || true

      - uses: actions/upload-artifact@v4
        with:
          name: build-${{ github.sha }}
          path: build.tar.gz
          retention-days: 1

  # ===========================================================================
  # Deploy to Stage (release:create only)
  # ===========================================================================
  deploy-stage:
    name: Upload to Stage
    runs-on: ubuntu-latest
    needs: [build]

    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ inputs.php_version }}

      - uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}

      - run: tar xf build.tar.gz && rm build.tar.gz

      - run: apt-get update && apt-get install -y openssh-client rsync

      - name: Upload release
        uses: deployphp/action@v1
        with:
          deployer-binary: "./bin/dep"
          dep: --file=${{ inputs.deployer_file }} release:create stage
          private-key: ${{ secrets.stage_key }}

  # ===========================================================================
  # Switch Stage Release
  # ===========================================================================
  switch-stage:
    name: Activate Stage Release
    runs-on: ubuntu-latest
    needs: [deploy-stage]

    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ inputs.php_version }}

      - uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}

      - run: tar xf build.tar.gz && rm build.tar.gz

      - run: apt-get update && apt-get install -y openssh-client rsync

      - name: Switch release
        uses: deployphp/action@v1
        with:
          deployer-binary: "./bin/dep"
          dep: --file=${{ inputs.deployer_file }} release:switch stage
          private-key: ${{ secrets.stage_key }}

  # ===========================================================================
  # E2E Tests on Stage
  # ===========================================================================
  test-stage:
    name: E2E Tests
    runs-on: ubuntu-latest
    needs: [switch-stage]
    if: ${{ inputs.run_e2e_tests }}
    container:
      image: mcr.microsoft.com/playwright:v1.50.0-noble

    steps:
      - uses: actions/checkout@v4

      - name: Install dependencies
        working-directory: ${{ inputs.e2e_path }}
        run: npm ci

      - name: Run smoke tests
        working-directory: ${{ inputs.e2e_path }}
        env:
          TEST_URL: ${{ inputs.stage_url }}
        run: npx playwright test smoke

      - name: Run visual regression tests
        working-directory: ${{ inputs.e2e_path }}
        env:
          TEST_URL: ${{ inputs.stage_url }}
        run: npx playwright test visual
        continue-on-error: true

      - name: Upload test report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: ${{ inputs.e2e_path }}/playwright-report/
          retention-days: 7

      - name: Upload diff screenshots
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: visual-diff
          path: ${{ inputs.e2e_path }}/test-results/
          retention-days: 7

  # ===========================================================================
  # Deploy to Production
  # ===========================================================================
  deploy-production:
    name: Deploy Production
    runs-on: ubuntu-latest
    needs: [test-stage]
    if: ${{ inputs.deploy_production && (needs.test-stage.result == 'success' || needs.test-stage.result == 'skipped') }}

    steps:
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: ${{ inputs.php_version }}

      - uses: actions/download-artifact@v4
        with:
          name: build-${{ github.sha }}

      - run: tar xf build.tar.gz && rm build.tar.gz

      - run: apt-get update && apt-get install -y openssh-client rsync

      - name: Deploy to production
        uses: deployphp/action@v1
        with:
          deployer-binary: "./bin/dep"
          dep: --file=${{ inputs.deployer_file }} deploy production
          private-key: ${{ secrets.prod_key }}
