Skip to content

Commit 7204e25

Browse files
Merge pull request #219 from VeckoTheGecko/pixi-for-edito
2 parents 30b32e4 + 31c7bbb commit 7204e25

File tree

11 files changed

+253
-103
lines changed

11 files changed

+253
-103
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Adapted from https://raw.githubusercontent.com/Parcels-code/Parcels/58cdd6185b3af03785c567914a070288ffd804e0/.github/workflows/cache-pixi-lock.yml
2+
name: Generate and cache Pixi lockfile
3+
4+
on:
5+
workflow_call:
6+
outputs:
7+
cache-id:
8+
description: "The lock file contents"
9+
value: ${{ jobs.cache-pixi-lock.outputs.cache-id }}
10+
11+
jobs:
12+
cache-pixi-lock:
13+
name: Generate output
14+
runs-on: ubuntu-latest
15+
outputs:
16+
cache-id: ${{ steps.restore.outputs.cache-primary-key }}
17+
steps:
18+
- uses: actions/checkout@v5
19+
with:
20+
fetch-depth: 0
21+
submodules: recursive
22+
- name: Get current date
23+
id: date
24+
run: echo "date=$(date +'%Y-%m-%d')" >> "$GITHUB_OUTPUT"
25+
- uses: actions/cache/restore@v4
26+
id: restore
27+
with:
28+
path: |
29+
pixi.lock
30+
key: ${{ steps.date.outputs.date }}_${{hashFiles('pixi.toml')}}
31+
- uses: prefix-dev/[email protected]
32+
if: ${{ !steps.restore.outputs.cache-hit }}
33+
with:
34+
pixi-version: v0.56.0
35+
run-install: false
36+
- name: Run pixi lock
37+
if: ${{ !steps.restore.outputs.cache-hit }}
38+
run: pixi lock
39+
- uses: actions/cache/save@v4
40+
if: ${{ !steps.restore.outputs.cache-hit }}
41+
id: cache
42+
with:
43+
path: |
44+
pixi.lock
45+
key: ${{ steps.restore.outputs.cache-primary-key }}
46+
- name: Upload pixi.lock
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: pixi-lock
50+
path: pixi.lock

.github/workflows/ci.yml

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,56 +21,61 @@ env:
2121
FORCE_COLOR: 3
2222

2323
jobs:
24+
cache-pixi-lock:
25+
uses: ./.github/workflows/cache-pixi-lock.yml
26+
2427
tests:
25-
name: tests (${{ matrix.runs-on }} | Python ${{ matrix.python-version }})
28+
name: "Unit tests: ${{ matrix.runs-on }} | pixi run -e ${{ matrix.pixi-environment }} tests"
2629
runs-on: ${{ matrix.runs-on }}
30+
needs: cache-pixi-lock
2731
strategy:
2832
fail-fast: false
2933
matrix:
30-
python-version: ["3.10", "3.12"]
34+
pixi-environment: ["test-py310", "test-py312"]
3135
runs-on: [ubuntu-latest, windows-latest, macos-14]
3236

3337
steps:
3438
- uses: actions/checkout@v4
3539
with:
3640
fetch-depth: 0
37-
- uses: mamba-org/setup-micromamba@v2
41+
submodules: recursive
42+
- uses: actions/cache/restore@v4
3843
with:
39-
environment-name: ship
40-
environment-file: environment.yml
41-
create-args: >-
42-
python=${{matrix.python-version}}
43-
44-
- run: pip install . --no-deps
44+
path: pixi.lock
45+
key: ${{ needs.cache-pixi-lock.outputs.cache-id }}
46+
- uses: prefix-dev/[email protected]
47+
with:
48+
cache: true
49+
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
4550

4651
- name: Test package
47-
run: >-
48-
python -m pytest -ra --cov --cov-report=xml --cov-report=term
52+
run:
53+
pixi run -e ${{ matrix.pixi-environment }} tests -ra --cov --cov-report=xml --cov-report=term
4954
--durations=20
5055

