name: build

on:
  - push
  - pull_request

jobs:
  build:
    strategy:
      matrix:
        os:
          - ubuntu_x64_8_cores
        ocaml-version:
          - '5.2.0+ox'
        oxcaml-opam-commit:
          - '231c88c2e564fdca40e15e750aacad5fb0887435'

    runs-on: ${{ matrix.os }}
    steps:
      - name: Checkout code
        uses: actions/checkout@v6

      - uses: actions/cache@v5
        with:
          path: ~/.opam
          key: ${{ matrix.os }}-opam-${{ matrix.ocaml-version }}-${{ matrix.oxcaml-opam-commit }}-1

      - name: Install musl-compatible kernel headers
        run: |
          mkdir musl-kernel
          filename='v4.19.88-1.tar.gz'
          wget "https://github.com/sabotage-linux/kernel-headers/archive/refs/tags/$filename"
          shasum --check <(echo "44a07e9f18033cff7840dbb112fff2862c0fb8fc  $filename")
          tar -xzf "$filename" -C musl-kernel --strip-components=1
          echo "C_INCLUDE_PATH=$(pwd)/musl-kernel/x86/include" >> "$GITHUB_ENV"
          echo "CC=musl-gcc" >> "$GITHUB_ENV"

      - name: "Install apt packages"
        run: |
          sudo apt-get update
          sudo apt-get install -y bubblewrap musl musl-tools libucl1 rsync

      - name: Install upx
        run: |
          # The version that comes with focal is broken for musl binaries, so we have to download
          # from another location.
          filename='upx-ucl_3.96-2_amd64.deb'
          wget "http://ftp.debian.org/debian/pool/main/u/upx-ucl/$filename"
          shasum --check <(echo "0b3c901a6ae8db264a0e58aad9bbed4ef3e925b9  $filename")
          sudo dpkg -i upx-ucl_3.96-2_amd64.deb

      - name: Build zlib with musl
        run: |
          mkdir musl-zlib
          filename='zlib-1.3.2.tar.gz'
          wget "https://zlib.net/$filename"
          shasum -a 256 --check <(echo "bb329a0a2cd0274d05519d61c667c062e06990d72e125ee2dfa8de64f0119d16  $filename")
          tar -xzf "$filename" -C musl-zlib --strip-components=1
          cd musl-zlib
          CC=musl-gcc ./configure --libdir=/usr/lib/x86_64-linux-musl --includedir=/usr/include/x86_64-linux-musl
          make -j$(nproc)
          sudo make install

      - name: Build zstd with musl
        run: |
          mkdir musl-zstd
          filename='zstd-1.5.5.tar.gz'
          wget "https://github.com/facebook/zstd/releases/download/v1.5.5/$filename"
          shasum --check <(echo "4479ecc74300d23391d99fbebf2fddd47aed9b28  $filename")
          tar -xzf "$filename" -C musl-zstd --strip-components=1
          cd musl-zstd
          CC=musl-gcc make -j$(nproc)
          sudo make INCLUDEDIR=/usr/include/x86_64-linux-musl LIBDIR=/usr/lib/x86_64-linux-musl install

      - name: Use OCaml ${{ matrix.ocaml-version }}
        run: |
          filename='opam-2.5.0-x86_64-linux'
          wget "https://github.com/ocaml/opam/releases/download/2.5.0/$filename"
          shasum --check <(echo "67fb680a785f0bc7ceb57155f21786c0680ef5fe  $filename")
          sudo mv "$filename" /usr/local/bin/opam
          sudo chmod a+x /usr/local/bin/opam

          export OPAMYES=1
          export OPAMJOBS=$(($(nproc) + 2))
          export OPAMROOTISOK=1
          echo "OPAMYES=1" >> "$GITHUB_ENV"
          echo "OPAMJOBS=$OPAMJOBS" >> "$GITHUB_ENV"
          echo "OPAMROOTISOK=$OPAMROOTISOK" >> "$GITHUB_ENV"

          opam init --bare -yav https://github.com/ocaml/opam-repository.git
          opam switch set ${{ matrix.ocaml-version }} 2>/dev/null || \
            opam switch create ${{ matrix.ocaml-version }} --repos "ox=git+https://github.com/oxcaml/opam-repository.git#${{ matrix.oxcaml-opam-commit }},default"

      - run: opam install . --deps-only --locked --with-test

      - run: opam exec -- dune build @fmt

      - run: opam exec -- make PROFILE=static

      - run: opam exec -- dune runtest

      - name: Compress magic-trace executable
        run: |
          cp _build/install/default/bin/magic-trace .
          ls -l magic-trace
          strip magic-trace
          upx -9 magic-trace

      - uses: actions/upload-artifact@v6
        with:
          name: magic-trace
          path: magic-trace
          if-no-files-found: error

      - name: Upload to GitHub releases
        if: startsWith(github.ref, 'refs/tags/')
        uses: svenstaro/upload-release-action@v2
        with:
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          file: magic-trace
          asset_name: magic-trace
          tag: ${{ github.ref }}
          overwrite: true