name: Build and publish sonarcal

on: push

jobs:
  test:
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]
        python-version: ["3.11", "3.12", "3.13", "3.14"]
    runs-on: ${{ matrix.os }}
    env:
      # Display must be available globally for linux to know where xvfb is
      DISPLAY: ":99.0"

    steps:
      - name: Set environment variables (Linux/macOS)
        if: runner.os != 'Windows'
        run: echo "OFFLINE_PLUGIN_ENABLED=true" >> $GITHUB_ENV
      - name: Set environment variables (Windows)
        if: runner.os == 'Windows'
        run: echo "OFFLINE_PLUGIN_ENABLED=true" | Out-File -FilePath $env:GITHUB_ENV -Append
      - name: Checkout sonarcal
        uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Build offline documentation (should get this done via pyproject.toml settings)
        run: |
          pip install mkdocs mkdocstrings[python] mkdocs-material
          mkdocs build --clean --verbose 
      - name: Install packages
        run: |
          python -m pip install --upgrade pip
          python -m pip install .[dev]  # NOTE: [dev] includes pytest
      - name: Setup xvfb (Linux)
        if: runner.os == 'Linux'
        run: |
          sudo apt-get update
          # from https://stackoverflow.com/questions/60692711
          sudo apt-get install -y xvfb libxkbcommon-x11-0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xinerama0 libxcb-xinput0 libxcb-xfixes0 libxcb-shape0 libglib2.0-0 libgl1-mesa-dev
          sudo apt-get install '^libxcb.*-dev' libx11-xcb-dev libglu1-mesa-dev libxrender-dev libxi-dev libxkbcommon-dev libxkbcommon-x11-dev
          # start xvfb in the background
          sudo /usr/bin/Xvfb $DISPLAY -screen 0 1280x1024x24 &
      - name: Run tests with pytest
        run: |
          # export DISPLAY=:99
          # Xvfb :99 &
          python -m pytest -v -s

  build:
    name: Build distribution
    runs-on: ubuntu-latest
    needs: 
      - test

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: "3.x"
    - name: Build offline documentation
      run: |
        pip install mkdocs mkdocstrings[python] mkdocs-material
        export OFFLINE_PLUGIN_ENABLED=true
        mkdocs build --clean --verbose  # writes offline docs to directory 'site'
    - name: Install pypa/build
      run: python3 -m pip install build --user
    - name: Get history and tags for SCM versioning to work
      run: |
        git branch
        git fetch --prune --unshallow
        git fetch --depth=1 origin +refs/tags/*:refs/tags/*
    - name: Build a binary wheel and a source tarball
      run: python3 -m build
    - name: Store the distribution packages
      uses: actions/upload-artifact@v4
      with:
        name: python-package-distributions
        path: dist/

  publish-to-pypi:
    name: >-
      Publish sonarcal to PyPI
    if: startsWith(github.ref, 'refs/tags/')  # only publish to PyPI on tag pushes
    needs:
    - build
    runs-on: ubuntu-latest
    environment:
      name: pypi
      url: https://pypi.org/p/sonarcal
    permissions:
      id-token: write  # IMPORTANT: mandatory for trusted publishing

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@v4
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution to PyPI
      uses: pypa/gh-action-pypi-publish@release/v1

  github-release:
    name: >-
      Sign the Python distribution with Sigstore
      and upload them to GitHub Release
    needs:
    - publish-to-pypi
    runs-on: ubuntu-latest

    permissions:
      contents: write  # IMPORTANT: mandatory for making GitHub Releases
      id-token: write  # IMPORTANT: mandatory for sigstore

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@v4
      with:
        name: python-package-distributions
        path: dist/
    - name: Sign the dists with Sigstore
      uses: sigstore/gh-action-sigstore-python@v3.0.0
      with:
        inputs: >-
          ./dist/*.tar.gz
          ./dist/*.whl
    - name: Create GitHub Release
      env:
        GITHUB_TOKEN: ${{ github.token }}
      run: >-
        gh release create
        '${{ github.ref_name }}'
        --repo '${{ github.repository }}'
        --notes ""
    - name: Upload artifact signatures to GitHub Release
      env:
        GITHUB_TOKEN: ${{ github.token }}
      # Upload to GitHub Release using the `gh` CLI.
      # `dist/` contains the built packages, and the
      # sigstore-produced signatures and certificates.
      run: >-
        gh release upload
        '${{ github.ref_name }}' dist/**
        --repo '${{ github.repository }}'

  publish-to-testpypi:
    name: Publish sonarcal to TestPyPI
    needs:
    - build
    runs-on: ubuntu-latest

    environment:
      name: testpypi
      url: https://test.pypi.org/p/sonarcal

    permissions:
      id-token: write  # IMPORTANT: mandatory for trusted publishing

    steps:
    - name: Download all the dists
      uses: actions/download-artifact@v4
      with:
        name: python-package-distributions
        path: dist/
    - name: Publish distribution to TestPyPI
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        verbose: true
        repository-url: https://test.pypi.org/legacy/