on:
  push:
    branches: ["master"]
    tags: ["*"]
  pull_request:
    branches: ["master"]

name: Continuous integration

{%- macro steps_pre(cache_key) %}
    - uses: actions/checkout@v4
      with:
        submodules: "true"

    - name: Generate a timestamp
      run: echo "TIMESTAMP=$(date +%Y%m%d%H%M%S)" >>"$GITHUB_ENV"

    - uses: actions/cache@v4
      with:
        path: |
          ~/.cache/pip
          ~/.ccache
        key: {{ cache_key }}-{% raw %}${{ env.TIMESTAMP }}{% endraw %}
        restore-keys: {{ cache_key }}-
{%- endmacro %}

{%- macro steps_post(artifact_name) %}
    - uses: actions/upload-artifact@v4
      with:
        name: {{ artifact_name }}
        path: dist/
{%- endmacro %}

jobs:
  native:
    runs-on: ubuntu-latest

    steps:
    - name: Install packages
      run: export DEBIAN_FRONTEND=noninteractive &&
           sudo apt-get update &&
           sudo apt-get install -y
               black
               ccache
               cmake
               cpplint
               g++
               gcc
               git
               libboost-dev
               libboost-python-dev
               libc6-dev-i386
               libcapstone-dev
               libdw-dev
               python3
               python3-flake8
               python3-pip
               python3-skbuild
               python3-venv
               quilt
               make
               ninja-build
{{ steps_pre("native") }}

    - name: Configure ccache
      run: echo "CCACHE_DIR=$HOME/.ccache" >>"$GITHUB_ENV"

    - name: Show ccache stats
      run: ccache --show-stats --verbose

    - name: Check code style
      run: ./fmt --check

    - name: Build a source distribution
      run: python3 setup.py sdist

    - name: Build
      run: PATH=/usr/lib/ccache:$PATH ./ci
               --skip-repair
               -DVALGRIND_CONFIGURE_FLAGS=--disable-dependency-tracking
               --sanitize

    - name: Smoke test
      run: python3 -m pip install --user dist/wheelhouse/*.whl &&
           ./python3-asan "$(command -v memtrace)" record true &&
           ./python3-asan "$(command -v memtrace)" report | tail

    - name: Show and reset ccache stats
      run: ccache --show-stats --verbose --zero-stats
{{ steps_post("native") }}

  cross:
    strategy:
      matrix:
        arch: [{{ arches|map(attribute=0)|join(",") }}]
        python: [{{ pythons|map(attribute=1)|join(",") }}]
    runs-on: ubuntu-latest

{%- set arch_python %}--arch={% raw %}${{ matrix.arch }}{% endraw %}
               --python={% raw %}${{ matrix.python }}{% endraw %}{%- endset %}

    steps:
{{ steps_pre("cross-${{ matrix.arch }}-${{ matrix.python }}") }}

    - name: Pull the Docker image
      run: ./in-docker
               {{ arch_python }}
               true

    - name: Show ccache stats
      run: ./in-docker
               {{ arch_python }}
               ccache --show-stats --verbose

    - name: Build
      run: ./ci-docker
               {{ arch_python }}
               -DVALGRIND_CONFIGURE_FLAGS=--disable-dependency-tracking

    - name: Show and reset ccache stats
      run: ./in-docker
               {{ arch_python }}
               ccache --show-stats --verbose --zero-stats
{{ steps_post("cross-${{ matrix.arch }}-${{ matrix.python }}") }}

  PyPI:
    runs-on: ubuntu-latest
    needs:
    - native
    - cross
    if: startsWith(github.ref, 'refs/tags/')
    environment: PyPI

    steps:
    - name: Install packages
      run: export DEBIAN_FRONTEND=noninteractive &&
           sudo apt-get update &&
           sudo apt-get install -y
               tree
               twine
               unzip

    - uses: actions/download-artifact@v4

    - name: Show artifacts
      run: tree

    - name: Upload artifacts
      env:
        TWINE_USERNAME: {% raw %}${{ secrets.TWINE_USERNAME }}{% endraw %}
        TWINE_PASSWORD: {% raw %}${{ secrets.TWINE_PASSWORD }}{% endraw %}
      run: twine upload --non-interactive --verbose
               native/*.tar.gz
               cross-*/wheelhouse/*.whl
