name: CI Build Major Branch Keymap

permissions:
  contents: read
  actions: write

on:
  workflow_call:
    inputs:
      branch:
        type: string
        required: true
      keymap:
        type: string
        required: true
      slice_length:
        type: string
        required: true

jobs:
  generate_targets:
    name: "Generate targets (${{ inputs.keymap }})"
    runs-on: ubuntu-latest
    container: ghcr.io/qmk/qmk_cli

    outputs:
      targets: ${{ steps.generate_targets.outputs.targets }}

    steps:
      - name: Disable safe.directory check
        run: |
          git config --global --add safe.directory '*'

      - name: Checkout QMK Firmware
        uses: actions/checkout@v6

      - name: Install dependencies
        run: pip3 install -r requirements-dev.txt

      - name: Generate build targets
        id: generate_targets
        run: |
          { # Intentionally use `shuf` here so that we share manufacturers across all build groups -- some have a lot of ARM-based boards which inherently take longer
            counter=0
            echo -n '{'
            qmk find -km ${{ inputs.keymap }} 2>/dev/null | sort | uniq | shuf | xargs -L${{ inputs.slice_length }} | while IFS=$'\n' read target ; do
                if [ $counter -gt 0 ]; then
                    echo -n ','
                fi
                counter=$((counter+1))
                printf "\"group %02d\":{" $counter
                echo -n '"targets":"'
                echo $target | tr ' ' '\n' | sort | uniq | xargs echo -n
                echo -n '"}'
            done
            echo -n '}'
          } | sed -e 's@\n@@g' > targets.json

          # Output the target keys as a variable
          echo "targets=$(jq -c 'keys' targets.json)" >> $GITHUB_OUTPUT

      - name: Upload targets json
        uses: actions/upload-artifact@v6
        with:
          name: targets-${{ inputs.keymap }}
          path: targets.json

  build_targets:
    name: "Compile ${{ matrix.target }} (${{ inputs.keymap }})"
    needs: generate_targets
    runs-on: ubuntu-latest
    container: ghcr.io/qmk/qmk_cli
    continue-on-error: true

    strategy:
      matrix:
        target: ${{ fromJson(needs.generate_targets.outputs.targets) }}

    steps:
      - name: Disable safe.directory check
        run: |
          git config --global --add safe.directory '*'

      - name: Checkout QMK Firmware
        uses: actions/checkout@v6

      - name: Install dependencies
        run: pip3 install -r requirements-dev.txt

      - name: Get target definitions
        uses: actions/download-artifact@v7
        with:
          name: targets-${{ inputs.keymap }}
          path: .

      - name: Deploy submodules
        run: |
          qmk git-submodule -f

      - name: Dump targets
        run: |
          jq -r '.["${{ matrix.target }}"].targets' targets.json | tr ' ' '\n' | sort

      - name: Build targets
        continue-on-error: true
        run: |
          export NCPUS=$(( $(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || getconf _NPROCESSORS_ONLN 2>/dev/null) -1 ))
          targets=$(jq -r '.["${{ matrix.target }}"].targets' targets.json | tr ' ' '\n' | sort)
          if [ -z "${targets}" ]; then
            echo "Zero build targets detected"
            exit 0
          fi
          qmk mass-compile -t -j $NCPUS -e DUMP_CI_METADATA=yes $targets || touch .failed

      - name: Upload binaries
        uses: actions/upload-artifact@v6
        with:
          name: firmware-${{ inputs.keymap }}-${{ matrix.target }}
          if-no-files-found: ignore
          path: |
            *.bin
            *.hex
            *.uf2
            .build/failed.*
            .failed

      - name: Fail build if any group failed
        run: |
          # Exit with failure if the compilation stage failed
          [ ! -f .failed ] || exit 1

  repack_firmware:
    if: always()
    name: "Repack artifacts"
    needs: build_targets
    runs-on: ubuntu-latest

    steps:
      - name: Checkout QMK Firmware
        uses: actions/checkout@v6

      - name: Download firmwares
        uses: actions/download-artifact@v7
        with:
          pattern: firmware-${{ inputs.keymap }}-*
          path: .
          merge-multiple: true

      - name: Upload all firmwares
        uses: actions/upload-artifact@v6
        with:
          name: firmware-${{ inputs.keymap }}
          if-no-files-found: ignore
          path: |
            *.bin
            *.hex
            *.uf2
            .build/failed.*
            .failed

      - name: Generate output logs
        run: |
          # Generate the step summary markdown
          ./util/ci/generate_failure_markdown.sh > $GITHUB_STEP_SUMMARY || true
          # Truncate to a maximum of 1MB to deal with GitHub workflow limit
          truncate --size='<960K' $GITHUB_STEP_SUMMARY || true

      - name: Delete temporary build artifacts
        uses: geekyeggo/delete-artifact@v5
        with:
          name: |
            firmware-${{ inputs.keymap }}-*
            targets-${{ inputs.keymap }}

      - name: 'CI Discord Notification'
        if: always() && !cancelled()
        working-directory: util/ci/
        env:
          DISCORD_WEBHOOK: ${{ secrets.CI_DISCORD_WEBHOOK }}
        run: |
          python3 -m pip install -r requirements.txt
          python3 ./discord-results.py --branch ${{ inputs.branch || github.ref_name }} --sha $(git rev-parse HEAD) --keymap ${{ inputs.keymap }} --url ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
