name: Build & test

on:
  workflow_call:
    inputs:
      arch:
        required: true
        type: string
      flavor:
        required: true
        type: string

concurrency:
  group: ${{ github.workflow }}-${{ github.head_ref || github.ref_name }}-${{ inputs.flavor }}-aarch64
  cancel-in-progress: true

permissions:
  contents: read

jobs:
  build-iso:
    needs: detect
    runs-on: [self-hosted, arm64]
    env:
      FLAVOR: ${{ inputs.flavor }}
      ARCH: aarch64
    steps:
      - uses: actions/checkout@v4
      - run: |
          git fetch --prune --unshallow
      - name: Cached ISO
        id: cache-iso
        uses: actions/cache/restore@v4
        env:
          cache-name: pr-iso-build-aarch64-${{ inputs.flavor }}
          enableCrossOsArchive: true
          lookup-only: true
        with:
          path: /tmp/*.iso
          key: ${{ env.cache-name }}-${{ hashFiles('Dockerfile', '**/go.sum', '**/pkg/**', '**/examples/**', '**/cmd/**', '**/vendor/**', '**/Makefile', '**/main.go') }}
      - if: ${{ steps.cache-iso.outputs.cache-hit != 'true' }}
        name: Build toolkit
        run: |
          make build
      - if: ${{ steps.cache-iso.outputs.cache-hit != 'true' }}
        name: Build ISO
        run: |
          make build-iso
          sudo mv build/elemental-${{ env.FLAVOR }}.${{ env.ARCH}}.iso /tmp/
      - if: ${{ steps.cache-iso.outputs.cache-hit != 'true' }}
        name: Save ISO
        id: save-iso
        uses: actions/cache/save@v4
        env:
          cache-name: pr-iso-build-aarch64-${{ inputs.flavor }}
        with:
          path: /tmp/*.iso
          key: ${{ env.cache-name }}-${{ hashFiles('Dockerfile', '**/go.sum', '**/pkg/**', '**/examples/**', '**/cmd/**', '**/vendor/**', '**/Makefile', '**/main.go') }}
          enableCrossOsArchive: true
  
  build-disk:
    needs: detect
    runs-on: [self-hosted, arm64]
    env:
      FLAVOR: ${{ inputs.flavor }}
      ARCH: aarch64
    steps:
      - uses: actions/checkout@v4
      - run: |
          git fetch --prune --unshallow
      - name: Checks cached Disk
        uses: actions/cache/restore@v4
        id: cache-check
        env:
          cache-name: pr-disk-build-aarch64-${{ inputs.flavor }}
        with:
          path: /tmp/*.qcow2
          key: ${{ env.cache-name }}-${{ hashFiles('Dockerfile', '**/go.sum', '**/pkg/**', '**/examples/**', '**/cmd/**', '**/vendor/**', '**/Makefile', '**/main.go') }}
          enableCrossOsArchive: true
          lookup-only: true
      - if: ${{ steps.cache-check.outputs.cache-hit != 'true' }}
        name: Cleanup worker
        run: |
          sudo rm -rf /usr/local/lib/android # will release about 10 GB if you don't need Android
          sudo rm -rf /usr/share/dotnet # will release about 20GB if you don't need .NET
          sudo df -h
      - if: ${{ steps.cache-check.outputs.cache-hit != 'true' }}
        name: Install to disk
        run: |
          sudo apt-get update && sudo apt-get install -y --no-install-recommends qemu-utils coreutils
          make ARCH=${{ env.ARCH }} build-os
          sudo -E make ARCH=${{ env.ARCH }} build-disk
          sudo mv build/elemental-${{ env.FLAVOR }}.${{ env.ARCH}}.qcow2 /tmp/
      - if: ${{ steps.cache-check.outputs.cache-hit != 'true' }}
        name: Save cached disk
        id: cache-disk
        uses: actions/cache/save@v4
        env:
          cache-name: pr-disk-build-aarch64-${{ inputs.flavor }}
        with:
          path: /tmp/*.qcow2
          key: ${{ env.cache-name }}-${{ hashFiles('Dockerfile', '**/go.sum', '**/pkg/**', '**/examples/**', '**/cmd/**', '**/vendor/**', '**/Makefile', '**/main.go') }}
          enableCrossOsArchive: true

  tests-matrix:
    needs: 
      - build-disk
      - detect
    runs-on: [self-hosted, arm64]
    env:
      FLAVOR: ${{ inputs.flavor }}
      ARCH: aarch64
      COS_TIMEOUT: 1600
    strategy:
      matrix:
        test: 
          - test-smoke
      fail-fast: false
    steps:
      - uses: actions/checkout@v4
      - name: Install Go
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
      - run: |
          git fetch --prune --unshallow
      - name: Cached Disk
        id: cache-disk
        uses: actions/cache/restore@v4
        env:
          cache-name: pr-disk-build-aarch64-${{ inputs.flavor }}
        with:
          path: /tmp/*.qcow2
          key: ${{ env.cache-name }}-${{ hashFiles('Dockerfile', '**/go.sum', '**/pkg/**', '**/examples/**', '**/cmd/**', '**/vendor/**', '**/Makefile', '**/main.go') }}
          enableCrossOsArchive: true
          fail-on-cache-miss: true
      - name: Run ${{ matrix.test }} 
        run: |
          make DISK=/tmp/elemental-${{ env.FLAVOR }}.${{ env.ARCH}}.qcow2 ELMNTL_ACCEL=none ELMNTL_MACHINETYPE=virt ELMNTL_TARGETARCH=${{ env.ARCH }} ELMNTL_FIRMWARE=/usr/share/AAVMF/AAVMF_CODE.fd ${{ matrix.test }}
      - name: Upload serial console for ${{ matrix.test }}
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: serial-${{ env.ARCH }}-${{ env.FLAVOR }}-${{ matrix.test }}.log
          path: tests/serial.log
          if-no-files-found: error
          overwrite: true
      - name: Upload qemu stdout for ${{ matrix.test }}
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: vmstdout-${{ env.ARCH }}-${{ env.FLAVOR }}-${{ matrix.test }}.log
          path: tests/vmstdout
          if-no-files-found: error
          overwrite: true
      - name: Stop test VM
        if: always()
        run: |
          make test-clean

  test-installer:
    needs: 
      - build-iso
      - detect
    runs-on: [self-hosted, arm64]
    env:
      FLAVOR: ${{ inputs.flavor }}
      ARCH: aarch64
      COS_TIMEOUT: 1600
    steps:
      - uses: actions/checkout@v4
      - name: Install Go
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod
      - run: |
          git fetch --prune --unshallow
      - name: Cached ISO
        id: cache-iso
        uses: actions/cache/restore@v4
        env:
          cache-name: pr-iso-build-aarch64-${{ inputs.flavor }}
        with:
          path: /tmp/*.iso
          key: ${{ env.cache-name }}-${{ hashFiles('Dockerfile', '**/go.sum', '**/pkg/**', '**/examples/**', '**/cmd/**', '**/vendor/**', '**/Makefile', '**/main.go') }}
          enableCrossOsArchive: true
          fail-on-cache-miss: true
      - name: Run installer test 
        run: |
          make ISO=/tmp/elemental-${{ env.FLAVOR }}.${{ env.ARCH}}.iso ELMNTL_ACCEL=none ELMNTL_MACHINETYPE=virt ELMNTL_TARGETARCH=${{ env.ARCH }} ELMNTL_FIRMWARE=/usr/share/AAVMF/AAVMF_CODE.fd test-installer
      - name: Upload serial console for installer tests
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: serial-${{ env.ARCH }}-${{ env.FLAVOR }}-installer.log
          path: tests/serial.log
          if-no-files-found: error
          overwrite: true
      - name: Upload qemu stdout for installer tests
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: vmstdout-${{ env.ARCH }}-${{ env.FLAVOR }}-installer.log
          path: tests/vmstdout
          if-no-files-found: error
          overwrite: true
      - name: Stop test VM
        if: always()
        run: |
          make test-clean
