basemap-data

name: basemap-data

env:
  PKGDIR: "packages/basemap_data"
  PIP_DEFAULT_TIMEOUT: 10
  PIP_DISABLE_PIP_VERSION_CHECK: 1
  PIP_PREFER_BINARY: 1
  PIP_RETRIES: 0
  PYTHONUNBUFFERED: "1"
  PYTHONWARNINGS: "ignore:DEPRECATION"

on:
  push:
    paths:
      - ".github/workflows/basemap-data.yml"
      - "packages/basemap_data/**"
  pull_request:
    paths:
      - ".github/workflows/basemap-data.yml"
      - "packages/basemap_data/**"
  workflow_dispatch:

jobs:

  checkout:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v4
      -
        name: Upload checkout
        uses: actions/upload-artifact@v4
        with:
          name: checkout
          path: .

  build:
    strategy:
      matrix:
        python-version:
          ["2.7"]
      max-parallel: 1
    needs: checkout
    runs-on: ubuntu-latest
    container: "pylegacy/python:${{ matrix.python-version }}-debian-10"
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v4
        with:
          name: checkout
          path: .
      -
        name: Build sdist and wheel
        run: |
          cd ${{ env.PKGDIR }}
          python setup.py sdist
          pip wheel -w dist --no-deps dist/*.zip
      -
        name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: artifacts-build
          path: ${{ env.PKGDIR }}/dist

  test:
    strategy:
      matrix:
        python-version:
          ["2.6", "2.7", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8",
           "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 3
      fail-fast: false
    needs: build
    runs-on: ubuntu-latest
    container: "pylegacy/python:${{ matrix.python-version }}-debian-10"
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v4
        with:
          name: checkout
          path: .
      -
        name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: artifacts-build
          path: ${{ env.PKGDIR }}/dist
      -
        name: Install package
        run: |
          pip install ${{ env.PKGDIR }}/dist/*.whl
      -
        name: Test package
        run: |
          python -c "from mpl_toolkits import basemap_data; print(basemap_data)"

  upload:
    strategy:
      matrix:
        python-version:
          ["2.7"]
      max-parallel: 1
    if: startsWith(github.event.ref, 'refs/tags/v')
    needs: test
    runs-on: ubuntu-latest
    container: "pylegacy/python:${{ matrix.python-version }}-debian-10"
    environment: PyPI
    steps:
      -
        name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: artifacts-build
          path: ${{ env.PKGDIR }}/dist
      -
        name: Install upload requirements
        run: |
          pip install twine
      -
        name: Check distributables
        run: |
          python -m twine check                                               \
              ${{ env.PKGDIR }}/dist/*.zip                                    \
              ${{ env.PKGDIR }}/dist/*.whl
      -
        name: Upload distributables
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: "${{ secrets.PYPI_TOKEN }}"
          TWINE_REPOSITORY_URL: "${{ secrets.PYPI_REPOSITORY_URL }}"
        run: |
          python -m twine upload --skip-existing                              \
              ${{ env.PKGDIR }}/dist/*.zip                                    \
              ${{ env.PKGDIR }}/dist/*.whl


basemap-for-manylinux

name: basemap-for-manylinux

env:
  PKGDIR: "packages/basemap"
  PIP_DEFAULT_TIMEOUT: 10
  PIP_DISABLE_PIP_VERSION_CHECK: 1
  PIP_PREFER_BINARY: 1
  PIP_RETRIES: 0
  PYTHONUNBUFFERED: "1"
  PYTHONWARNINGS: "ignore:DEPRECATION"

on:
  push:
    paths:
      - ".github/workflows/basemap-for-manylinux.yml"
      - "packages/basemap/**"
  pull_request:
    paths:
      - ".github/workflows/basemap-for-manylinux.yml"
      - "packages/basemap/**"
  workflow_dispatch:

jobs:

  checkout:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v1
      -
        name: Upload checkout
        uses: actions/upload-artifact@v1
        with:
          name: checkout
          path: .

  lint:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 3
      fail-fast: false
    needs: checkout
    container: "pylegacy/python:${{ matrix.python-version }}-debian-10"
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v1
        with:
          name: checkout
          path: .
      -
        name: Install lint requirements
        run: |
          cd ${{ env.PKGDIR }}
          pip install -r requirements-lint.txt
      -
        name: Install library requirements
        run: |
          cd ${{ env.PKGDIR }}
          pip install -r requirements.txt
      -
        name: Run Flake8
        run: |
          cd ${{ env.PKGDIR }}
          if [ -x "$(command -v flake8)" ]; then
              flake8 src/mpl_toolkits/basemap/cm.py src/mpl_toolkits/basemap/diagnostic.py src/mpl_toolkits/basemap/proj.py src/mpl_toolkits/basemap/solar.py test;
          fi
      -
        name: Run PyLint
        run: |
          cd ${{ env.PKGDIR }}
          if [ -x "$(command -v pylint)" ]; then
              pylint src/mpl_toolkits/basemap/cm.py src/mpl_toolkits/basemap/diagnostic.py src/mpl_toolkits/basemap/proj.py src/mpl_toolkits/basemap/solar.py test;
          fi

  build-geos:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
      max-parallel: 2
      fail-fast: false
    needs: lint
    runs-on: ubuntu-latest
    container: "pylegacy/${{ matrix.arch }}-python:3.8-debian-4"
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v1
        with:
          name: checkout
          path: .
      -
        name: Install CMake 3.6.2
        run: |
          apt-get update
          apt-get install -y libidn11
          pkgvers=3.6.2
          pkgname=cmake
          pkgcode=cmake-${pkgvers}
          case "${{ matrix.arch }}" in
              x86)  pkgfile=${pkgcode}-Linux-i386.tar.gz;;
              *)    pkgfile=${pkgcode}-Linux-x86_64.tar.gz;;
          esac
          wget https://github.com/Kitware/CMake/releases/download/v${pkgvers}/${pkgfile} -P /tmp
          tar -xf /tmp/${pkgfile} --strip-components=1 -C /usr
          rm -rf /tmp/${pkgfile}
      -
        name: Install GCC toolchain
        run: |
          apt-get update
          apt-get install -y gcc g++ make
      -
        name: Build GEOS from source
        run: |
          cd ${{ env.PKGDIR }}
          python -c "import utils; utils.GeosLibrary('3.6.5').build('extern', njobs=16)"
      -
        name: Upload GEOS artifacts
        uses: actions/upload-artifact@v1
        with:
          name: artifacts-geos-${{ matrix.arch }}
          path: ${{ env.PKGDIR }}/extern

  build:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 3
      fail-fast: false
    needs: build-geos
    runs-on: ubuntu-latest
    container: "pylegacy/${{ matrix.arch }}-python:${{ matrix.python-version }}-debian-4"
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v1
        with:
          name: checkout
          path: .
      -
        name: Download GEOS artifacts
        uses: actions/download-artifact@v1
        with:
          name: artifacts-geos-${{ matrix.arch }}
          path: ${{ env.PKGDIR }}/extern
      -
        name: Install GCC toolchain
        run: |
          apt-get update
          apt-get install -y gcc g++ make
      -
        name: Build old numpy from source
        run: |
          case "${{ matrix.arch }}" in
              x64)  arch="x86_64" ;;
              x86)  arch="i686"   ;;
          esac
          case "${{ matrix.python-version }}" in
              2.6|3.[23])      pkgvers=1.11.3; tag=manylinux1 ;;
              2.7|3.[456789])  pkgvers=1.16.6; tag=manylinux1 ;;
              3.10)            pkgvers=1.21.4; tag=manylinux1 ;;
              3.11)            pkgvers=1.23.3; tag=manylinux_2_17 ;;
              *)               pkgvers=1.26.1; tag=manylinux_2_28 ;;
          esac
          case "${{ matrix.python-version }}" in
              3.11|3.12)
                  # Dirty solution to get NumPy headers for Python 3.11 and 3.12.
                  kwds="--plat=${tag}_${arch}"
                  pip download --no-deps ${kwds} "numpy==${pkgvers}"
                  oldpkgfile=$(ls *.whl | head -n1)
                  newpkgfile=$(echo "${oldpkgfile}" | sed "s/${tag}/linux/")
                  mv "${oldpkgfile}" "${newpkgfile}"
                  pip install "${newpkgfile}"
                  rm "${newpkgfile}"
              ;;
              *)
                  pip install "numpy == ${pkgvers}"
              ;;
          esac
      -
        name: Build wheel
        run: |
          sitepkgdir=$(pip show numpy 2>/dev/null | grep Location: | cut -d' ' -f2)
          export GEOS_DIR="${GITHUB_WORKSPACE}/${{ env.PKGDIR }}/extern"
          export NUMPY_INCLUDE_PATH=${sitepkgdir}/numpy/core/include
          case "${{ matrix.python-version }}" in
              3.11|3.12)
                kwds="--no-build-isolation"
                pip install setuptools wheel "cython >= 0.29, < 3.1"
              ;;
          esac
          cd ${{ env.PKGDIR }}
          python setup.py sdist
          pip wheel -w dist --no-deps ${kwds} dist/*.zip
      -
        name: Upload build artifacts
        uses: actions/upload-artifact@v1
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist

  repair:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 3
      fail-fast: false
    needs: build
    runs-on: ubuntu-latest
    container: "pylegacy/${{ matrix.arch }}-python:3.8-debian-10"
    steps:
      -
        name: Download GEOS artifacts
        uses: actions/download-artifact@v1
        with:
          name: artifacts-geos-${{ matrix.arch }}
          path: ${{ env.PKGDIR }}/extern
      -
        name: Download build artifacts
        uses: actions/download-artifact@v1
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist
      -
        name: Install auditwheel
        run: |
          apt-get update
          apt-get install -y unzip
          pip install patchelf
          pip install "auditwheel < 4.0"
      -
        name: Repair wheel
        run: |
          cd ${{ env.PKGDIR }}
          export LD_LIBRARY_PATH="$(readlink -f extern/lib)"
          auditwheel repair -w dist dist/*.whl
      -
        name: Upload build artifacts
        uses: actions/upload-artifact@v1
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist

  test:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
        exclude:
          # Missing precompiled binaries for `numpy`, `matplotlib`,
          # `pyproj`, `pillow` and `lxml`.
          - arch: "x86"
            python-version: "3.12"
      max-parallel: 3
      fail-fast: false
    needs: repair
    runs-on: ubuntu-latest
    container: "pylegacy/${{ matrix.arch }}-python:${{ matrix.python-version }}-debian-10"
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v1
        with:
          name: checkout
          path: .
      -
        name: Download build artifacts
        uses: actions/download-artifact@v1
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist
      -
        name: Install numpy from source
        run: |
          apt-get update
          apt-get install -y gcc g++ make
          pip install "numpy < 1.24"
        if: matrix.arch == 'x86' && (matrix.python-version >= '3.8' || matrix.python-version >= '3.10')
      -
        name: Install test requirements
        run: |
          cd ${{ env.PKGDIR }}
          pip install -r requirements-test.txt
      -
        name: Install package (full)
        run: |
          whlpath=$(ls ${{ env.PKGDIR }}/dist/*-manylinux1*.whl | head -n1)
          pip install "${whlpath}[owslib,pillow]"
      -
        name: Test package
        run: |
          cd ${{ env.PKGDIR }}
          export COVERAGE_FILE=.coverage.${{ matrix.python-version }}
          python -m pytest                                                    \
              --cov="mpl_toolkits.basemap" --cov-report=term                  \
              --ignore=dist --ignore=build
      -
        name: Upload test artifacts
        uses: actions/upload-artifact@v1
        with:
          name: artifacts-test
          path: ${{ env.PKGDIR }}/.coverage.${{ matrix.python-version }}

  coverage:
    needs: test
    runs-on: ubuntu-latest
    container: "pylegacy/python:3.8-debian-10"
    steps:
      -
        name: Checkout
        uses: actions/checkout@v1
      -
        name: Download test artifacts
        uses: actions/download-artifact@v1
        with:
          name: artifacts-test
          path: ${{ env.PKGDIR }}
      -
        name: Install test requirements
        run: |
          cd ${{ env.PKGDIR }}
          pip install -r requirements-test.txt
      -
        name: Compute combined coverage
        run: |
          cd ${{ env.PKGDIR }}
          coverage combine
          coverage html
          coverage report
      -
        name: Upload coverage artifacts
        uses: actions/upload-artifact@v1
        with:
          name: artifacts-coverage
          path: ${{ env.PKGDIR }}/htmlcov

  docs:
    needs: test
    runs-on: ubuntu-latest
    container: "pylegacy/python:3.8-debian-10"
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v1
        with:
          name: checkout
          path: .
      -
        name: Install doc requirements
        run: |
          cd ${{ env.PKGDIR }}
          pip install -r requirements-doc.txt
      -
        name: Download build artifacts
        uses: actions/download-artifact@v1
        with:
          name: artifacts-build-x64-3.8
          path: ${{ env.PKGDIR }}/dist
      -
        name: Install package
        run: |
          cd ${{ env.PKGDIR }}
          pip install dist/*-manylinux1*.whl
      -
        name: Run sphinx
        run: |
          cd ${{ env.PKGDIR }}
          python -m sphinx doc/source public
      -
        name: Upload docs artifacts
        uses: actions/upload-artifact@v1
        with:
          name: artifacts-docs
          path: ${{ env.PKGDIR }}/public
      -
        name: Upload github-pages artifact
        uses: actions/upload-pages-artifact@v3
        with:
          name: github-pages
          path: ${{ env.PKGDIR }}/public

  pages:
    if: startsWith(github.event.ref, 'refs/tags/v')
    needs: docs
    runs-on: ubuntu-latest
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    permissions:
      pages: write
      id-token: write
    steps:
      - name: Deploy github-pages
        uses: actions/deploy-pages@v3
        id: deployment

  upload:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 1
    if: startsWith(github.event.ref, 'refs/tags/v')
    needs: test
    runs-on: ubuntu-latest
    container: "pylegacy/${{ matrix.arch }}-python:${{ matrix.python-version }}-debian-10"
    environment: PyPI
    steps:
      -
        name: Download build artifacts
        uses: actions/download-artifact@v1
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist
      -
        name: Install upload requirements
        run: |
          pip install twine
      -
        name: Check distributables
        run: |
          python -m twine check                                               \
              ${{ env.PKGDIR }}/dist/*.zip                                    \
              ${{ env.PKGDIR }}/dist/*-manylinux1*.whl
      -
        name: Upload distributables
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: "${{ secrets.PYPI_TOKEN }}"
          TWINE_REPOSITORY_URL: "${{ secrets.PYPI_REPOSITORY_URL }}"
        run: |
          python -m twine upload --skip-existing                              \
              ${{ env.PKGDIR }}/dist/*.zip                                    \
              ${{ env.PKGDIR }}/dist/*-manylinux1*.whl


basemap-for-windows

name: basemap-for-windows

env:
  PKGDIR: "packages/basemap"
  PIP_DEFAULT_TIMEOUT: 10
  PIP_DISABLE_PIP_VERSION_CHECK: 1
  PIP_PREFER_BINARY: 1
  PIP_RETRIES: 0
  PYTHONUNBUFFERED: "1"
  PYTHONWARNINGS: "ignore:DEPRECATION"

on:
  push:
    paths:
      - ".github/workflows/basemap-for-windows.yml"
      - "!packages/basemap/doc/**"
      - "packages/basemap/**"
  pull_request:
    paths:
      - ".github/workflows/basemap-for-windows.yml"
      - "!packages/basemap/doc/**"
      - "packages/basemap/**"
  workflow_dispatch:

jobs:

  checkout:
    runs-on: windows-2019
    steps:
      -
        name: Checkout
        uses: actions/checkout@v4
      -
        name: Upload checkout
        uses: actions/upload-artifact@v4
        with:
          name: checkout
          path: .

  lint:
    runs-on: windows-2019
    strategy:
      matrix:
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 3
      fail-fast: false
    needs: checkout
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v4
        with:
          name: checkout
          path: .
      -
        name: Set Python
        uses: pylegacy/actions/setup-pyenv-win@v2
        with:
          architecture: ${{ matrix.arch }}
          python-version: ${{ matrix.python-version }}
      -
        name: Set Python base packages
        run: |
          python -m pip install --upgrade pip setuptools wheel
      -
        name: Install lint requirements
        run: |
          cd ${{ env.PKGDIR }}
          python -m pip install -r requirements-lint.txt
      -
        name: Install library requirements
        run: |
          cd ${{ env.PKGDIR }}
          python -m pip install -r requirements.txt
      -
        name: Run Flake8
        run: |
          cd ${{ env.PKGDIR }}
          if (Get-Command flake8 -errorAction SilentlyContinue)
          {
              flake8 src/mpl_toolkits/basemap/cm.py src/mpl_toolkits/basemap/diagnostic.py src/mpl_toolkits/basemap/proj.py src/mpl_toolkits/basemap/solar.py test;
          }
      -
        name: Run PyLint
        run: |
          cd ${{ env.PKGDIR }}
          if (Get-Command pylint -errorAction SilentlyContinue)
          {
              pylint src/mpl_toolkits/basemap/cm.py src/mpl_toolkits/basemap/diagnostic.py src/mpl_toolkits/basemap/proj.py src/mpl_toolkits/basemap/solar.py test;
          }

  build-geos:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        msvc-toolset:
          ["9.0", "14.0"]
        include:
          - msvc-toolset: "9.0"
            python-version: "2.7"
          - msvc-toolset: "14.0"
            python-version: "3.5"
      max-parallel: 4
      fail-fast: false
    needs: lint
    runs-on: windows-2019
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v4
        with:
          name: checkout
          path: .
      -
        name: Set MSVC toolset
        uses: pylegacy/actions/setup-msvc@v2
        with:
          arch: ${{ matrix.arch }}
          toolset: ${{ matrix.msvc-toolset }}
      -
        name: Set CMake
        uses: jwlawson/actions-setup-cmake@v2.0
        with:
          cmake-version: "3.24.2"
      -
        name: Set Python
        uses: pylegacy/actions/setup-pyenv-win@v2
        with:
          architecture: ${{ matrix.arch }}
          python-version: ${{ matrix.python-version }}
      -
        name: Build GEOS from source
        run: |
          cd ${{ env.PKGDIR }}
          python -c "import utils; utils.GeosLibrary('3.6.5').build('extern', toolset='${{ matrix.msvc-toolset }}', njobs=16)"
      -
        name: Upload GEOS artifacts
        uses: actions/upload-artifact@v4
        with:
          name: artifacts-geos-${{ matrix.arch }}-msvc${{ matrix.msvc-toolset }}
          path: ${{ env.PKGDIR }}/extern

  build:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 3
      fail-fast: false
    needs: build-geos
    runs-on: windows-2019
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v4
        with:
          name: checkout
          path: .
      -
        name: Set Python
        uses: pylegacy/actions/setup-pyenv-win@v2
        with:
          architecture: ${{ matrix.arch }}
          python-version: ${{ matrix.python-version }}
      -
        name: Set Python base packages
        run: |
          python -m pip install --upgrade pip setuptools wheel
      -
        name: Build old numpy from source
        run: |
          Switch -regex ("${{ matrix.python-version }}") {
              "^2\.6|3\.[123]$"     { Set-Variable -Name "pkgvers" -Value "1.11.3" }
              "^2\.7|3\.[456789]$"  { Set-Variable -Name "pkgvers" -Value "1.16.6" }
              "^3\.10$"             { Set-Variable -Name "pkgvers" -Value "1.21.4" }
              "^3\.11$"             { Set-Variable -Name "pkgvers" -Value "1.23.3" }
              default               { Set-Variable -Name "pkgvers" -Value "1.26.1" }
          }
          $env:SETUPTOOLS_USE_DISTUTILS = "stdlib"
          python -m pip install "numpy == ${pkgvers}"
      -
        name: Set MSVC toolset version
        run: |
          if ("${{ matrix.python-version }}" -eq "2.7") {
              echo "msvc-toolset=9.0" >> $env:GITHUB_ENV
          } else {
              echo "msvc-toolset=14.0" >> $env:GITHUB_ENV
          }
      -
        name: Set MSVC toolset
        uses: pylegacy/actions/setup-msvc@v2
        with:
          arch: ${{ matrix.arch }}
          toolset: ${{ env.msvc-toolset }}
      -
        name: Download GEOS artifacts
        uses: actions/download-artifact@v4
        with:
          name: artifacts-geos-${{ matrix.arch }}-msvc${{ env.msvc-toolset }}
          path: ${{ env.PKGDIR }}/extern
      -
        name: Build sdist and wheel
        run: |
          cd ${{ env.PKGDIR }}
          $env:GEOS_DIR = "$env:GITHUB_WORKSPACE/${{ env.PKGDIR }}/extern"
          python -m pip install -r requirements-setup.txt
          python setup.py sdist
          python -m pip wheel -w dist --no-deps (Get-Item dist/*.zip)
      -
        name: Upload build artifacts
        uses: actions/upload-artifact@v4
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist

  test:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
        exclude:
          # Missing precompiled binaries for `numpy` and `matplotlib`.
          - arch: "x86"
            python-version: "3.12"
      max-parallel: 3
      fail-fast: false
    needs: build
    runs-on: windows-2019
    steps:
      -
        name: Download checkout
        uses: actions/download-artifact@v4
        with:
          name: checkout
          path: .
      -
        name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist
      -
        name: Set Python
        uses: pylegacy/actions/setup-pyenv-win@v2
        with:
          architecture: ${{ matrix.arch }}
          python-version: ${{ matrix.python-version }}
      -
        name: Set Python base packages
        run: |
          python -m pip install --upgrade pip setuptools wheel
      -
        name: Install test requirements
        run: |
          cd ${{ env.PKGDIR }}
          pip install -r requirements-test.txt
      -
        name: Install package (full)
        run: |
          $whlpath = "$(Get-Item ${{ env.PKGDIR }}/dist/*-win*.whl)"
          python -m pip install "${whlpath}[owslib,pillow]"
      -
        name: Test package
        run: |
          cd ${{ env.PKGDIR }}
          $env:COVERAGE_FILE = ".coverage.${{ matrix.arch }}.${{ matrix.python-version }}"
          python -m pytest                                                    `
              --cov="mpl_toolkits.basemap" --cov-report=term                  `
              --ignore=dist --ignore=build
      -
        name: Upload test artifacts
        uses: actions/upload-artifact@v4
        with:
          name: artifacts-test-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/.coverage.${{ matrix.arch }}.${{ matrix.python-version }}

  upload:
    strategy:
      matrix:
        arch:
          ["x64", "x86"]
        python-version:
          ["2.7", "3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
      max-parallel: 1
    if: startsWith(github.event.ref, 'refs/tags/v')
    needs: test
    runs-on: windows-2019
    environment: PyPI
    steps:
      -
        name: Set Python
        uses: pylegacy/actions/setup-pyenv-win@v2
        with:
          architecture: ${{ matrix.arch }}
          python-version: ${{ matrix.python-version }}
      -
        name: Download build artifacts
        uses: actions/download-artifact@v4
        with:
          name: artifacts-build-${{ matrix.arch }}-${{ matrix.python-version }}
          path: ${{ env.PKGDIR }}/dist
      -
        name: Install upload requirements
        run: |
          python -m pip install twine
      -
        name: Check distributables
        run: |
          python -m twine check                                               `
              ${{ env.PKGDIR }}/dist/*.zip                                    `
              ${{ env.PKGDIR }}/dist/*.whl
      -
        name: Upload distributables
        env:
          TWINE_USERNAME: __token__
          TWINE_PASSWORD: "${{ secrets.PYPI_TOKEN }}"
          TWINE_REPOSITORY_URL: "${{ secrets.PYPI_REPOSITORY_URL }}"
        run: |
          python -m twine upload --skip-existing                              `
              ${{ env.PKGDIR }}/dist/*.whl


CodeQL

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ "master" ]
  pull_request:
    branches: [ "master" ]
  schedule:
    - cron: '35 0 * * 5'

jobs:
  analyze:
    name: Analyze
    # Runner size impacts CodeQL analysis time. To learn more, please see:
    #   - https://gh.io/recommended-hardware-resources-for-running-codeql
    #   - https://gh.io/supported-runners-and-hardware-resources
    #   - https://gh.io/using-larger-runners
    # Consider using larger runners for possible analysis time improvements.
    runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
    timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
    permissions:
      # required for all workflows
      security-events: write

      # only required for workflows in private repositories
      actions: read
      contents: read

    strategy:
      fail-fast: false
      matrix:
        language: [ 'javascript-typescript', 'python', 'ruby' ]
        # CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
        # Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
        # Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.

        # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

    # Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v3

    # ℹ Command-line programs to run using the OS shell.
    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

    #   If the Autobuild fails above, remove it and uncomment the following three lines.
    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

    # - run: |
    #     echo "Run, Build Application using script"
    #     ./location_of_script_within_repo/buildscript.sh

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        category: "/language:${{matrix.language}}"


publish 🐳 Docker image

name: publish 🐳 Docker image

on:
  push:
    tags:
      - "v*"

jobs:
  build-and-push-container:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:

      - name: cut v from tag
        env:
          TAG: ${{ github.ref_name }}
        id: split
        run: echo "tag=${TAG:1}" >> $GITHUB_OUTPUT

      - uses: voxpupuli/gha-build-and-publish-a-container@v2
        with:
          registry_password: ${{ secrets.GITHUB_TOKEN }}
          build_arch: linux/amd64,linux/arm64
          docker_username: voxpupulibot
          docker_password: ${{ secrets.DOCKERHUB_BOT_PASSWORD}}
          tags: |
            ghcr.io/${{ github.repository }}:${{ steps.split.outputs.tag }}
            ghcr.io/${{ github.repository }}:latest
            docker.io/${{ github.repository }}:${{ steps.split.outputs.tag }}
            docker.io/${{ github.repository }}:latest

      - name: Update Docker Hub Description
        uses: peter-evans/dockerhub-description@v4
        with:
          username: voxpupulibot
          password: ${{ secrets.DOCKERHUB_BOT_PASSWORD }}


publish 🐍 egg to PyPI

name: publish 🐍 egg to PyPI

on:
  push:
    tags:
      - "v*"

jobs:
  build-n-publish:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4
      - name: Set up Python 3.12
        uses: actions/setup-python@v5
        with:
          python-version: 3.12
      - name: Install dependencies
        run: |
          pip install wheel
      - name: Build
        run: |
          python setup.py build sdist bdist_wheel
      - name: Publish distribution 📦 to PyPI
        uses: pypa/gh-action-pypi-publish@v1.9.0
        with:
          password: ${{ secrets.PYPI_API_TOKEN_PUPPETBOARD }}
          # repository_url: https://test.pypi.org/legacy/
      - name: Create release in GitHub
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          draft: false
          prerelease: false


tests (unit)

name: tests (unit)

on:
  pull_request: {}
  push:
    branches:
      - master

jobs:
  test:

    runs-on: ubuntu-latest

    strategy:
      max-parallel: 5
      matrix:
        python-version: [3.8, 3.9, '3.10', 3.11, 3.12]

    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          pip install --upgrade wheel setuptools
          python setup.py develop
          pip install -r requirements-test.txt
          mypy --install-types --non-interactive puppetboard/ test/
      - name: Test
        run: |
          pytest --cov=. --cov-report=xml --strict-markers --mypy -v puppetboard test
          pylint --errors-only puppetboard test
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4.3.0
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: true

  build_docker_image:
    name: 'Test building a container'
    runs-on: ubuntu-latest
    permissions:
      contents: read
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - name: Build Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: false

  security-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python 3.12
        uses: actions/setup-python@v5
        with:
          python-version: 3.12
      - name: Install dependencies
        run: |
          pip install bandit
      - name: Run bandit
        run: |
          bandit -r puppetboard

  tests:
    needs:
      - test
      - build_docker_image
      - security-tests
    runs-on: ubuntu-latest
    name: Test suite
    steps:
      - run: echo Test suite completed


Trivy

---
name: Trivy

on:
  push:
    branches:
      - master
  pull_request:
    # The branches below must be a subset of the branches above
    branches:
      - master

jobs:
  analyze:
    name: 'Analyze'
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Build Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          tags: 'ci/puppetboard:${{ github.sha }}'
          push: false

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: 'ci/puppetboard:${{ github.sha }}'
          format: 'sarif'
          output: 'trivy-results.sarif'

      - name: Upload Trivy scan results to GitHub Security tab
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: 'trivy-results.sarif'


CI

name: CI

on:
  push:
    branches:
      - stable
      - main
      - 4.1-update
    tags:
      - v*
  pull_request:
    branches:
      - '**'

concurrency:
  group: ${{ github.ref }}-${{ github.workflow }}-${{ github.event_name }}-${{ github.ref == 'refs/heads/main' && github.sha || '' }}
  cancel-in-progress: true

defaults:
  run:
    shell: bash

jobs:
  build:
    name: Build ${{ matrix.os.name }} ${{ matrix.python.name }}
    runs-on: ${{ matrix.os.runs-on }}
    strategy:
      fail-fast: false
      matrix:
        os:
          - name: 🐧
            runs-on: ubuntu-latest
        python:
          - name: CPython 3.10
            major_dot_minor: '3.10'
            action: '3.10'
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        # with:
          # This allows the matrix to specify just the major.minor version while still
          # expanding it to get the latest patch version including alpha releases.
          # This avoids the need to update for each new alpha, beta, release candidate,
          # and then finally an actual release version.  actions/setup-python doesn't
          # support this for PyPy presently so we get no help there.
          #
          # CPython -> 3.9.0-alpha - 3.9.X
          # PyPy    -> pypy-3.7
          # python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python.action), matrix.python.action))[startsWith(matrix.python.action, 'pypy')] }}
          # architecture: x64

      - name: Setup environment
        run: |
          python -m pip install build

      - name: Build sdist and wheel
        run: |
          python -m build

      - name: Publish package files
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: packages
          path: dist/*
          if-no-files-found: error

  test:
    name: Test ${{ matrix.os.name }} ${{ matrix.python.name }}
    needs:
      - build
    runs-on: ${{ matrix.os.runs-on }}
    strategy:
      fail-fast: false
      matrix:
        os:
          - name: 🐧
            runs-on: ubuntu-latest
          - name: 🍎
            # This would preferably be macos-latest, but it has pip updating bugs right now.
            runs-on: macos-12
          - name: 🪟
            runs-on: windows-latest
        python:
          - name: CPython 3.8
            major_dot_minor: '3.8'
            action: '3.8'
          - name: CPython 3.9
            major_dot_minor: '3.9'
            action: '3.9'
          - name: CPython 3.10
            major_dot_minor: '3.10'
            action: '3.10'
          - name: CPython 3.11
            major_dot_minor: '3.11'
            action: '3.11'
          - name: CPython 3.12
            major_dot_minor: '3.12'
            action: '3.12'
# Failing due to error using temporary file in a unittest. I think it's a PyPy bug, not a bitstring one!
          # - name: PyPy 3.8
            # major_dot_minor: '3.8'
            # action: 'pypy-3.8'

    steps:
      - uses: actions/checkout@v4
        with:
          path: repo

      - name: Download package files
        uses: actions/download-artifact@v4
        with:
          name: packages
          path: dist

      - uses: actions/setup-python@v5
        with:
          # This allows the matrix to specify just the major.minor version while still
          # expanding it to get the latest patch version including alpha releases.
          # This avoids the need to update for each new alpha, beta, release candidate,
          # and then finally an actual release version.  actions/setup-python doesn't
          # support this for PyPy presently so we get no help there.
          #
          # CPython -> 3.9.0-alpha - 3.9.X
          # PyPy    -> pypy-3.7
          python-version: ${{ fromJSON(format('["{0}", "{1}"]', format('{0}.0-alpha - {0}.X', matrix.python.action), matrix.python.action))[startsWith(matrix.python.action, 'pypy')] }}
          architecture: x64

      - name: Setup environment
        run: |
          python --version --version
          # make sure we test the installed code
          cp -R repo/tests/ tests/
          python -m pip install -r tests/requirements.txt
          python -m pip install ./dist/*.whl
          # show the directory contents for diagnostics
          ls -la

      - name: Run pytest
        run: |
          python -m pytest tests/ --benchmark-disable

  all:
    name: All successful
    runs-on: ubuntu-latest
    # The always() part is very important.
    # If not set, the job will be skipped on failing dependencies.
    if: always()
    needs:
      # This is the list of CI job that we are interested to be green before
      # a merge.
      - build
      - test
    steps:
      - name: Require all successes
        uses: re-actors/alls-green@v1.2.2
        with:
          jobs: ${{ toJSON(needs) }}


Mamonsu DEV

name: Mamonsu DEV

on:
  push:
    branches:
      - dev
    paths-ignore:
      - 'README.md'
      - 'documentation/**'
      - 'examples/**'
      - 'packaging/conf/**'
  pull_request:
    branches:
      - dev
    paths-ignore:
      - 'README.md'
      - 'documentation/**'
      - 'examples/**'
      - 'packaging/conf/**'

jobs:
  mamonsu-tests:
    runs-on: ubuntu-20.04
    env:
      DOCKER_COMPOSE_VERSION: '1.29.2'
      MAMONSU_PATH: '/home/runner/work/mamonsu/mamonsu/'
    strategy:
      matrix:
        docker_os: ['centos:7', 'centos:8']
        zabbix_version: ['6.2.9']
        pg_version: ['12', '13', '14', '15']
        include:
          - docker_os: 'centos:8'
            pg_version: '16'
            zabbix_version: '6.2.9'
          - docker_os: 'centos:8'
            pg_version: '16'
            zabbix_version: '6.4.13'
          - docker_os: 'ubuntu:24.04'
            pg_version: '16'
            zabbix_version: '6.4.13'
        exclude:
          - docker_os: 'centos:8'
            pg_version: '12'
          - docker_os: 'centos:8'
            pg_version: '13'
          - docker_os: 'centos:8'
            pg_version: '14'
          - docker_os: 'centos:8'
            pg_version: '15'

    steps:
      - name: Checkout mamonsu repo
        uses: actions/checkout@v1

      - name: Install docker-compose
        run: sudo apt-get update
      - run: sudo rm -f /usr/local/bin/docker-compose
      - run: curl -L https://github.com/docker/compose/releases/download/${{ env.DOCKER_COMPOSE_VERSION }}/docker-compose-`uname -s`-`uname -m` > docker-compose
      - run: chmod +x docker-compose
      - run: sudo mv docker-compose /usr/local/bin
      - name: Set up docker environment variables
        run: echo 'DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock -s devicemapper"' | sudo tee /etc/default/docker > /dev/null
      - run: sudo service docker restart
      - run: sleep 5

      - name: Install docker OS image
        run: docker pull ${{ matrix.docker_os }}
      - name: Run docker CentOS image
        if: "contains(matrix.docker_os, 'centos')"
        run: docker run -t -d --name $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) --privileged=true ${{ matrix.docker_os }} /usr/sbin/init
      - name: Run docker Ubuntu image
        if: contains(matrix.docker_os, 'ubuntu')
        run: docker run -t -d --name $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) --privileged=true ${{ matrix.docker_os }}

      - name: Install Zabbix ${{ matrix.zabbix_version }} on VM
        run: bash ./github-actions-tests/zbx_install.sh --zbx-version="${{ matrix.zabbix_version }}"
      - name: Retrieve Zabbix address
        run: |
          echo "zabbix_address=$(hostname -I | awk '{print $1}')" >> $GITHUB_OUTPUT
        id: zabbix_address
      - name: Edit Zabbix address in agent.conf
        run: sed -i "s/\(address *= *\).*/\1 ${{ steps.zabbix_address.outputs.zabbix_address }}/" ${{ env.MAMONSU_PATH }}/github-actions-tests/sources/agent_3.5.8.conf

      - name: Copy test scripts to container
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) mkdir -p -m 755 /mamonsu/
      - run: docker cp . $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ):/mamonsu
      - name: Install prerequisites
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tests.sh --os="${{ matrix.docker_os }}" --pg-version="${{ matrix.pg_version }}"

      - name: Build and install mamonsu
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/mamonsu_build.sh --os="${{ matrix.docker_os }}" --pg-version="${{ matrix.pg_version }}"

      - name: Test MAMONSU BOOTSTRAP
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/bootstrap.sh

      - name: Test MAMONSU AGENT
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/agent.sh

      - name: Test MAMONSU REPORT
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/report.sh

      - name: Test MAMONSU EXPORT
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/export.sh --pg-version="${{ matrix.pg_version }}"

      - name: Test MAMONSU ZABBIX CLI
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/zabbix_cli.sh --zbx-address="${{ steps.zabbix_address.outputs.zabbix_address }}" --zbx-version="${{ matrix.zabbix_version }}"

      - name: Test mamonsu metrics on master
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/metrics.sh --pg-version="${{ matrix.pg_version }}" --os="${{ matrix.docker_os }}"

      - name: Test Mamonsu removal
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/mamonsu_removal.sh --os="${{ matrix.docker_os }}"


