name: Documentation

on:
  push:
    branches:
      - 'main'
    paths:
      - '**'
      - '!website/**'
    tags:
      - '**'
  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

env:
  ACTION_PACKAGE: discord-api-types

jobs:
  build-docs:
    name: Build & upload documentation
    runs-on: ubuntu-latest
    env:
      REF_TYPE: ${{ inputs.ref_type || github.ref_type }}
    if: github.repository_owner == 'discordjs'

    steps:
      - name: Checkout discord-api-types
        uses: actions/checkout@v6
        with:
          ref: ${{ inputs.ref || '' }}

      - name: Use Node.js
        uses: actions/setup-node@v6
        with:
          cache: 'yarn'
          node-version-file: package.json

      - name: Install Dependencies for discord-api-types
        run: yarn

      #region DJS start (mostly from discord.js/packages/actions/src/pnpmCache)
      # pnpm --filter="*api-*" --filter="scripts" --filter="actions" run build

      - name: Checkout discord.js
        uses: actions/checkout@v6
        with:
          repository: discordjs/discord.js
          path: djs

      - name: Set up swap space
        if: runner.os == 'Linux'
        uses: pierotofy/set-swap-space@v1.0
        with:
          swap-size-gb: 10

      - uses: pnpm/action-setup@v5.0.0
        name: Install pnpm
        with:
          run_install: false
          package_json_file: djs/package.json

      - name: Expose pnpm config(s) through "$GITHUB_OUTPUT"
        id: pnpm-config
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT

      - name: Cache rotation keys
        id: cache-rotation
        shell: bash
        run: |
          echo "YEAR_MONTH=$(/bin/date -u "+%Y%m")" >> $GITHUB_OUTPUT

      - uses: actions/cache@v5
        name: Setup pnpm cache
        with:
          path: ${{ steps.pnpm-config.outputs.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-cache-${{ steps.cache-rotation.outputs.YEAR_MONTH }}-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-cache-${{ steps.cache-rotation.outputs.YEAR_MONTH }}-

      - name: Install djs dependencies
        working-directory: djs
        shell: bash
        run: |
          pnpm install --filter="*api-*" --filter="scripts" --filter="actions" --frozen-lockfile --prefer-offline --loglevel error
        env:
          HUSKY: '0'

      - name: Build djs
        working-directory: djs
        shell: bash
        run: |
          pnpm --filter="*api-*" --filter="scripts" --filter="actions" run build

      #endregion

      - name: Extract package and semver from tag
        if: ${{ env.REF_TYPE == 'tag' }}
        id: extract-tag
        uses: ./djs/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-api-types/tree/main!https://github.com/discordjs/discord-api-types/tree/${{ github.ref_name }}!' "api-extractor.json"

      - name: Build docs
        shell: bash
        run: |
          yarn prepack
          ./djs/packages/api-extractor/bin/api-extractor run --local --minify
          ./djs/packages/scripts/bin/generateSplitDocumentation.js
          yarn postpack

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadDocumentation.ts

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadDocumentation.ts

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadSplitDocumentation.ts

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadSplitDocumentation.ts

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadDocumentation.ts

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadDocumentation.ts

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadSplitDocumentation.ts

      - 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 }}
          ACTION_PACKAGE: ${{ env.ACTION_PACKAGE }}
          ACTION_VERSION: ${{ steps.extract-tag.outputs.semver }}
        run: |
          yarn tsx ./scripts/actions/documentation/uploadSplitDocumentation.ts
