name: Build

on:
  workflow_dispatch:
    inputs:
      flavor:
        description: 'Optional build flavor (e.g. _minimal)'
        required: false
        default: ''
        type: string
      parallel:
        description: 'Massive parallel build of each image'
        required: false
        default: true
        type: boolean
      infix_repo:
        description: 'Repo to checkout (for spin overrides)'
        required: false
        default: kernelkit/infix
        type: string


  workflow_call:
    inputs:
      target:
        required: true
        type: string
      name:
        required: true
        type: string
      flavor:
        required: false
        type: string
        default: ''
      infix_repo:
        required: false
        type: string
        default: kernelkit/infix

env:
  FLV: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.flavor || inputs.flavor }}
  INFIX_REPO: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.infix_repo || inputs.infix_repo }}

jobs:
  build:
    name: Build ${{ inputs.name }} ${{ inputs.target }}
    runs-on: [ self-hosted, latest ]
    strategy:
      fail-fast: false
    outputs:
      build_id: ${{ steps.vars.outputs.INFIX_BUILD_ID }}
    steps:
      - name: Cleanup Build Folder
        run: |
          ls -la ./
          rm -rf ./* || true
          rm -rf ./.??* || true
          ls -la ./

      - name: Checkout infix repo
        uses: actions/checkout@v4
        with:
          repository: ${{ env.INFIX_REPO }}
          ref: ${{ github.ref }}
          clean: true
          fetch-depth: 0
          submodules: recursive

      - name: Set Build Variables
        id: vars
        run: |
          if [ -n "${{ github.event.pull_request.head.sha }}" ]; then
              # Since PRs are built from an internally generated merge
              # commit, reverse lookups of PRs and/or commits from
              # image version information are cumbersome.  Therefore:
              # explicitly set a build id that references both the PR
              # and the commit.
              printf "INFIX_BUILD_ID=pr%d.%.7s\n" \
                  "${{ github.event.number }}" "${{ github.event.pull_request.head.sha }}" \
                  | tee -a $GITHUB_OUTPUT $GITHUB_ENV
          fi

          target=${{ inputs.target }}
          name=${{ inputs.name }}
          echo "dir=${name}-${target}"        >> $GITHUB_OUTPUT
          echo "tgz=${name}-${target}.tar.gz" >> $GITHUB_OUTPUT
          echo "flv=$FLV"              >> $GITHUB_OUTPUT
          echo "Building target ${target}${FLV}_defconfig"

      - name: Restore Cache of dl/
        uses: actions/cache@v4
        with:
          path: dl/
          key: dl-${{ hashFiles('.git/modules/buildroot/HEAD', 'configs/*', 'package/*/*.hash') }}
          restore-keys: |
            dl-

      - name: Restore Cache of .ccache/
        uses: actions/cache@v4
        with:
          path: .ccache/
          key: ccache-${{ inputs.target }}-${{ hashFiles('.git/modules/buildroot/HEAD', 'package/*/*.hash') }}
          restore-keys: |
            ccache-${{ inputs.target }}-
            ccache-

      - name: Configure ${{ inputs.target }}${{ steps.vars.outputs.flv }}
        run: |
          make ${{ inputs.target }}${{ steps.vars.outputs.flv }}_defconfig

      - name: Unit Test ${{ inputs.target }}
        run: |
          make test-unit

      - name: Prepare parallel build
        id: parallel
        run: |

          if [ "${{ ((github.event.inputs.parallel == 'true' && github.event_name == 'workflow_dispatch') || (github.ref_name != 'main' && github.event_name != 'workflow_dispatch')) }}" == "true" ]; then
             echo "BR2_PER_PACKAGE_DIRECTORIES=y" >> output/.config
             MAKE="make -j$((`getconf _NPROCESSORS_ONLN` / 2 + 2))"
             echo "Building in parallel with -j$((`getconf _NPROCESSORS_ONLN` / 2 + 2))"
          else
             echo "Disabling parallel build"
             MAKE="make"
          fi
          echo "MAKE=$MAKE" >> $GITHUB_OUTPUT

      - name: Build ${{ inputs.target }}${{ steps.vars.outputs.flv }}
        run: |
          echo "Building ${{ inputs.target }}${{ steps.vars.outputs.flv }}_defconfig ..."
          eval "${{ steps.parallel.outputs.MAKE }}"

      - name:  Check SBOM from Build
        run: |
          make legal-info

      - name: Build test specification
        run: |
          make test-spec

      - name: Resulting size of build
        run: |
          printf "Size of complete tree : "
          du -sh .
          printf "Size of output/       : "
          du -sh output
          printf "Size of dl/           : "
          du -sh dl
          printf "Size of output/images/: "
          ls -l output/images/

      - name: Prepare ${{ inputs.target }} Artifact
        run: |
          cd output/
          mv images ${{ steps.vars.outputs.dir }}
          ln -s ${{ steps.vars.outputs.dir }} images
          tar cfz ${{ steps.vars.outputs.tgz }} ${{ steps.vars.outputs.dir }}

      - uses: actions/upload-artifact@v4
        with:
          path: output/${{ steps.vars.outputs.tgz }}
          name: artifact-${{ inputs.target }}
