From 2c72a855df3193aa1352d58729eca140a130035a Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Mon, 27 Jul 2026 10:24:26 +0200 Subject: [PATCH 1/2] Switch docs to point to the conda-forge package --- README.md | 87 +++++++++++++++++++++++++++++++++-- docs/generating_test_files.md | 2 +- isschecker_env.yml | 5 ++ 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f45263f..a9b993a 100644 --- a/README.md +++ b/README.md @@ -93,9 +93,37 @@ Reference lookup tables are available in the companion repository [`ismip7-time- --- -## Setup +## Installation -Create the conda environment and install the package: +The checker is packaged on [conda-forge](https://anaconda.org/conda-forge/isschecker), and that is how you should install it. Nothing is built, no dependency has to be picked by hand, and there is no need to clone this repository at all: + +```bash +conda create -n isschecker -c conda-forge isschecker +conda activate isschecker +``` + +`mamba` and `micromamba` work the same way; substitute either for `conda` if you prefer. If your conda is configured with the `defaults` channel, add `--override-channels` so a package cannot be pulled from it: builds from the two channels are not interchangeable, and mixing them is a good way for two people to get different results from the same files. + +The package registers the `ismip7-compliance-checker` and `ismip7-generate-test-files` commands and bundles the data files, so the checker can be run from any directory. Confirm the installation with: + +```bash +ismip7-compliance-checker --version +``` + +To move to a newer release later: + +```bash +conda activate isschecker +conda update -c conda-forge isschecker +``` + +The conda-forge package is built from the tagged releases of this repository, so it can be behind `main` by a release; `--version` always reports the one you actually have. See [Releasing](#releasing) for when a tag is cut. + +### Installing from source + +You only need this to work *on* the checker — to test a change that has not been released yet, or to develop one. For checking a submission, install from conda-forge instead. + +Create the conda environment and install the package into it: ```bash conda env create -f isschecker_env.yml @@ -103,7 +131,7 @@ conda activate isschecker python -m pip install --no-deps --no-build-isolation . ``` -Installing the package registers the `ismip7-compliance-checker` command and bundles the data files, so the checker can be run from any directory. +Note that `isschecker_env.yml` installs the dependencies but not the checker itself, so the environment it creates is not the one above: an `isschecker` environment made this way holds no `isschecker` package until the `pip install` runs. If you already have an environment of that name from conda-forge, `conda env create` will refuse to create another over it; give this one a different name with `conda env create -n isschecker-dev -f isschecker_env.yml` and keep both. **Use those pip flags.** All dependencies come from conda-forge, and a plain `pip install .` can silently replace them with PyPI wheels — `netCDF4` in particular bundles its own copy of the netCDF C library — which is exactly how two people end up with different results from the same files. `--no-deps` keeps pip from resolving anything, and `--no-build-isolation` builds with the environment's `setuptools` instead of downloading one from PyPI. Add `--no-index` if you want any accidental network fetch to fail loudly rather than succeed quietly. @@ -119,6 +147,8 @@ If a rebuild ever behaves as though it were still running older code, delete the ### Dependencies +Installing from conda-forge pulls these in for you, and you can skip this section. It matters when you install from source, where the environment is yours to create. + Versions are constrained in `isschecker_env.yml`; the same constraints appear in `pyproject.toml`. The suite is tested at both ends of every range, so results should agree across machines and operating systems within these bounds. | Package | Constraint | Why bounded | @@ -185,7 +215,7 @@ ismip7-generate-test-files --list-grids ## Running Tests -The regression suite uses `pytest` and creates temporary synthetic datasets, then mutates them to verify expected checker failures for naming, missing and misnamed variables, wrong variable dimensions, time-axis problems, and missing attributes. It imports `isschecker`, so install the package first (see [Setup](#setup)); the tests then exercise what is actually installed and can be run from any directory. +The regression suite uses `pytest` and creates temporary synthetic datasets, then mutates them to verify expected checker failures for naming, missing and misnamed variables, wrong variable dimensions, time-axis problems, and missing attributes. It imports `isschecker`, so install the package first (see [Installing from source](#installing-from-source)); the tests then exercise what is actually installed and can be run from any directory. Run the suite against the source install you are developing in: run against a conda-forge install and you are testing the last release with the working tree's tests, which disagree whenever the working tree has changed anything the tests look at. ```bash pytest -v tests/test_compliance_checker.py @@ -206,3 +236,52 @@ When a change to the checker is *meant* to change the log, read the diff the fai ```bash ISSCHECKER_UPDATE_GOLDEN_LOG=1 pytest tests/test_golden_log.py ``` + +--- + +## Releasing + +This section is for maintainers — those with write access to [the main repository](https://github.com/ismip/ISM_SimulationChecker). If you are contributing from a fork, nothing here is yours to do; open the pull request and a maintainer will fold it into the next release. + +Modellers get the checker from conda-forge, and conda-forge builds from a tag. Anything on `main` that has not been tagged therefore does not exist as far as they are concerned: a check you added, a message you reworded, a variable you renamed in `ISMIP7_variable_request.csv` — all of it sits in this repository being invisible to everyone running the tool. + +**So tag a release whenever a change reaches `main` that a user would notice.** That is the rule, and it is deliberately a low bar: new or changed checks, a change in a finding's severity or wording, a change to the bundled data request or grid definitions, a new or altered command-line option, a bug fix, or a widened dependency range. Releases are cheap; a user chasing a discrepancy against a source checkout that turns out to be six months of untagged changes is not. Refactorings, tests, CI and documentation-only changes need no release, though there is no harm in folding them into the next one. + +To cut a release: + +1. Bump `version` in `pyproject.toml` following [semantic versioning](https://semver.org/) — patch for a fix, minor for a new or changed check, major for a change that would fail a submission that used to pass — and merge that to `main`. +2. Draft a new [GitHub release](https://github.com/ismip/ISM_SimulationChecker/releases/new) against `main`. In the tag field, type the new version and choose **Create new tag on publish**, so that publishing the release creates the tag: one action, and the two can never disagree about which commit they point at. Write notes saying what changed for users, then publish. + + The tag is the bare version number — `0.2.0`, no `v` prefix — because the feedstock builds its source URL from it, and it must match `version` in `pyproject.toml` exactly. +3. Wait for the conda-forge bot to open a version-bump PR on [`isschecker-feedstock`](https://github.com/conda-forge/isschecker-feedstock), usually within a few hours. Review and merge it; the package appears on conda-forge shortly after the build finishes. Merging it needs write access to the feedstock, which is separate from write access here — see [Maintaining the feedstock](#maintaining-the-feedstock) below. + +If the release changed the dependency ranges, edit the feedstock PR before merging so that the `run:` requirements in `recipe/recipe.yaml` match `pyproject.toml` and `isschecker_env.yml` — the bot updates the version and hash, not the requirements. Those three lists are the same constraints written down three times, and it is worth checking them against one another at each release. + +Finally, and **optionally**, you can confirm what was published rather than assuming it: + +```bash +conda create -n isschecker-test -c conda-forge --override-channels isschecker pytest +conda activate isschecker-test +ismip7-compliance-checker --version # should print the version you tagged +cd $(mktemp -d) && pytest -v /path/to/ISM_SimulationChecker/tests +``` + +Run that from a checkout of the tag, not of `main`: the tests come from the source tree while the package comes from conda-forge, so with `main` checked out any change made since the tag shows up as a test failure that says nothing about the release. + +It is optional because of the wait. A merged feedstock PR does not put the package within reach immediately: the build has to finish, and the result then takes roughly an hour to propagate across the servers `conda` fetches from. Until it has, `conda create` either cannot find the new version or reports the old one, and neither means anything is wrong. So this is not a step to sit and retry — come back to it later in the day, or skip it. The CI in this repository already runs the full suite against the tagged source at both ends of every dependency range, and the feedstock runs the recipe's own import and `--help` tests before the package is published at all, so a release that got that far is very unlikely to be broken in a way an install check would catch. What it does catch is the recipe describing something other than what you tagged — wrong version, a dependency range that never made it into `recipe/recipe.yaml` — which is worth a few minutes at some point after a release that changed either. + +### Maintaining the feedstock + +The conda-forge package is built by its own repository, [`conda-forge/isschecker-feedstock`](https://github.com/conda-forge/isschecker-feedstock), which is separate from this one and has its own list of maintainers — being a maintainer here does not make you one there. Only feedstock maintainers can merge the bot's version-bump PRs, so a release stalls if nobody available has that access. It is worth having more than one of us on the list. + +The list lives in the recipe itself, under `extra: recipe-maintainers:` in `recipe/recipe.yaml`. To be added, open an **issue** on the feedstock with the title: + +``` +@conda-forge-admin, please add user @your-github-username +``` + +A bot then opens a PR adding you, which an existing feedstock maintainer merges. GitHub will email you an invitation to the feedstock's team in the conda-forge organisation; **you have to accept it**, or the merge has given you nothing. This is conda-forge's documented mechanism, described under [Updating the maintainer list](https://conda-forge.org/docs/maintainer/updating_pkgs/#updating-the-maintainer-list); leave the bot's PR alone rather than editing it or its commit message, since it is built to skip a package rebuild. + +Those docs also say that asking to be added is not how to introduce yourself to a feedstock you have no history with — the usual route is to contribute a PR first. That caveat is about strangers arriving at someone else's package; this feedstock exists to publish this repository, so a maintainer here asking to be added to it is expected rather than presumptuous. + +[The conda-forge maintainer documentation](https://conda-forge.org/docs/maintainer/) covers the rest: what the bots do, how to fix a build, and the [`@conda-forge-admin` commands](https://conda-forge.org/docs/maintainer/infrastructure/#conda-forge-admin-please-add-user-username) for re-rendering a feedstock and other routine chores. Very little of it is needed for a package as simple as this one — a pure-Python `noarch` recipe whose releases are usually nothing more than a version and a hash. diff --git a/docs/generating_test_files.md b/docs/generating_test_files.md index 9a6df9d..226c190 100644 --- a/docs/generating_test_files.md +++ b/docs/generating_test_files.md @@ -1,6 +1,6 @@ # ISMIP7 NetCDF generator -`ismip7-generate-test-files` creates ISMIP7-style NetCDF test files with synthetic data, one file per variable, following the naming convention and grid definitions used by the compliance checker. It is part of the `isschecker` package (`isschecker.generate`), so it is installed along with the checker and can be run from any directory. +`ismip7-generate-test-files` creates ISMIP7-style NetCDF test files with synthetic data, one file per variable, following the naming convention and grid definitions used by the compliance checker. It is part of the `isschecker` package (`isschecker.generate`), so it is installed along with the checker — `conda create -n isschecker -c conda-forge isschecker`, see [Installation](../README.md#installation) — and can be run from any directory. Files are written to `Models/{GrIS|AIS}/ISMIP7/SYNTH1/CORE/{set_counter}/` (default `C001`) beneath the current working directory. diff --git a/isschecker_env.yml b/isschecker_env.yml index 6946902..22d953a 100644 --- a/isschecker_env.yml +++ b/isschecker_env.yml @@ -1,3 +1,8 @@ +# Development environment: the checker's dependencies, but not the checker +# itself, which is then pip-installed from a source checkout (see "Installing +# from source" in the README). To *use* the checker, install it from +# conda-forge instead -- `conda create -n isschecker -c conda-forge isschecker` +# -- which brings these packages with it. name: isschecker channels: - conda-forge From 50c41fca5851ba1d3210756227dc52dd50c656a4 Mon Sep 17 00:00:00 2001 From: Xylar Asay-Davis Date: Mon, 27 Jul 2026 10:26:52 +0200 Subject: [PATCH 2/2] Update to v0.1.1 for a release --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 0f1fae1..ed984e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "isschecker" -version = "0.1.0" +version = "0.1.1" description = "ISMIP7 compliance checker for ice sheet model simulation NetCDF datasets" readme = "README.md" license = "MIT"