on:
  workflow_call:
    inputs:
      deb-src-artifact-id:
        required: true
        type: string
      runs-on:
        required: true
        type: string
      arch:
        required: true
        type: string
      dist-name:
        required: true
        type: string
      dist-version:
        required: true
        type: string
    secrets:
      GPG_SECRET_SUBKEYS:
        required: true
      GPG_SIGNING_SUBKEY_FINGERPRINT:
        required: true
      GPG_AUTH_SUBKEY_KEYGRIP:
        required: true
      OBS_SNAPSHOT_REPO_URL:
        required: true
      OBS_RELEASE_REPO_URL:
        required: true

jobs:
  linux:
    runs-on: ${{ inputs.runs-on }}
    env:
      CONTAINER_DISTRO: trixie
      DEBFULLNAME: apt.bcachefs.org CI bot
      DEBEMAIL: linux-bcachefs@vger.kernel.org
      SUITE: ${{ (github.event_name == 'push' && github.ref_type == 'tag') && 'RELEASE' || 'SNAPSHOT' }}
    steps:
      - name: Configure baseline system
        timeout-minutes: 1
        id: init
        shell: sudo sh "{0}"
        run: |
          set -xe
          mount -t tmpfs tmpfs ${{ github.workspace }}
          echo "set man-db/auto-update false" | debconf-communicate
          dpkg-reconfigure man-db
          mkdir -p /etc/apt/apt.conf.d
          mkdir -p /etc/dpkg/dpkg.cfg.d
          tee /etc/apt/apt.conf.d/99gh > /dev/null <<EOT
          APT::ExtractTemplates::TempDir "/tmp/apt/temp";
          Acquire::Retries "10";
          APT::Install-Recommends "false";
          APT::Install-Suggests "false";
          APT::Get::Assume-Yes "true";
          APT::Get::Fix-Missing "true";
          EOT
          tee /etc/dpkg/dpkg.cfg.d/99gh > /dev/null <<EOT
          force-unsafe-io
          force-confdef
          EOT
          rm -rf /var/lib/apt/lists/*
          rm -rf /etc/apt/sources.list*
          tee /etc/apt/sources.list > /dev/null <<EOT
          deb http://archive.ubuntu.com/ubuntu noble main universe
          EOT
          apt update
          apt install eatmydata
          eatmydata apt install \
            podman \
          ;
          apt clean
      - name: Start the container
        timeout-minutes: 1
        shell: sudo eatmydata sh "{0}"
        run: |
          set -xe
          export IMAGE=debian:${{ env.CONTAINER_DISTRO }}-slim
          podman pull ${IMAGE}
          podman run \
            --name container \
            --image-volume=tmpfs \
            --tmpfs=/run \
            --tmpfs=/tmp \
            --tmpfs=/var/tmp \
            --tmpfs=/var/lib/schroot/union/overlay \
            --volume=/home/runner:/home/runner \
            --volume=${{ github.workspace }}:${{ github.workspace }} \
            --privileged \
            --cap-add=SYS_ADMIN \
            --security-opt=apparmor:unconfined \
            --interactive \
            --tty \
            --detach \
            ${IMAGE} \
            /usr/bin/sh \
          ;
      - name: Install necessary packages
        timeout-minutes: 1
        shell: sudo podman exec --interactive --tty container sh "{0}"
        run: |
          set -xe
          mkdir -p /etc/apt/apt.conf.d
          mkdir -p /etc/dpkg/dpkg.cfg.d
          tee /etc/apt/apt.conf.d/99gh > /dev/null <<EOT
          APT::ExtractTemplates::TempDir "/tmp/apt/temp";
          Acquire::Retries "10";
          APT::Install-Recommends "false";
          APT::Install-Suggests "false";
          APT::Get::Assume-Yes "true";
          APT::Get::Fix-Missing "true";
          EOT
          tee /etc/dpkg/dpkg.cfg.d/99gh > /dev/null <<EOT
          force-unsafe-io
          force-confdef
          EOT
          rm -rf /var/lib/apt/lists/*
          rm -rf /etc/apt/sources.list*
          tee /etc/apt/sources.list > /dev/null <<EOT
          deb http://deb.debian.org/debian ${{ env.CONTAINER_DISTRO }} main
          deb http://deb.debian.org/debian ${{ env.CONTAINER_DISTRO }}-updates main
          deb http://deb.debian.org/debian ${{ env.CONTAINER_DISTRO }}-backports main
          EOT
          apt update
          apt install eatmydata
          eatmydata apt full-upgrade
          eatmydata apt install \
            ca-certificates \
            curl \
            git \
            git-lfs \
            gnupg \
            openssh-client \
            tar \
            xz-utils \
            zip \
          ;
          apt clean
          USER=`whoami`
          usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
      - name: Import/Configure GPG
        timeout-minutes: 1
        id: gpg
        if: github.event_name != 'pull_request'
        shell: sudo podman exec --interactive --tty container eatmydata sh "{0}"
        run: |
          set -xe
          gpg --import <<EOT
          ${{ secrets.GPG_SECRET_SUBKEYS }}
          EOT
          set -xe
          gpg \
            --output /etc/apt/trusted.gpg.d/apt.bcachefs.org.asc \
            --armor \
            --export \
            ${{ secrets.GPG_SIGNING_SUBKEY_FINGERPRINT }} \
          ;
          rm -f ~/.gnupg/trustedkeys.gpg
          gpg \
            --no-default-keyring \
            --keyring ~/.gnupg/trustedkeys.gpg \
            --import \
            /etc/apt/trusted.gpg.d/apt.bcachefs.org.asc \
          ;
      - name: Ensure that the download directory does not exist
        timeout-minutes: 1
        run: |
          set -xe
          rm -rf "${{ github.workspace }}/deb-src"
      - name: Download source-only .deb to be built
        timeout-minutes: 1
        uses: actions/download-artifact@v5
        with:
          artifact-ids: ${{ inputs.deb-src-artifact-id }}
          path: deb-src
      - name: Check attestation of all incoming artifact archives
        timeout-minutes: 1
        if: github.event_name != 'pull_request'
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          set -xe
          cd "${{ github.workspace }}/deb-src"
          find . -type f -print0 | xargs --null -I'{}' sh -c "                 \
            echo '::group::Attestation check for {}' &&                        \
            (                                                                  \
              gh attestation verify                                            \
                {}                                                             \
                --repo        ${{ github.repository }}                         \
                --signer-repo ${{ github.repository }}                         \
                --source-digest ${{ github.sha }}                              \
                --signer-digest ${{ github.sha }}                              \
              ||                                                               \
              (                                                                \
                echo '::error file={}::NOT ATTESTED!' &&                       \
                echo '::endgroup::' &&                                         \
                exit 1                                                         \
              )                                                                \
            ) &&                                                               \
            echo 'ok.' &&                                                      \
            echo '::endgroup::'                                                \
          "
      - name: Unpack the downloaded tarball
        timeout-minutes: 1
        shell: sudo podman exec --interactive --tty container eatmydata sh "{0}"
        run: |
          set -xe
          cd "${{ github.workspace }}/deb-src"
          tar -xf "${{ github.workspace }}/deb-src/artifact-src.tar"
          rm "${{ github.workspace }}/deb-src/artifact-src.tar"
      - name: Ensure that all incoming source artifacts are signed
        timeout-minutes: 1
        if: steps.gpg.conclusion != 'skipped'
        shell: sudo podman exec --interactive --tty container eatmydata sh "{0}"
        run: |
          set -xe
          cd "${{ github.workspace }}/deb-src"
          find . -type f -not -iname '*.sig' -print0 | xargs --null -I'{}' sh -c "                     \
            echo '::group::Signature check for {}' &&                                                  \
            (                                                                                          \
              gpg --verbose --no-default-keyring --keyring ~/.gnupg/trustedkeys.gpg --verify {}     || \
              gpg --verbose --no-default-keyring --keyring ~/.gnupg/trustedkeys.gpg --verify {}.sig || \
              (                                                                                        \
                echo '::error file={}::NOT SIGNED!' &&                                                 \
                echo '::endgroup::' &&                                                                 \
                exit 1                                                                                 \
              )                                                                                        \
            ) &&                                                                                       \
            echo 'ok.' &&                                                                              \
            echo '::endgroup::'                                                                        \
          "
      - name: Update OBS Repo
        timeout-minutes: 1
        shell: sudo podman exec --interactive --tty container eatmydata sh "{0}"
        run: |
          set -xe
          git config --global user.email "${{ env.DEBFULLNAME }}"
          git config --global user.name "${{ env.DEBEMAIL }}"
          git config --global user.signingkey "${{ secrets.GPG_SIGNING_SUBKEY_FINGERPRINT }}"
          git config --global commit.gpgsign true
          git lfs install
          mkdir -p ~/.ssh
          echo "" >> ~/.ssh/config
          echo "StrictHostKeyChecking=accept-new" >> ~/.ssh/config
          echo "" >> ~/.gnupg/gpg-agent.conf
          echo "enable-ssh-support" >> ~/.gnupg/gpg-agent.conf
          gpgconf --kill gpg-agent
          gpgconf --launch gpg-agent
          export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
          gpg-connect-agent 'keyattr ${{ secrets.GPG_AUTH_SUBKEY_KEYGRIP }} Use-for-ssh: true' /bye
          OBS_REPO_URL="${{ secrets[format('OBS_{0}_REPO_URL', env.SUITE)] }}"
          OBS_REPO_DIR="${{ github.workspace }}/bcachefs-obs"
          git clone "$OBS_REPO_URL" "$OBS_REPO_DIR"
          cd "$OBS_REPO_DIR"
          git config --global --add safe.directory .
          git rm -rf --ignore-unmatch -- .
          tee .gitattributes > /dev/null <<EOT
          *.tar.xz filter=lfs diff=lfs merge=lfs -text
          EOT
          git add .gitattributes
          cp /etc/apt/trusted.gpg.d/apt.bcachefs.org.asc apt.bcachefs.org.keyring
          for suffix in .dsc .tar.xz .tar.xz.sig; do
          cp "${{ github.workspace }}/deb-src/"*$suffix .
          done
          tee dkms-bcachefs.rpmlintrc > /dev/null <<EOT
          addFilter("dkms-bcachefs.noarch: E: devel-file-in-non-devel-package")
          EOT
          tar -xvf *.tar.xz -C "$OBS_REPO_DIR" --wildcards '*/bcachefs-tools.spec' --strip-components=1
          tar -xvf *.tar.xz -C "$OBS_REPO_DIR" --wildcards '*/debian/cargo.config' --strip-components=2
          rm -f "${{ github.workspace }}/_service"
          tee -a "${{ github.workspace }}/_service" > /dev/null <<EOT
          <services>
            <service name="set_version" mode="buildtime" />
          EOT
          for FILENAME in *; do
          CHECKSUM="$(sha256sum "$FILENAME" | awk '{print $1}')"
          tee -a "${{ github.workspace }}/_service" > /dev/null <<EOT
            <service name="verify_file">
              <param name="file">$FILENAME</param>
              <param name="verifier">sha256</param>
              <param name="checksum">$CHECKSUM</param>
            </service>
          EOT
          done
          tee -a "${{ github.workspace }}/_service" > /dev/null <<EOT
          </services>
          EOT
          mv "${{ github.workspace }}/_service" "$OBS_REPO_DIR"
          VER="$(basename --suffix=.tar.xz $(ls *.tar.xz))"
          git add .
          git commit --message="Update to $VER"
          git push