5156
- name: Upload coverage report
5257
uses: codecov/[email protected]
5358
with:
5459
token: ${{ secrets.CODECOV_TOKEN }}
5560
typechecking:
56-
name: mypy
61+
name: "TypeChecking: pixi run typing"
5762
runs-on: ubuntu-latest
63+
needs: cache-pixi-lock
5864
steps:
5965
- uses: actions/checkout@v4
6066
with:
6167
fetch-depth: 0
62-
- uses: mamba-org/setup-micromamba@v2
68+
submodules: recursive
69+
- uses: actions/cache/restore@v4
6370
with:
64-
environment-name: ship
65-
environment-file: environment.yml
66-
create-args: >-
67-
python=3.12
68-
69-
- run: pip install . --no-deps
70-
- run: conda install lxml # dep for report generation
71+
path: pixi.lock
72+
key: ${{ needs.cache-pixi-lock.outputs.cache-id }}
73+
- uses: prefix-dev/[email protected]
74+
with:
75+
cache: true
76+
cache-write: ${{ github.event_name == 'push' && github.ref_name == 'main' }}
7177
- name: Typechecking
72-
run: |
73-
mypy --install-types --non-interactive src/virtualship --html-report mypy-report
78+
run: pixi run typing --non-interactive --html-report mypy-report
7479
- name: Upload test results
7580
if: ${{ always() }} # Upload even on mypy error
7681
uses: actions/upload-artifact@v4

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,9 @@ src/virtualship/_version_setup.py
178178

179179
.vscode/
180180
.DS_Store
181+
182+
# Ignore pixi.lock file for this project. The con of 22k lines of noise it adds to diffs is not worth
183+
# the minor benefit of perfectly reproducible environments for all developers (and all the tooling that would
184+
# be required to support that - see https://github.com/pydata/xarray/issues/10732#issuecomment-3327780806
185+
# for more details)
186+
pixi.lock

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "Parcels"]
2+
path = Parcels
3+
url = [email protected]:Parcels-code/Parcels.git

.readthedocs.yaml

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
# Read the Docs configuration file
2-
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3-
41
version: 2
5-
sphinx:
6-
configuration: docs/conf.py
72
build:
8-
os: ubuntu-22.04
3+
os: ubuntu-lts-latest
94
tools:
10-
python: mambaforge-22.9
5+
python: "latest" # just so RTD stops complaining
116
jobs:
12-
pre_build:
13-
- pip install .
14-
- sphinx-build -b linkcheck docs/ _build/linkcheck
15-
- sphinx-apidoc -o docs/api/ --module-first --no-toc --force src/virtualship
16-
17-
conda:
18-
environment: environment.yml
7+
create_environment:
8+
- asdf plugin add pixi
9+
- asdf install pixi latest
10+
- asdf global pixi latest
11+
install:
12+
- pixi install -e docs
13+
build:
14+
html:
15+
- pixi run -e docs sphinx-build -T -b html docs $READTHEDOCS_OUTPUT/html
16+
sphinx:
17+
configuration: docs/conf.py

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
<!-- Badges -->
99