Mamonsu MASTER

name: Mamonsu MASTER

on:
  push:
    branches:
      - master
    paths-ignore:
      - 'README.md'
      - 'documentation/**'
      - 'examples/**'
      - 'packaging/conf/**'
  pull_request:
    branches:
      - master
    paths-ignore:
      - 'README.md'
      - 'documentation/**'
      - 'examples/**'
      - 'packaging/conf/**'

jobs:
  mamonsu-tests:
    runs-on: ubuntu-20.04
    env:
      DOCKER_COMPOSE_VERSION: '1.29.2'
      MAMONSU_PATH: '/home/runner/work/mamonsu/mamonsu/'
    strategy:
      matrix:
        docker_os: ['ubuntu:20.04', 'centos:7', 'centos:8']
        zabbix_version: ['4.0.44', '4.4.10', '5.0.30', '5.4.12', '6.0.12', '6.2.9']
        pg_version: ['12', '13', '14', '15']
        include:
          - docker_os: 'centos:8'
            pg_version: '16'
            zabbix_version: '6.2.9'
          - docker_os: 'centos:8'
            pg_version: '16'
            zabbix_version: '6.4.13'
          - docker_os: 'ubuntu:20.04'
            pg_version: '16'
            zabbix_version: '6.4.13'
          - docker_os: 'ubuntu:20.04'
            pg_version: '15'
            zabbix_version: '6.4.13'
          - docker_os: 'ubuntu:24.04'
            pg_version: '16'
            zabbix_version: '6.4.13'
        exclude:
          # excludes PG 15, 16 on CentOS
          - docker_os: 'centos:7'
            pg_version: '15'
          - docker_os: 'centos:7'
            pg_version: '16'
          - docker_os: 'centos:8'
            pg_version: '12'
          - docker_os: 'centos:8'
            pg_version: '13'
          - docker_os: 'centos:8'
            pg_version: '14'
          - docker_os: 'centos:8'
            pg_version: '15'

    steps:
      - name: Checkout mamonsu repo
        uses: actions/checkout@v1

      - name: Install docker-compose
        run: sudo apt-get update
      - run: sudo rm -f /usr/local/bin/docker-compose
      - run: curl -L https://github.com/docker/compose/releases/download/${{ env.DOCKER_COMPOSE_VERSION }}/docker-compose-`uname -s`-`uname -m` > docker-compose
      - run: chmod +x docker-compose
      - run: sudo mv docker-compose /usr/local/bin
      - name: Set up docker environment variables
        run: echo 'DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock -s devicemapper"' | sudo tee /etc/default/docker > /dev/null
      - run: sudo service docker restart
      - run: sleep 5

      - name: Install docker OS image
        run: docker pull ${{ matrix.docker_os }}
      - name: Run docker CentOS image
        if: "contains(matrix.docker_os, 'centos')"
        run: docker run -t -d --name $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) --privileged=true ${{ matrix.docker_os }} /usr/sbin/init
      - name: Run docker Ubuntu image
        if: "contains(matrix.docker_os, 'ubuntu')"
        run: docker run -t -d --name $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) --privileged=true ${{ matrix.docker_os }}

      - name: Install Zabbix ${{ matrix.zabbix_version }} on VM
        run: bash ./github-actions-tests/zbx_install.sh --zbx-version="${{ matrix.zabbix_version }}"
      - name: Retrieve Zabbix address
        run: |
          echo "zabbix_address=$(hostname -I | awk '{print $1}')" >> $GITHUB_OUTPUT
        id: zabbix_address
      - name: Edit Zabbix address in agent.conf
        run: sed -i "s/\(address *= *\).*/\1 ${{ steps.zabbix_address.outputs.zabbix_address }}/" ${{ env.MAMONSU_PATH }}/github-actions-tests/sources/agent_3.5.8.conf

      - name: Copy test scripts to container
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) mkdir -p -m 755 /mamonsu/
      - run: docker cp . $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ):/mamonsu
      - name: Install prerequisites
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tests.sh --os="${{ matrix.docker_os }}" --pg-version="${{ matrix.pg_version }}"

      - name: Build and install mamonsu
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/mamonsu_build.sh --os="${{ matrix.docker_os }}" --pg-version="${{ matrix.pg_version }}"

      - name: Test MAMONSU BOOTSTRAP
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/bootstrap.sh

      - name: Test MAMONSU AGENT
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/agent.sh

      - name: Test MAMONSU REPORT
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/report.sh

      - name: Test MAMONSU EXPORT
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/export.sh --pg-version="${{ matrix.pg_version }}"

      - name: Test MAMONSU ZABBIX CLI
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/tools/zabbix_cli.sh --zbx-address="${{ steps.zabbix_address.outputs.zabbix_address }}" --zbx-version="${{ matrix.zabbix_version }}"

      - name: Test mamonsu metrics on master
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/metrics.sh --pg-version="${{ matrix.pg_version }}" --os="${{ matrix.docker_os }}"

      - name: Test Mamonsu removal
        run: docker exec $( echo "${{ matrix.docker_os }}" | sed 's/://' | sed 's/\.//' ) bash /mamonsu/github-actions-tests/mamonsu_removal.sh --os="${{ matrix.docker_os }}"


