name: Documentation
on:
  push:
    branches:
      - 'main'
    paths:
      - 'packages/*/src/**'
      - '!packages/create-discord-bot/**'
      - '!packages/proxy-container/**'
      - '!packages/ui/**'
    tags:
      - '**'
      - '!create-discord-app@*'
      - '!create-discord-bot@*'
  workflow_dispatch:
    inputs:
      ref:
        description: 'The branch, tag or SHA to checkout'
        required: true
      ref_type:
        type: choice
        description: 'Branch or tag'
        options:
          - branch
          - tag
        required: true
concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
  cancel-in-progress: true
jobs:
  build-docs:
    name: Build & upload documentation
    runs-on: ubuntu-latest
    env:
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
      TURBO_TEAM: ${{ vars.TURBO_TEAM }}
      REF_TYPE: ${{ inputs.ref_type || github.ref_type }}
    if: github.repository_owner == 'discordjs'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          ref: ${{ inputs.ref || '' }}

      - name: Install Node.js v24
        uses: actions/setup-node@v6
        with:
          node-version: 24
          package-manager-cache: false

      - name: Install dependencies
        uses: ./packages/actions/src/pnpmCache

      - name: Build dependencies
        run: pnpm run build

      - name: Checkout main repository
        if: ${{ inputs.ref && inputs.ref != 'main' }}
        uses: actions/checkout@v6
        with:
          path: 'main'

      - name: Build main
        if: ${{ inputs.ref && inputs.ref != 'main' }}
        shell: bash
        env:
          COREPACK_ENABLE_STRICT: 0
        run: |
          cd main
          pnpm self-update 10
          pnpm install --frozen-lockfile --prefer-offline --loglevel error
          pnpm run build
          cd ..

      - name: Extract package and semver from tag
        if: ${{ env.REF_TYPE == 'tag' }}
        id: extract-tag
        uses: ./packages/actions/src/formatTag
        with:
          tag: ${{ inputs.ref || github.ref_name }}

      - name: Apply tag to api-extractor config
        if: ${{ env.REF_TYPE == 'tag' && !inputs.ref }}
        run: sed -i 's!https://github.com/discordjs/discord.js/tree/main!https://github.com/discordjs/discord.js/tree/${{ github.ref_name }}!' "packages/${{ steps.extract-tag.outputs.package}}/api-extractor.json"

      - name: Build docs
        run: pnpm run docs

      - name: Build docs with main api-extractor
        if: ${{ inputs.ref && inputs.ref != 'main' }}
        run: |
          declare -a PACKAGES=("brokers" "builders" "collection" "core" "discord.js" "formatters" "next" "proxy" "rest" "structures" "util" "voice" "ws")
          for PACKAGE in "${PACKAGES[@]}"; do
            if [ ! -d "packages/${PACKAGE}" ]; then
              echo "::notice::${PACKAGE} does not exist on this ref. Skipping..."
              continue
            fi

            cd "packages/${PACKAGE}"
            sed -i 's!https://github.com/discordjs/discord.js/tree/main!https://github.com/discordjs/discord.js/tree/${{ inputs.ref }}!' api-extractor.json
            ../../main/packages/api-extractor/bin/api-extractor run --local --minify
            ../../main/packages/scripts/bin/generateSplitDocumentation.js
            cd ../..
          done

      - name: Upload documentation to database
        if: ${{ env.REF_TYPE == 'tag' && (!inputs.ref || inputs.ref == 'main') }}
        env:
          CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
          CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
          CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
          CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
        uses: ./packages/actions/src/uploadDocumentation
        with:
          package: ${{ steps.extract-tag.outputs.package }}
          version: ${{ steps.extract-tag.outputs.semver }}

      - name: Upload documentation to database
        if: ${{ env.REF_TYPE == 'tag' && inputs.ref && inputs.ref != 'main' }}
        env:
          CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
          CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
          CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
          CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
        uses: ./main/packages/actions/src/uploadDocumentation
        with:
          package: ${{ steps.extract-tag.outputs.package }}
          version: ${{ steps.extract-tag.outputs.semver }}

      - name: Upload split documentation to blob storage
        if: ${{ env.REF_TYPE == 'tag' && (!inputs.ref || inputs.ref == 'main') }}
        env:
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
        uses: ./packages/actions/src/uploadSplitDocumentation
        with:
          package: ${{ steps.extract-tag.outputs.package }}
          version: ${{ steps.extract-tag.outputs.semver }}

      - name: Upload split documentation to blob storage
        if: ${{ env.REF_TYPE == 'tag' && inputs.ref && inputs.ref != 'main' }}
        env:
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
        uses: ./main/packages/actions/src/uploadSplitDocumentation
        with:
          package: ${{ steps.extract-tag.outputs.package }}
          version: ${{ steps.extract-tag.outputs.semver }}

      - name: Upload documentation to database
        if: ${{ env.REF_TYPE == 'branch' && (!inputs.ref || inputs.ref == 'main') }}
        env:
          CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
          CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
          CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
          CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
        uses: ./packages/actions/src/uploadDocumentation

      - name: Upload documentation to database
        if: ${{ env.REF_TYPE == 'branch' && inputs.ref && inputs.ref != 'main' }}
        env:
          CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
          CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
          CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
          CF_R2_DOCS_BUCKET_URL: ${{ secrets.CF_R2_DOCS_BUCKET_URL }}
        uses: ./main/packages/actions/src/uploadDocumentation

      - name: Upload split documentation to blob storage
        if: ${{ env.REF_TYPE == 'branch' && (!inputs.ref || inputs.ref == 'main') }}
        env:
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
        uses: ./packages/actions/src/uploadSplitDocumentation

      - name: Upload split documentation to blob storage
        if: ${{ env.REF_TYPE == 'branch' && inputs.ref && inputs.ref != 'main' }}
        env:
          CF_R2_DOCS_URL: ${{ secrets.CF_R2_DOCS_URL }}
          CF_R2_DOCS_ACCESS_KEY_ID: ${{ secrets.CF_R2_DOCS_ACCESS_KEY_ID }}
          CF_R2_DOCS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_DOCS_SECRET_ACCESS_KEY }}
          CF_R2_DOCS_BUCKET: ${{ secrets.CF_R2_DOCS_BUCKET }}
        uses: ./main/packages/actions/src/uploadSplitDocumentation

  build-indices:
    needs: build-docs
    name: Build & upload search indices
    runs-on: ubuntu-latest
    env:
      TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
      TURBO_TEAM: ${{ vars.TURBO_TEAM }}
    if: github.repository_owner == 'discordjs'
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Install Node.js v24
        uses: actions/setup-node@v6
        with:
          node-version: 24
          package-manager-cache: false

      - name: Install dependencies
        uses: ./packages/actions/src/pnpmCache

      - name: Build dependencies
        run: pnpm run build

      - name: Upload search indices to meilisearch
        env:
          CF_D1_DOCS_API_KEY: ${{ secrets.CF_D1_DOCS_API_KEY }}
          CF_D1_DOCS_ID: ${{ secrets.CF_D1_DOCS_ID }}
          CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
          SEARCH_API_URL: ${{ secrets.SEARCH_API_URL }}
          SEARCH_API_KEY: ${{ secrets.SEARCH_API_KEY }}
        uses: ./packages/actions/src/uploadSearchIndices