10+
[![Pixi Badge](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/prefix-dev/pixi/main/assets/badge/v0.json)](https://pixi.sh)
1011
[![Anaconda-release](https://anaconda.org/conda-forge/virtualship/badges/version.svg)](https://anaconda.org/conda-forge/virtualship/)
1112
![PyPI - Python Version](https://img.shields.io/pypi/pyversions/virtualship)
1213
[![DOI](https://zenodo.org/badge/682478059.svg)](https://doi.org/10.5281/zenodo.14013931)

docs/contributing/index.md

Lines changed: 60 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,75 @@ We have a design document providing a conceptual overview of VirtualShip. This d
88

99
### Development installation
1010

11-
We use `conda` to manage our development installation. Make sure you have `conda` installed by following [the instructions here](https://docs.conda.io/projects/conda/en/latest/user-guide/install/index.html) and then run the following commands:
11+
```{note}
12+
VirtualShip uses [Pixi](https://pixi.sh) to manage environments and run developer tooling. Pixi is a modern alternative to Conda and also includes other powerful tooling useful for a project like VirtualShip. It is our sole development workflow - we do not offer a Conda development workflow. Give Pixi a try, you won't regret it!
13+
```
14+
15+
To get started contributing to VirtualShip:
16+
17+
**Step 1:** [Install Pixi](https://pixi.sh/latest/).
18+
19+
**Step 2:** [Fork the repository](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo#forking-a-repository)
20+
21+
**Step 3:** Clone your fork with submodules and `cd` into the repository.
22+
23+
```bash
24+
git clone --recurse-submodules [email protected]:YOUR_USERNAME/virtualship.git
25+
cd virtualship
26+
```
27+
28+
```{note}
29+
The `--recurse-submodules` flag is required to clone the Parcels submodule, which is used for testing and development.
30+
```
31+
32+
**Step 4:** Install the Pixi environment
1233

1334
```bash
14-
conda create -n ship python=3.10
15-
conda activate ship
16-
conda env update --file environment.yml
17-
pip install -e . --no-deps --no-build-isolation
35+
pixi install
1836
```
1937

20-
This creates an environment, and installs all the dependencies that you need for development, including:
38+
Now you have a development installation of VirtualShip, as well as a bunch of developer tooling to run tests, check code quality, and build the documentation! Simple as that.
2139

22-
- core dependencies
23-
- development dependencies (e.g., for testing)
24-
- documentation dependencies
40+
### Pixi workflows
2541

26-
then installs the package in editable mode.
42+
You can use the following Pixi commands to run common development tasks.
2743

28-
### Useful commands
44+
**Testing**
2945

30-
The following commands are useful for local development:
46+
- `pixi run tests` - Run the full test suite using pytest with coverage reporting
47+
- `pixi run tests-notebooks` - Run notebook tests
3148

32-
- `pytest` to run tests
33-
- `pre-commit run --all-files` to run pre-commit checks
34-
- `pre-commit install` (optional) to install pre-commit hooks
35-
- this means that every time you commit, pre-commit checks will run on the files you changed
36-
- `sphinx-autobuild docs docs/_build` to build and serve the documentation
37-
- `sphinx-apidoc -o docs/api/ --module-first --no-toc --force src/virtualship` (optional) to generate the API documentation
38-
- `sphinx-build -b linkcheck docs/ _build/linkcheck` to check for broken links in the documentation
49+
**Documentation**
3950

40-
The running of these commands is useful for local development and quick iteration, but not _vital_ as they will be run automatically in the CI pipeline (`pre-commit` by pre-commit.ci, `pytest` by GitHub Actions, and `sphinx` by ReadTheDocs).
51+
- `pixi run docs` - Build the documentation using Sphinx
52+
- `pixi run docs-watch` - Build and auto-rebuild documentation when files change (useful for live editing)
53+
54+
**Code quality**
55+
56+
- `pixi run lint` - Run pre-commit hooks on all files (includes formatting, linting, and other code quality checks)
57+
- `pixi run typing` - Run mypy type checking on the codebase
58+
59+
**Different environments**
60+
61+
VirtualShip supports testing against different environments (e.g., different Python versions) with different feature sets. In CI we test against these environments, and you can too locally. For example:
62+
63+
- `pixi run -e test-py311 tests` - Run tests using Python 3.11
64+
- `pixi run -e test-py312 tests` - Run tests using Python 3.12
65+
- `pixi run -e test-latest tests` - Run tests using latest Python
66+
67+
The name of the workflow on GitHub contains the command you have to run locally to recreate the workflow - making it super easy to reproduce CI failures locally.
68+
69+
**Typical development workflow**
70+
71+
1. Make your code changes
72+
2. Run `pixi run lint` to ensure code formatting and style compliance
73+
3. Run `pixi run tests` to verify your changes don't break existing functionality
74+
4. If you've added new features, run `pixi run typing` to check type annotations
75+
5. If you've modified documentation, run `pixi run docs` to build and verify the docs
76+
77+
```{tip}
78+
You can run `pixi info` to see all available environments and `pixi task list` to see all available tasks across environments.
79+
```
4180

4281
## For maintainers
4382

@@ -52,5 +91,5 @@ The running of these commands is useful for local development and quick iteratio
5291

5392
When adding a dependency, make sure to modify the following files where relevant:
5493

55-
- `environment.yml` for core and development dependencies (important for the development environment, and CI)
94+
- `pixi.toml` for core and development dependencies (important for the development environment, and CI)
5695
- `pyproject.toml` for core dependencies (important for the pypi package, this should propagate through automatically to `recipe/meta.yml` in the conda-forge feedstock)

environment.yml

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)