diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index 4de5b77..595d471 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -1,30 +1,67 @@ +# Reference: +# - https://github.com/actions/checkout +# - https://github.com/awalsh128/cache-apt-pkgs-action +# - https://github.com/prefix-dev/setup-pixi + name: ci-docs on: - push: - branches: - - "*" pull_request: + + push: branches: - "*" + workflow_dispatch: + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: - build: + tests: + name: "${{ matrix.session }} (${{ matrix.version }})" + runs-on: "${{ matrix.os }}" + + defaults: + run: + shell: bash -l {0} + + env: + ENV_NAME: "ci-docs" - runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + os: ["ubuntu-latest"] + version: ["py311"] + session: ["doctest"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: "environment configure" + env: + # Maximum cache period (in weeks) before forcing a cache refresh. + CACHE_WEEKS: 2 + run: | + echo "CACHE_PERIOD=$(date +%Y).$(expr $(date +%U) / ${CACHE_WEEKS})" >> ${GITHUB_ENV} + + - name: "apt cache" + uses: awalsh128/cache-apt-pkgs-action@7ca5f46d061ad9aa95863cd9b214dd48edef361d + with: + packages: libgl1-mesa-glx xvfb + version: 1.0 - - uses: actions/cache@v4 - with: - key: tox-${{ hashFiles('requirements/dev.yml') }}-${{ hashFiles('tox.ini') }} - path: | - .tox + - name: "setup pixi" + uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da + with: + environments: "docs-${{ matrix.version }}" + frozen: true + activate-environment: true - - name: Run tox - run: pipx run 'tox<4' -e doctests + - name: "${{ matrix.session }} (${{ matrix.version }})" + run: | + pixi run --frozen make ${{ matrix.session }} \ No newline at end of file diff --git a/.github/workflows/stale.yml b/.github/workflows/ci-stale.yml similarity index 99% rename from .github/workflows/stale.yml rename to .github/workflows/ci-stale.yml index d266bee..869d1f2 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/ci-stale.yml @@ -7,7 +7,7 @@ on: env: # 6 months - DAYS_BEFORE_STALE: 168 + DAYS_BEFORE_STALE: 182 # 1 month DAYS_BEFORE_CLOSE: 28 @@ -29,6 +29,7 @@ jobs: In order to maintain a backlog of relevant issues, we automatically label them as stale after ${{ env.DAYS_BEFORE_STALE }} days of inactivity. If this issue is still important to you, then please comment on this issue and the stale label will be removed. Otherwise this issue will be automatically closed in ${{ env.DAYS_BEFORE_CLOSE }} days time. + stale-pr-message: | In order to maintain a backlog of relevant PRs, we automatically label them as stale after ${{ env.DAYS_BEFORE_STALE }} days of inactivity. If this PR is still important to you, then please comment on this PR and the stale label will be removed. @@ -40,6 +41,7 @@ jobs: If you still care about this issue, then please either: * Re-open this issue, if you have sufficient permissions, or * Add a comment pinging `@SciTools/tephi-maintainers` who will re-open on your behalf. + close-pr-message: | This stale PR has been automatically closed due to a lack of community activity. @@ -56,7 +58,6 @@ jobs: # Exempt all issues/prs with milestones from stale. exempt-all-milestones: true - remove-stale-when-updated: true # Max number of operations per run. diff --git a/.github/workflows/ci-tests.yml b/.github/workflows/ci-tests.yml index c75a0a6..de52232 100644 --- a/.github/workflows/ci-tests.yml +++ b/.github/workflows/ci-tests.yml @@ -1,43 +1,125 @@ +# Reference: +# - https://github.com/actions/checkout +# - https://github.com/actions/download-artifact +# - https://github.com/actions/setup-python +# - https://github.com/actions/upload-artifact +# - https://github.com/awalsh128/cache-apt-pkgs-action +# - https://github.com/codecov/codecov-action +# - https://github.com/prefix-dev/setup-pixi + name: ci-tests on: - push: - branches: - - "*" pull_request: - branches: - - "*" + push: + concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true +defaults: + run: + shell: bash -l {0} + jobs: tests: name: "${{ matrix.session }} (${{ matrix.version }})" + runs-on: "${{ matrix.os }}" - runs-on: ${{ matrix.os }} + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + ENV_NAME: "ci-tests" strategy: fail-fast: false matrix: - os: [ "ubuntu-latest" ] + os: ["ubuntu-22.04"] version: ["py310", "py311"] - session: [ "test" ] + session: ["tests"] include: - version: "py311" - coverage: "--cov-report= --cov=tephi" + coverage: "--cov-report= --cov=geovista" steps: - - uses: actions/checkout@v4 - - - uses: actions/cache@v4 - with: - key: tox-${{ hashFiles('requirements/dev.yml') }}-${{ hashFiles('tox.ini') }} - path: | - .tox - - - name: Run tox - run: | - pip install 'tox<4' - tox -e ${{ matrix.version }}-${{ matrix.session }} + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: "environment configure" + env: + # Maximum cache period (in weeks) before forcing a cache refresh. + CACHE_WEEKS: 2 + run: | + echo "CACHE_PERIOD=$(date +%Y).$(expr $(date +%U) / ${CACHE_WEEKS})" >> ${GITHUB_ENV} + + - name: "apt cache" + uses: awalsh128/cache-apt-pkgs-action@7ca5f46d061ad9aa95863cd9b214dd48edef361d + with: + packages: libgl1-mesa-glx xvfb + version: 1.0 + + - name: "setup pixi" + uses: prefix-dev/setup-pixi@19eac09b398e3d0c747adc7921926a6d802df4da + with: + environments: "test-${{ matrix.version }}" + frozen: true + activate-environment: true + + - name: "${{ matrix.session }} (${{ matrix.version }})" + env: + PY_COLORS: "1" + run: | + pixi run --frozen pytest -m ${{ matrix.posargs }} ${{ matrix.coverage }} + + - name: "upload test images" + if: ${{ failure() }} + uses: actions/upload-artifact@v4 + with: + name: test-images-${{ github.job }}-${{ strategy.job-index }} + path: ${{ github.workspace }}/test_images + + - name: "prepare coverage" + if: ${{ matrix.coverage }} + run: | + mv .coverage ci-test-coverage${{ strategy.job-index }} + + - if: ${{ matrix.coverage }} + uses: actions/upload-artifact@v4 + with: + name: coverage-artifacts-${{ github.job }}-${{ strategy.job-index }} + path: ${{ github.workspace }}/ci-test-coverage* + + + coverage: + needs: [tests] + name: "upload coverage" + runs-on: "ubuntu-latest" + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - run: | + python -m pip install --upgrade pip + pip install coverage + + - uses: actions/download-artifact@v4 + with: + pattern: coverage-artifacts-* + merge-multiple: true + + - name: "create coverage report" + run: | + coverage combine ci-test-coverage* + coverage xml --omit=*/_version.py + + - name: "upload coverage report" + uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 + with: + token: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fb909e5..9778ac6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -197,3 +197,132 @@ tephi = [ [tool.setuptools.packages.find] include = ["tephi*"] + +[tool.pixi.workspace] +channels = ["conda-forge"] +platforms = ["linux-64"] + +[tool.pixi.environments] +default = { features = [], solve-group = "default" } +devs = { features = ["devs"], solve-group = "default" } +docs = { features = ["devs", "docs"], solve-group = "default" } +geovista = { features = ["devs", "docs", "test"], solve-group = "default" } +test = { features = ["devs", "test"], solve-group = "default" } + +devs-py310 = { features = ["devs", "py310"], solve-group = "py310" } +docs-py310 = { features = ["devs", "docs", "py310"], solve-group = "py310" } +tephi-py310 = { features = [ + "devs", + "docs", + "py310", + "test", +], solve-group = "py310" } +py310 = { features = ["py310"], solve-group = "py310" } +test-py310 = { features = ["devs", "py310", "test"], solve-group = "py310" } +devs-py311 = { features = ["devs", "py311"], solve-group = "py311" } +docs-py311 = { features = ["devs", "docs", "py311"], solve-group = "py311" } +tephi-py311 = { features = [ + "devs", + "docs", + "py311", + "test", +], solve-group = "py311" } +py311 = { features = ["py311"], solve-group = "py311" } +test-py311 = { features = ["devs", "py311", "test"], solve-group = "py311" } + +[tool.pixi.dependencies] +cartopy = ">=0.24.0,<0.25" +click = ">=8.2.1,<9" +click-default-group = ">=1.2.4,<2" +cmocean = ">=4.0.3,<5" +colorcet = ">=3.1.0,<4" +lazy_loader = ">=0.4,<0.5" +netcdf4 = ">=1.7.2,<2" +numpy = ">=2.2.6,<3" +platformdirs = ">=4.3.8,<5" +pykdtree = ">=1.4.1,<2" +pyproj = ">=3.7.1,<4" +setuptools = ">=80.9.0,<81" +setuptools-scm = ">=8.3.1,<9" + +[tool.pixi.feature.devs.dependencies] +fastparquet = ">=2024.11.0,<2025" +h3-py = ">=4.2.2,<5" +pandas = ">=2.2.3,<3" +pre-commit = ">=4.2.0,<5" +rasterio = ">=1.4.3,<2" +ruff = ">=0.12.0,<0.13" +zizmor = ">=1.9.0,<2" + +[tool.pixi.feature.devs.pypi-dependencies] +tephi = { path = ".", editable = true } + +[tool.pixi.feature.devs.tasks] +fmt = "ruff format" +lint = "ruff check" + +[tool.pixi.feature.docs.dependencies] +ipykernel = ">=6.29.5,<7" +ipywidgets = ">=8.1.7,<9" +joblib = ">=1.5.1,<2" +jupyter-server-proxy = ">=4.4.0,<5" +myst-nb = ">=1.2.0,<2" +nest-asyncio = ">=1.6.0,<2" +numpydoc = ">=1.8.0,<2" +sphinx = ">=8.2.3,<9" +sphinx-autoapi = ">=3.5.0,<4" +sphinx-book-theme = ">=1.1.3,<2" +sphinx-click = ">=6.0.0,<7" +sphinx-copybutton = ">=0.5.2,<0.6" +sphinx-design = ">=0.6.1,<0.7" +sphinx-gallery = ">=0.19.0,<0.20" +sphinx-tags = ">=0.4,<0.5" +sphinx-togglebutton = ">=0.3.2,<0.4" +sphinx_changelog = ">=1.6.0,<2" + +[tool.pixi.feature.docs.pypi-dependencies] +sphinx-tippy = ">=0.4.3,<0.5" + +[tool.pixi.feature.docs.tasks.clean] +cmd = "make clean" +cwd = "docs" + +[tool.pixi.feature.docs.tasks.clean-all] +cmd = "make clean-all" +cwd = "docs" +depends-on = [{ "task" = "clean" }, { "task" = "clean-cache" }] + +[tool.pixi.feature.docs.tasks.clean-cache] +cmd = "make clean-cache" +cwd = "docs" + +[tool.pixi.feature.docs.tasks.doctest] +cmd = "make doctest" +cwd = "docs" +depends-on = [{ "task" = "clean" }] + +[tool.pixi.feature.docs.tasks.make] +args = [{ "arg" = "option", "default" = "html-noplot" }] +cmd = "make {{ option }}" +cwd = "docs" +depends-on = [{ "task" = "clean" }] + +[tool.pixi.feature.docs.tasks.serve-html] +args = [{ "arg" = "option", "default" = "html-noplot" }] +cmd = "make serve-html" +cwd = "docs" +depends-on = [{ "task" = "make", "args" = ["{{ option }}"] }] + +[tool.pixi.feature.py310.dependencies] +pip = ">=25.1.1,<26" +python = "3.10.*" + +[tool.pixi.feature.py311.dependencies] +pip = ">=25.1.1,<26" +python = "3.11.*" + +[tool.pixi.feature.test.dependencies] +codecov = ">=2.1.13,<3" +pytest = ">=8.4.0,<9" +pytest-cov = ">=6.1.1,<7" +pytest-mock = ">=3.14.1,<4"