name: Hyperion APT Build

on:
  # Reusable from nightly and push
  workflow_call:
    inputs:
      head_sha:
        type: string
        description: The branch, tag or SHA to checkout
        default: "master"
        required: false
      nightly:
        type: boolean
        description: Nightly build
        default: false
        required: false
      publish:
        type: boolean
        description: Publish packages
        default: false
        required: false
  # For running the workflow manually via GitHub Actions tab
  workflow_dispatch:
    inputs:
      head_sha:
        type: string
        description: The branch, tag or SHA to checkout
        default: "master"
        required: false
      nightly:
        type: boolean
        description: Nightly build
        default: false
        required: false
      publish:
        type: boolean
        description: Publish packages
        default: false
        required: false

env:
  ghcr: hyperion-project

jobs:
  build:
    name: ๐Ÿง ${{ matrix.os.description }} (${{ matrix.architecture[0] }})
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        os: [
          { distribution: ubuntu, codename: focal,    description: Ubuntu 20.04 (Focal Fossa)     },
          { distribution: ubuntu, codename: jammy,    description: Ubuntu 22.04 (Jammy Jellyfish) },
          { distribution: ubuntu, codename: lunar,    description: Ubuntu 23.04 (Lunar Lobster)   },
          { distribution: ubuntu, codename: mantic,   description: Ubuntu 23.10 (Mantic Minotaur) },
          { distribution: debian, codename: buster,   description: Debian 10.x (Buster)           },
          { distribution: debian, codename: bullseye, description: Debian 11.x (Bullseye)         },
          { distribution: debian, codename: bookworm, description: Debian 12.x (Bookworm)         },
          { distribution: debian, codename: trixie,   description: Debian 13.x (Trixie)           }
        ]
        architecture: [
          [ amd64, linux/amd64  ],
          [ arm64, linux/arm64  ],
          [ armhf, linux/arm/v7 ]
        ]
        include:
          - os: { distribution: debian, codename: bullseye, description: Debian 11.x (Bullseye) }
            architecture: [ armel, linux/arm/v6 ]
          - os: { distribution: debian, codename: bookworm, description: Debian 12.x (Bookworm) }
            architecture: [ armel, linux/arm/v6 ]
          - os: { distribution: debian, codename: trixie, description: Debian 13.x (Trixie) }
            architecture: [ armel, linux/arm/v6 ]

    steps:
      - name: โฌ‡ Checkout
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.inputs.head_sha || github.event.client_payload.head_sha }}
          submodules: recursive

      - name: ๐Ÿ”ง Prepare
        run: |
          echo '::group::Checking the version number'
            if [[ "${{ inputs.nightly }}" = true ]]; then
              echo "$(tr -d '\n' < .version)+nightly$(date '+%Y%m%d')$(git rev-parse --short HEAD)" > .version
            else
              tr -d '\n' < .version > temp && mv temp .version
            fi
          echo '::endgroup::'

          echo '::group::Generate environment variables'
            VERSION=$(cat .version)
            echo VERSION=${VERSION} >> $GITHUB_ENV
            if [[ $VERSION == *"-"* ]]; then
              echo STANDARDS_VERSION=$(echo ${VERSION%-*}) >> $GITHUB_ENV
              echo DEBIAN_FORMAT='3.0 (quilt)' >> $GITHUB_ENV
            else
              echo STANDARDS_VERSION=$(echo ${VERSION%+*}) >> $GITHUB_ENV
              echo DEBIAN_FORMAT='3.0 (native)' >> $GITHUB_ENV
            fi
          echo '::endgroup::'

      - name: ๐Ÿ› ๏ธ Setup QEMU
        uses: docker/setup-qemu-action@v3

      - name: ๐Ÿ‘ท Build
        shell: bash
        run: |
          mkdir -p "${GITHUB_WORKSPACE}/deploy"
          docker run --rm --platform=${{ matrix.architecture[1] }} \
            -v "${GITHUB_WORKSPACE}/deploy:/deploy" \
            -v "${GITHUB_WORKSPACE}:/source:rw" \
            ghcr.io/${{ env.ghcr }}/${{ matrix.os.distribution }}:${{ matrix.os.codename }} \
            /bin/bash -c "cd /source && \
            mkdir -p debian/source && echo '${{ env.DEBIAN_FORMAT }}' > debian/source/format && echo 10 > debian/compat && \
            dch --create --distribution ${{ matrix.os.codename }} --package 'hyperion' -v '${{ env.VERSION }}~${{ matrix.os.codename }}' '${{ github.event.commits[0].message }}' && \
            cp -fr LICENSE debian/copyright && \
            sed 's/@ARCHITECTURE@/${{ matrix.architecture[0] }}/g; s/@STANDARDS_VERSION@/${{ env.STANDARDS_VERSION }}/g' debian/control.in > debian/control && \
            debuild -b -uc -us && \
            cp ../hyperion_*.deb /deploy"

      - name: ๐Ÿ“ฆ Upload
        if: ${{ inputs.publish }}
        uses: actions/upload-artifact@v3
        with:
          path: deploy
          retention-days: 1

  publish:
    name: ๐Ÿš€ Publish DEB packages
    if: ${{ github.repository == 'hyperion-project' && inputs.publish }}
    needs: [build]
    runs-on: ubuntu-latest
    steps:
      - name: โฌ‡ Checkout
        uses: actions/checkout@v4
        with:
          ref: ${{ github.event.inputs.head_sha || github.event.client_payload.head_sha }}

      - name: ๐Ÿ”‘ GPG Import
        if: ${{ env.SECRET_GPG_KEY != null }}
        uses: crazy-max/ghaction-import-gpg@v5
        with:
          gpg_private_key: ${{ secrets.GPG_KEY }}
        env:
          SECRET_GPG_KEY: ${{ secrets.GPG_KEY }}

      - name: ๐Ÿ’พ Artifact download
        uses: actions/download-artifact@v3

      - name: ๐Ÿ”ง Prepare
        if: ${{ env.SECRET_APT_REPO_NIGHTLY != null && env.SECRET_APT_REPO != null }}
        run: |
          echo '::group::Install reprepro'
            sudo apt -y install reprepro
          echo '::endgroup::'

          echo '::group::Create initial structure'
            mkdir -p deb/{conf,dists,db}
            cp debian/distributions deb/conf/distributions
            if [[ "${{ inputs.nightly }}" = true ]]; then
              touch "deb/$(git rev-parse --short HEAD)"
            fi
            reprepro -Vb deb createsymlinks
            reprepro -Vb deb export
          echo '::endgroup::'

          echo '::group::Include artifacts into the package source'
            for file in artifact/hyperion_*.deb; do
              if [ -f "$file" ]; then
                dist=${file#*~}
                dist=${dist%_*}
                reprepro -Vb deb/ includedeb "$dist" "$file"
              fi
            done
          echo '::endgroup::'

          echo '::group::Set server directory'
            if [[ "${{ inputs.nightly }}" = true ]]; then
              echo "SERVER_DIR=${{ secrets.APT_REPO_NIGHTLY }}" >> $GITHUB_ENV
            else
              echo "SERVER_DIR=${{ secrets.APT_REPO }}" >> $GITHUB_ENV
            fi
          echo '::endgroup::'
        env:
          SECRET_APT_REPO_NIGHTLY: ${{ secrets.APT_REPO_NIGHTLY }}
          SECRET_APT_REPO: ${{ secrets.APT_REPO }}

      - name: ๐Ÿ“ฆ Upload
        if: ${{ env.SECRET_REPO_USER != null && env.SECRET_REPO_PASSWORD != null && env.SERVER_DIR != null }}
        uses: SamKirkland/FTP-Deploy-Action@v4.3.4
        with:
          server: releases.hyperion-project.org
          username: ${{ secrets.REPO_USER }}
          password: ${{ secrets.REPO_PASSWORD }}
          server-dir: ${{ env.SERVER_DIR }}
          local-dir: "./deb/"
          dangerous-clean-slate: true
        env:
          SECRET_REPO_USER: ${{ secrets.REPO_USER }}
          SECRET_REPO_PASSWORD: ${{ secrets.REPO_PASSWORD }}

      - name: ๐Ÿงน Cleanup
        uses: geekyeggo/delete-artifact@v2
        with:
          name: artifact
          failOnError: false