Daily Cron Tests

name: Daily Cron Tests

on:
  schedule:
    # run at 6am UTC on Tue-Fri (complete tests are run every Monday)
    - cron: '0 6 * * 2-5'
  pull_request:
    # We also want this workflow triggered if the 'Daily CI' label is added
    # or present when PR is updated
    types:
      - synchronize
      - labeled
  push:
    tags:
      - '*'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  TOXARGS: '-v'

permissions:
  contents: read

jobs:
  tests:
    if: (github.repository == 'astropy/regions' && (github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Daily CI')))
    name: ${{ matrix.prefix }} ${{ matrix.os }}, ${{ matrix.tox_env }}
    runs-on: ${{ matrix.os }}
    continue-on-error: ${{ matrix.allow_failure }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'linkcheck'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'py312-test-devdeps'
            toxposargs: --remote-data=any
            allow_failure: true
            prefix: '(Allowed failure)'

    steps:
    - name: Check out repository
      uses: actions/checkout@v4
      with:
        fetch-depth: 0
    - name: Set up Python ${{ matrix.python }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python }}
    - name: Install base dependencies
      run: python -m pip install --upgrade pip setuptools tox
    - name: Print Python, pip, setuptools, and tox versions
      run: |
        python -c "import sys; print(f'Python {sys.version}')"
        python -c "import pip; print(f'pip {pip.__version__}')"
        python -c "import setuptools; print(f'setuptools {setuptools.__version__}')"
        python -c "import tox; print(f'tox {tox.__version__}')"
    - name: Run tests
      run: tox -e ${{ matrix.tox_env }} -- ${{ matrix.toxposargs }}
    - name: Upload coverage to codecov
      if: ${{ contains(matrix.tox_env, '-cov') }}
      uses: codecov/codecov-action@v4
      with:
        files: ./coverage.xml
        verbose: true


Weekly Cron Tests

name: Weekly Cron Tests

on:
  schedule:
    # run every Monday at 5am UTC
    - cron: '0 5 * * 1'
  pull_request:
    # We also want this workflow triggered if the 'Weekly CI' label is added
    # or present when PR is updated
    types:
      - synchronize
      - labeled
  push:
    tags:
      - '*'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  TOXARGS: '-v'
  IS_CRON: 'true'

permissions:
  contents: read

jobs:
  tests:
    if: (github.repository == 'astropy/regions' && (github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Weekly CI')))
    name: ${{ matrix.os }}, ${{ matrix.tox_env }}
    runs-on: ${{ matrix.os }}
    continue-on-error: ${{ matrix.allow_failure }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'py312-test-alldeps-devinfra'
            allow_failure: false

    steps:
      - name: Check out repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Set up Python ${{ matrix.python }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}
      - name: Install base dependencies
        run: python -m pip install --upgrade pip setuptools tox
      - name: Print Python, pip, setuptools, and tox versions
        run: |
          python -c "import sys; print(f'Python {sys.version}')"
          python -c "import pip; print(f'pip {pip.__version__}')"
          python -c "import setuptools; print(f'setuptools {setuptools.__version__}')"
          python -c "import tox; print(f'tox {tox.__version__}')"
      - name: Run tests
        run: tox -e ${{ matrix.tox_env }} -- ${{ matrix.toxposargs }}

  test_more_architectures:
    # The following architectures are emulated and are therefore slow, so
    # we include them just in the weekly cron. These also serve as a test
    # of using system libraries and using pytest directly.

    runs-on: ubuntu-20.04
    name: More architectures
    if: (github.repository == 'astropy/regions' && (github.event_name == 'schedule' || github.event_name == 'push' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Arch CI')))
    env:
      ARCH_ON_CI: ${{ matrix.arch }}

    strategy:
      fail-fast: false
      matrix:
        include:
          - arch: aarch64
          - arch: s390x
          - arch: ppc64le
          - arch: armv7

    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: uraimo/run-on-arch-action@v2
        name: Run tests
        id: build
        with:
          arch: ${{ matrix.arch }}
          distro: ubuntu_rolling

          shell: /bin/bash
          env: |
            ARCH_ON_CI: ${{ env.ARCH_ON_CI }}
            IS_CRON: ${{ env.IS_CRON }}

          install: |
            apt-get update -q -y
            apt-get install -q -y --no-install-recommends \
                                  git \
                                  g++ \
                                  pkg-config \
                                  python3 \
                                  python3-astropy \
                                  python3-erfa \
                                  python3-extension-helpers \
                                  python3-numpy \
                                  python3-pytest-astropy \
                                  python3-setuptools-scm \
                                  python3-scipy \
                                  python3-venv \
                                  python3-wheel \
                                  wcslib-dev

          run: |
            uname -a
            echo "LONG_BIT="$(getconf LONG_BIT)
            python3 -m venv --system-site-packages tests
            source tests/bin/activate
            # cython and pyerfa versions in ubuntu repos are too old currently
            pip install -U cython
            pip install -U --no-build-isolation pyerfa
            ASTROPY_USE_SYSTEM_ALL=1 pip3 install -v --no-build-isolation -e .[test]
            pip3 list
            python3 -m pytest


CI Tests

name: CI Tests

on:
  push:
    branches:
      - main
    tags:
      - '*'
  pull_request:
  schedule:
    # run every Monday at 6am UTC
    - cron: '0 6 * * 1'
  workflow_dispatch:

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  TOXARGS: '-v'

permissions:
  contents: read

jobs:
  tests:
    name: ${{ matrix.prefix }} ${{ matrix.os }}, ${{ matrix.tox_env }}
    runs-on: ${{ matrix.os }}
    continue-on-error: ${{ matrix.allow_failure }}
    strategy:
      matrix:
        include:
          - os: ubuntu-latest
            python: '3.10'
            tox_env: 'py310-test-alldeps'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.11'
            tox_env: 'py311-test-alldeps'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'py312-test-alldeps-cov'
            toxposargs: --remote-data=any
            allow_failure: false
            prefix: ''

          - os: macos-latest
            python: '3.12'
            tox_env: 'py312-test-alldeps'
            allow_failure: false
            prefix: ''

          - os: macos-14
            python: '3.12'
            tox_env: 'py312-test-alldeps'
            allow_failure: false
            prefix: 'M1'

          - os: windows-latest
            python: '3.12'
            tox_env: 'py312-test-alldeps'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'py312-test'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'codestyle'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'pep517'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'bandit'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.10'
            tox_env: 'py310-test-oldestdeps'
            allow_failure: false
            prefix: ''

          - os: ubuntu-latest
            python: '3.12'
            tox_env: 'py312-test-devdeps'
            toxposargs: --remote-data=any
            allow_failure: true
            prefix: '(Allowed failure)'

    steps:
    - name: Check out repository
      uses: actions/checkout@v4
      with:
        fetch-depth: 0
    - name: Set up Python ${{ matrix.python }}
      uses: actions/setup-python@v5
      with:
        python-version: ${{ matrix.python }}
    - name: Install base dependencies
      run: python -m pip install --upgrade pip setuptools tox
    - name: Print Python, pip, setuptools, and tox versions
      run: |
        python -c "import sys; print(f'Python {sys.version}')"
        python -c "import pip; print(f'pip {pip.__version__}')"
        python -c "import setuptools; print(f'setuptools {setuptools.__version__}')"
        python -c "import tox; print(f'tox {tox.__version__}')"
    - name: Run tests
      run: tox -e ${{ matrix.tox_env }} -- ${{ matrix.toxposargs }}
    - name: Upload coverage to codecov
      if: ${{ contains(matrix.tox_env, '-cov') }}
      uses: codecov/codecov-action@v4
      with:
        files: ./coverage.xml
        verbose: true


CodeQL

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ "main" ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ "main" ]
  schedule:
    - cron: '33 1 * * 0'

permissions:
  contents: read

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Use only 'java' to analyze code written in Java, Kotlin or both
        # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

    steps:
    - name: Checkout repository
      uses: actions/checkout@v4

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.

        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

    # Autobuild attempts to build any compiled languages  (C/C++, C#, Go, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v2

    # ℹ Command-line programs to run using the OS shell.
    # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun

    #   If the Autobuild fails above, remove it and uncomment the following three lines.
    #   modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.

    # - run: |
    #   echo "Run, Build Application using script"
    #   ./location_of_script_within_repo/buildscript.sh

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2
      with:
        category: "/language:${{matrix.language}}"


Wheel building

name: Wheel building

on:
  schedule:
    # run every Monday at 5am UTC
    - cron: '0 5 * * 1'
  pull_request:
    # We also want this workflow triggered if the 'Build all wheels'
    # label is added or present when PR is updated
    types:
      - synchronize
      - labeled
  push:
    branches:
      - '*'
    tags:
      - '*'
      - '!*dev*'
      - '!*pre*'
      - '!*post*'
  workflow_dispatch:

permissions:
  contents: read

jobs:
  build_and_publish:
    # This job builds the wheels and publishes them to PyPI for all
    # tags, except those ending in ".dev". For PRs with the "Build all
    # wheels" label, wheels are built, but are not uploaded to PyPI.

    permissions:
      contents: none

    uses: OpenAstronomy/github-actions-workflows/.github/workflows/publish.yml@v1

    if: (github.repository == 'astropy/regions' && (github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || contains(github.event.pull_request.labels.*.name, 'Build all wheels')))
    with:
      # We upload to PyPI for all tag pushes, except tags ending in .dev
      upload_to_pypi: ${{ startsWith(github.ref, 'refs/tags/') && !endsWith(github.ref, '.dev') && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}

      test_extras: test
      test_command: pytest -p no:warnings --pyargs regions
      targets: |
        # Linux wheels
        - cp310-manylinux_x86_64
        - cp311-manylinux_x86_64
        - cp312-manylinux_x86_64

        # MacOS X wheels
        # Note that the arm64 wheels are not actually tested so we rely
        # on local manual testing of these to make sure they are ok.
        - cp310*macosx_x86_64
        - cp311*macosx_x86_64
        - cp312*macosx_x86_64

        - cp310*macosx_arm64
        - cp311*macosx_arm64
        - cp312*macosx_arm64

        # Windows wheels
        - cp310*win_amd64
        - cp311*win_amd64
        - cp312*win_amd64

    secrets:
      pypi_token: ${{ secrets.pypi_token }}


name: Pylint

on:
  push:
      branches:
     	- 'master'
  pull_request:
     branches:
       - 'master'
jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.8", "3.9", "3.10"]
    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v3
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install pylint
    - name: Analysing the code with pylint
      run: |
        pylint $(git ls-files '*.py')


Main

name: Main

on:
  push:
    branches: [main, master]
    tags: ['*']
  pull_request:
    branches: [main, master]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

env:
  RADIAN_NO_INPUTHOOK: 1

jobs:
  pytest:
    name: ${{ matrix.os }} r-${{ matrix.r }} py-${{ matrix.python }}
    strategy:
      fail-fast: false
      matrix:
        r: [4.1, latest, devel]
        python: [3.8, 3.12]
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        name: Install Python
        with:
          python-version: ${{ matrix.python }}
      - uses: r-lib/actions/setup-r@v2
        with:
          r-version: ${{ matrix.r }}
      - name: Install required R packages for testing
        run: Rscript -e "install.packages(c('reticulate', 'askpass'))"
      - name: Install and run tests
        run: |
          python -m pip install jedi
          python -m pip install -e .[test]
          pytest -s --coverage
          coverage combine
          coverage xml -i -o coverage.xml
      - name: codecov
        run: |
          python -m pip install codecov
          codecov
        env:
          CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}

  twine:
    name: Upload tarball
    if: startsWith(github.ref, 'refs/tags/')
    needs: pytest
    runs-on: ubuntu-latest
    env:
      TWINE_USERNAME: ${{secrets.TWINE_USERNAME}}
      TWINE_PASSWORD: ${{secrets.TWINE_PASSWORD}}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        name: Install Python
        with:
          python-version: 3.11
      - run: python -m pip install twine
      - run: python setup.py sdist
      - run: python -m pip install dist/*
      - run: python -m twine upload dist/*


CodeQL

# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
  push:
    branches: [ master ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ master ]
  schedule:
    - cron: '18 10 * * 0'

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'python' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
        # Learn more:
        # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v1
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # queries: ./path/to/local/query, your-org/your-repo/queries@main

    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
    # If this step fails, then you should remove it and run the build manually (see below)
    - name: Autobuild
      uses: github/codeql-action/autobuild@v1

    # ℹ Command-line programs to run using the OS shell.
    # 📚 https://git.io/JvXDl

    # ✏ If the Autobuild fails above, remove it and uncomment the following three lines
    #    and modify them (or add more) to build your code if your project
    #    uses a compiled language

    #- run: |
    #   make bootstrap
    #   make release

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v1


Integration tests

# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python

name: Integration tests

on:
  push:
    branches: [ "rc/**" ]
  pull_request:
    branches: [ "master", "rc/**" ]

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.12", "3.11", "3.10", "3.9", "3.8", "3.7"]
        neo4j-version: ["community", "enterprise", "5.5-enterprise", "4.4-enterprise", "4.4-community"]

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v4
      with:
        python-version: ${{ matrix.python-version }}
        cache: 'pip'
    - name: Creating Neo4j Container
      run: |
        chmod +x ./docker-scripts/docker-neo4j.sh
        sh ./docker-scripts/docker-neo4j.sh ${{ matrix.neo4j-version }}
        sleep 30s
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install -e '.[dev,pandas,numpy]'
    - name: Test with pytest
      env:
        AURA_TEST_DB_USER: ${{ secrets.AURA_TEST_DB_USER }}
        AURA_TEST_DB_PASSWORD: ${{ secrets.AURA_TEST_DB_PASSWORD }}
        AURA_TEST_DB_HOSTNAME: ${{ secrets.AURA_TEST_DB_HOSTNAME }}
      run: |
        pytest --cov=neomodel --cov-report=html:coverage_report
    - name: Upload coverage reports to Codecov
      uses: codecov/codecov-action@v3
      with:
        token: ${{ secrets.CODECOV_TOKEN }}  # Ensure the token is used here
        fail_ci_if_error: true  # Optional: specify if CI should fail when codecov fails


Upload Python Package

# This workflow will upload a Python Package using Twine when a release is created
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Upload Python Package

on:
  release:
    types: [published]

permissions:
  contents: read

jobs:
  deploy:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v3
    - name: Set up Python
      uses: actions/setup-python@v3
      with:
        python-version: '3.x'
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install build
    - name: Build package
      run: python -m build
    - name: Publish package
      uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29
      with:
        user: __token__
        password: ${{ secrets.PYPI_API_TOKEN }}


CI

name: CI

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:

  Test:
    strategy:
      matrix:
        os: [ubuntu-latest]
        python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ]
        include:
          - os: windows-latest
            python-version: "3.12"
          - os: macos-latest
            python-version: "3.12"

    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Run tests on ${{ matrix.os }}
        run: |
          python -m pip install --upgrade pip
          pip install -e .[dev]
          # stop the build if there are Python syntax errors or undefined names
          ruff check . --select=E9,F63,F7,F82
          pytest


Publish Python Package to PyPI

name: Publish Python Package to PyPI

on:
  release:
    types: [published]
  workflow_dispatch:

jobs:
  Publish:
    # prevents this action from running on forks
    if: github.repository == 'open2c/cooler'

    runs-on: ubuntu-latest
    permissions:
      id-token: write

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install build

      - name: Build
        run: python -m build

      - name: Publish distribution 📦 to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1


GHA CI

name: GHA CI

on:
  push:
  pull_request:
  schedule:
    - cron: "0 0 * * 0" # every Sunday at midnight
  workflow_dispatch:

jobs:
  industrial_ci:
    name: GHA CI
    runs-on: ubuntu-latest
    timeout-minutes: 60

    env:
      ADDITIONAL_DEBS: 'apt-utils dialog git'
      CATKIN_LINT: pedantic
      CATKIN_LINT_ARGS: '--ignore description_boilerplate'
      CMAKE_ARGS: -DCMAKE_BUILD_TYPE=Release
      PYLINT_ARGS: '--output-format=parseable --errors-only'
      PYLINT_CHECK: true
      ROS_REPO: main
      UPSTREAM_WORKSPACE: '.ci.rosinstall'

    strategy:
      matrix:
        include:
          - { ROS_DISTRO: noetic }

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
          lfs: true
          ssh-known-hosts: ''

      - uses: ros-industrial/industrial_ci@master
        with:
          config: ${{toJSON(matrix)}}


Release

name: Release
on:
  release:
    types: [created]

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  build_wheels:
    name: Build wheel for ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        os:
          - "ubuntu-22.04"
          - "macos-14"
    steps:
      - uses: pypa/cibuildwheel@v2.16.5
      - uses: actions/upload-artifact@v4
        with:
          name: binary-${{ matrix.os }}
          path: ./wheelhouse/*.whl
  build_sdist:
    name: Build source distribution
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
          fetch-depth: 0
      - uses: actions/setup-python@v5
        name: Install Python
        with:
          python-version: "3.10"
      - name: Install dependencies
        run: |
            python -m pip install -U pip
            python -m pip install -U build twine
      - name: Build sdist
        run: |
          python -m pip install -U pip
          python -m build --sdist .
      - uses: actions/upload-artifact@v4
        with:
          path: dist/*.tar.gz

  publish:
    environment:
      name: pypi
      url: https://pypi.org/p/fsps
    permissions:
      id-token: write
    needs: [build_wheels, build_sdist]
    runs-on: ubuntu-latest
    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
    steps:
      - uses: actions/download-artifact@v4
        with:
          path: dist
          merge-multiple: true
      - uses: pypa/gh-action-pypi-publish@v1.8.12


Tests

name: Tests
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  tests:
    name: "py${{ matrix.python-version }} / ${{ matrix.os }}"
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        python-version: ["3.9", "3.10"]
        os: [ubuntu-latest, macos-latest]
    steps:
      - name: Clone the repo
        uses: actions/checkout@v4
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python-version }}
      - name: Clone fsps
        uses: actions/checkout@v4
        with:
          repository: cconroy20/fsps
          path: fsps
      - name: Install dependencies
        run: |
          python -m pip install -U pip pytest
          python -m pip install -U fsps astro-sedpy astropy
          python -m pip install -U scipy
          python -m pip install -U dynesty
          python -m pip install .
        env:
          SPS_HOME: ${{ github.workspace }}/fsps
      - name: Run tests
        run: python -m pytest --durations=0 --maxfail=1 -vs tests/
        env:
          SPS_HOME: ${{ github.workspace }}/fsps


GHA CI

name: GHA CI

on:
  push:
  pull_request:
  schedule:
    - cron: "0 0 * * 0" # every Sunday at midnight
  workflow_dispatch:

jobs:
  industrial_ci:
    name: GHA CI
    runs-on: ubuntu-latest
    timeout-minutes: 60

    env:
      ADDITIONAL_DEBS: 'apt-utils dialog git'
      CATKIN_LINT: pedantic
      CATKIN_LINT_ARGS: '--ignore description_boilerplate --ignore wrong_bin_install_destination'
      CMAKE_ARGS: -DCMAKE_BUILD_TYPE=Release
      PYLINT_ARGS: '--output-format=parseable --errors-only'
      PYLINT_CHECK: true
      ROS_REPO: main
      UPSTREAM_WORKSPACE: '.ci.rosinstall'

    strategy:
      matrix:
        include:
          - { ROS_DISTRO: noetic }

    steps:
      - uses: actions/checkout@v4
        with:
          submodules: true
          lfs: true
          ssh-known-hosts: ''

      - uses: ros-industrial/industrial_ci@master
        with:
          config: ${{toJSON(matrix)}}


Glider Plugin Tests

name: Glider Plugin Tests

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -v -e . --no-deps --force-reinstall

    - name: cc-plugin-glider tests
      shell: bash -l {0}
      run: >
        git clone https://github.com/ioos/cc-plugin-glider.git
        && cd cc-plugin-glider
        && micromamba install --file requirements.txt --file requirements-dev.txt --channel conda-forge
        && micromamba remove compliance-checker --no-prune --force
        && python -m pip install -e . --no-deps --force-reinstall
        && python -m pytest -s -rxs -v cc_plugin_glider


NCEI Plugin Tests

name: NCEI Plugin Tests

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: cc-plugin-ncei tests
      shell: bash -l {0}
      run: >
        git clone https://github.com/ioos/cc-plugin-ncei.git
        && cd cc-plugin-ncei
        && micromamba install --file requirements.txt --file requirements-dev.txt --channel conda-forge
        && micromamba remove compliance-checker --no-prune --force
        && python -m pip install -e . --no-deps --force-reinstall
        && python -m pytest -s -rxs -v cc_plugin_ncei


OG Plugin Tests

name: OG Plugin Tests

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: cc-plugin-og tests
      shell: bash -l {0}
      run: >
        git clone https://github.com/uw-farlab/cc-plugin-og.git
        && cd cc-plugin-og
        && micromamba install --file requirements.txt --channel conda-forge
        && micromamba remove compliance-checker --no-prune --force
        && python -m pip install -e . --no-deps --force-reinstall
        && python -m pytest -s -rxs -v cc_plugin_og


SGRID Plugin Tests

name: SGRID Plugin Tests

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: cc-plugin-sgrid tests
      shell: bash -l {0}
      run: >
        git clone https://github.com/ioos/cc-plugin-sgrid.git
        && cd cc-plugin-sgrid
        && micromamba install --file requirements.txt --file requirements-dev.txt --channel conda-forge
        && micromamba remove compliance-checker --no-prune --force
        && python -m pip install -e . --no-deps --force-reinstall
        && python -m pytest -s -rxs -v cc_plugin_sgrid


UGRID Plugin Tests

name: UGRID Plugin Tests

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: cc-plugin-ugrid tests
      shell: bash -l {0}
      run: >
        git clone https://github.com/ioos/cc-checker-ugrid.git
        && cd cc-checker-ugrid
        && micromamba install --file requirements.txt --file requirements-dev.txt --channel conda-forge
        && micromamba remove compliance-checker --no-prune --force
        && python -m pip install -e . --no-deps --force-reinstall
        && python -m pytest -s -rxs -v cc_plugin_ugrid


Code coverage report

name: Code coverage report

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: Run tests with coverage
      shell: bash -l {0}
      run: |
        python -m pytest --cov=compliance_checker --cov-report=xml compliance_checker/tests
      # pass this step even if there are individual test failures, we are
      # interested in the overall level of coverage and other checks can
      # report on test failures.
      continue-on-error: true

    - name: Upload to codecov
      uses: codecov/codecov-action@v4
      with:
        files: coverage.xml


Default Tests

name: Default Tests

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ]
        os: [windows-latest, ubuntu-latest, macos-latest]
      fail-fast: false
    defaults:
      run:
        shell: bash -l {0}

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba ${{ matrix.python-version }}
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=${{ matrix.python-version }} pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: Default Tests
      run: python -m pytest -s -rxs -v -k "not integration" compliance_checker


Documentation

name: Documentation

on:
  pull_request:
  push:
  release:
    types:
      - published

jobs:
  build-docs:
    runs-on: ubuntu-latest

    steps:
    - name: checkout
      uses: actions/checkout@v4
      with:
        fetch-depth: 0

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: Build documentation
      shell: bash -l {0}
      run: |
        set -e
        pushd docs
        cp  ../README.md source/quickintro.md
        make clean html linkcheck
        popd

    - name: Deploy
      if: success() && github.event_name == 'release'
      uses: peaceiris/actions-gh-pages@v4
      with:
        github_token: ${{ secrets.GITHUB_TOKEN }}
        publish_dir: docs/build/html


Integration Tests

name: Integration Tests

on:
  pull_request:
  push:

jobs:
  run:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Micromamba
      uses: mamba-org/setup-micromamba@v1
      with:
        environment-name: TEST
        init-shell: bash
        create-args: >-
          python=3 pip
          --file requirements.txt
          --file test_requirements.txt
          --channel conda-forge

    - name: Install compliance-checker
      shell: bash -l {0}
      run: |
        python -m pip install -e . --no-deps --force-reinstall

    - name: Integration Tests
      shell: bash -l {0}
      run: python -m pytest -m "integration" -s -rxs -v --vcr-record=none compliance_checker


Publish to PyPI

name: Publish to PyPI

on:
  pull_request:
  push:
  release:
    types:
      - published

defaults:
  run:
    shell: bash

jobs:
  packages:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        # Should be enough for setuptools-scm
        fetch-depth: 100
        persist-credentials: false

    - name: Get tags
      run: git fetch origin 'refs/tags/*:refs/tags/*'

    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: "3.11"

    - name: Install build tools
      run: |
        python -m pip install --upgrade pip build twine

    - name: Build binary wheel
      run: python -m build --sdist --wheel . --outdir dist

    - name: CheckFiles
      run: |
        ls -lh dist

    - name: Test wheels
      run: |
        cd dist && python -m pip install compliance_checker*.whl
        python -m twine check *

    - name: Publish a Python distribution to PyPI
      if: success() && github.event_name == 'release'
      uses: pypa/gh-action-pypi-publish@release/v1
      with:
        user: __token__
        password: ${{ secrets.PYPI_ACCESS_TOKEN }}


Adds all new issues to project board

name: Adds all new issues to project board

on:
  issues:
    types:
      - opened

jobs:
  add-to-project:
    name: Add issue to perfSONAR project
    runs-on: ubuntu-latest
    steps:
      # NOTE: "uses" cannot be a variable so name and version hard-coded here
      - uses: actions/add-to-project@v0.5.0
        with:
          project-url: ${{ vars.PROJECT_PS_URL }}
          github-token: ${{ secrets.PAT_PROJECT_PS_AUTO_ADD }}


brightwind

name: brightwind

on:
  # Triggers the workflow on pull request events but only for the "main" branch
  # push events are only possible via pull_request!
  pull_request:
    branches: [ "master" ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]

    steps:
      - uses: actions/checkout@v3
      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v4
        with:
          python-version: ${{ matrix.python-version }}
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
      - name: Test with pytest
        run: |
          pytest


Lint

name: Lint

on: [pull_request]

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: actions/setup-python@v2
      - uses: psf/black@stable
        with:
            options: "--check --diff --color --verbose"
            jupyter: true


Upload Python Package

# This workflows will upload a Python Package using Twine when a release is created
# For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries

name: Upload Python Package

on:
  release:
    types: [created]

jobs:
  deploy:
    runs-on: ubuntu-latest
    name: upload release to PyPI
    permissions:
      id-token: write  # IMPORTANT: this permission is mandatory for trusted publishing
    steps:
      - uses: actions/checkout@v4
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.x"
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install setuptools wheel twine
      - name: Build and publish
        run: |
          python setup.py sdist bdist_wheel
      - name: Publish package distributions to PyPI
        uses: pypa/gh-action-pypi-publish@release/v1


Run pytests

name: Run pytests

on:
  pull_request:
    branches: [master, dev]

jobs:
  pytest:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        python-version: ["3.8", "3.11"]
        os: [ubuntu-latest]

    steps:
      - uses: actions/checkout@v2

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install test dependencies
        run: if [ -f requirements/requirements-test.txt ]; then pip install -r requirements/requirements-test.txt; fi

      - name: Install package
        run: python -m pip install .

      - name: Run pytest tests
        run: pytest tests -x -vv --remote-data


name: Build wheel, release and publish on new tag

on: [push, pull_request]

jobs:
  build:

    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: [3.8, 3.9, 3.10.9, 3.11, 3.12]

    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0  # Optional, use if you use setuptools_scm
        submodules: false  # Optional, use if you have submodules
      name: Check out repo
    - name: Set up Python ${{ matrix.python-version }}
      uses: actions/setup-python@v3
      with:
        python-version: ${{ matrix.python-version }}
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install wheel
        pip install .[test] --use-pep517
    - name: Test with pytest
      run: |
        pytest
    - name: Build wheel
      run: |
        python -m pip install --upgrade pip
        pip wheel . -w dist --no-deps --use-pep517

    - uses: actions/upload-artifact@v3
      name: Upload wheel as artifact
      with:
        name: wheels
        path: |
          ./dist/*.whl

  make_sdist:
    name: Make SDist
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
      with:
        fetch-depth: 0  # Optional, use if you use setuptools_scm
        submodules: true  # Optional, use if you have submodules

    - name: Build SDist
      run: pipx run build --sdist

    - uses: actions/upload-artifact@v3
      with:
        path: dist/*.tar.gz

  release_artifacts:
    if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')
    name: Release repaired and tested wheels
    needs: build
    runs-on: ubuntu-latest
    environment: release
    permissions:
      # IMPORTANT: this permission is mandatory for trusted publishing
      id-token: write
      contents: write

    steps:
    - uses: actions/checkout@v4

    - name: Download compressed artifacts
      id: download
      uses: actions/download-artifact@v3
      with:
        path: ./artifacts

    - name: 'List downloaded files'
      run: ls ${{ steps.download.outputs.download-path }}/**/*.*

    - name: Create release and upload wheels
      uses: ncipollo/release-action@v1
      with:
        allowUpdates: true
        artifacts: "${{ steps.download.outputs.download-path }}/**/*.whl,${{ steps.download.outputs.download-path }}/**/*.gz,${{ steps.download.outputs.download-path }}/**/*.so,${{ steps.download.outputs.download-path }}/**/*.dylib,${{ steps.download.outputs.download-path }}/**/*.lib,${{ steps.download.outputs.download-path }}/**/*.dll"
        token: ${{ secrets.GITHUB_TOKEN }}

    - name: PyPI Publish
      uses: pypa/gh-action-pypi-publish@v1.9.0
      with:
        packages-dir: ${{ steps.download.outputs.download-path }}/**/


ci-docker

name: ci-docker
on:
  schedule:
    - cron: "30 6 * * *"
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'
  workflow_dispatch:

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v4
      -
        name: Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: antsx/antspy
      -
        name: Login to DockerHub
        if: ${{ github.repository == 'ANTsX/ANTsPy' }}
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      -
        name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      -
        name: Set up Docker Buildx
        id: buildx
        uses: docker/setup-buildx-action@v3
      -
        name: Build and push
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64
          push: ${{ github.repository == 'ANTsX/ANTsPy' && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')) }}
          tags: ${{ github.event_name == 'schedule' && 'antsx/antspy:nightly,antsx/antspy:latest' || steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}