Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
23282a2
chore: ignore plans/ and .python-version for v1.5.0 work
crvernon Jun 15, 2026
349c049
test: add v1.4.0 behavioral baseline and regression gate (Phase 0)
crvernon Jun 15, 2026
0bd7abf
feat: migrate to pyproject.toml, modernize querymi, add Typer CLI
crvernon Jun 15, 2026
1bd38f3
refactor: restructure layout and remove legacy packaging files
crvernon Jun 15, 2026
9052b44
docs: rewrite README and add Sphinx documentation site
crvernon Jun 15, 2026
1f2d2de
ci: add modern GitHub Actions workflows and lint config
crvernon Jun 15, 2026
a1ef548
ci: trigger release workflow on push to main instead of version tags
crvernon Jun 15, 2026
0bec563
docs: add lint workflow badge to README
crvernon Jun 15, 2026
99a7589
docs: remove codecov linkage and badge
crvernon Jun 15, 2026
32fe0ef
docs: update maintainers
crvernon Jun 15, 2026
90ce209
tests: add benchmark code for gcam version testing
crvernon Jun 16, 2026
2b70430
add gcam verification scenarios
crvernon Jun 16, 2026
8b7b216
add logo to docs
crvernon Jun 16, 2026
6eb0bcd
add workflow figure do docs
crvernon Jun 16, 2026
fc1a4b1
docs: make install protocol and troubleshooting more robust across pl…
crvernon Jun 16, 2026
2b45cc2
docs: add js to support toc expansion
crvernon Jun 16, 2026
fe4637e
docs: create more robust docstrings and typehints with examples
crvernon Jun 16, 2026
62898c6
tests: rebase test suite to be more robust
crvernon Jun 16, 2026
c64111c
pr40: handling the changes mad in PR40 so we do not have to rebase first
crvernon Jun 16, 2026
6fb1b32
docs: update for release
crvernon Jun 16, 2026
84dbfdb
tests: fix lint action
crvernon Jun 16, 2026
6ac54a4
docs: let action build current release branch
crvernon Jun 16, 2026
cf6dc83
docs: only keep main as target in action
crvernon Jun 16, 2026
a181258
docs: wordmark image white background
crvernon Jun 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly

- package-ecosystem: pip
directory: "/"
schedule:
interval: weekly
92 changes: 52 additions & 40 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,45 +1,57 @@
name: build

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

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

jobs:
build:
runs-on: ${{ matrix.os }}

strategy:
matrix:
os: [ubuntu-latest]

env:
OS: ${{ matrix.os }}
PYTHON: '3.9'

steps:

- uses: actions/checkout@v1

- name: Set up Python
uses: actions/setup-python@master
with:
python-version: 3.9

- name: Install dependencies
run: |
sudo apt-get update -y
sudo apt-get install -y libxml2-dev
sudo snap install libxslt
python -m pip install --upgrade pip
pip install click
python setup.py install

- name: Test and generate coverage report on Linux
run: |
pip install pytest
pip install pytest-cov
pytest --cov=./ --cov-report=xml

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
file: ./coverage.xml
fail_ci_if_error: true
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

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

- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"

- name: Install system libraries
run: |
sudo apt-get update -y
sudo apt-get install -y libxml2-dev libxslt1-dev

- name: Install package
run: |
python -m pip install --upgrade pip
pip install -e ".[dev]"

- name: Run tests with coverage
run: pytest --cov=gcamreader --cov-report=xml

- name: Upload coverage to Codecov
if: matrix.python-version == '3.12'
uses: codecov/codecov-action@v4
with:
files: ./coverage.xml
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: false
56 changes: 56 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: docs

on:
push:
branches: [main]
pull_request:

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

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

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

- name: Install package with docs extras
run: |
python -m pip install --upgrade pip
pip install -e ".[docs]"

- name: Build documentation
run: sphinx-build -b html -W docs docs/_build/html

- name: Upload Pages artifact
if: github.event_name == 'push'
uses: actions/upload-pages-artifact@v3
with:
path: docs/_build/html

deploy:
if: github.event_name == 'push'
needs: build
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
33 changes: 33 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: lint

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

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

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

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

- name: Install linters
run: |
python -m pip install --upgrade pip
pip install ruff black

- name: Run ruff
run: ruff check .

- name: Run black
run: black --check .
52 changes: 52 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: release

on:
push:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive

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

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

- name: Check distribution contents
run: |
python -m pip install twine
twine check dist/*

- name: Upload distribution artifacts
uses: actions/upload-artifact@v4
with:
name: dist
path: dist/

publish:
needs: build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/gcamreader/
permissions:
id-token: write
steps:
- name: Download distribution artifacts
uses: actions/download-artifact@v4
with:
name: dist
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# pyenv
.python-version

# development plans
plans/

# local files
.local/

# pycharm
.idea

Expand Down
75 changes: 75 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Changelog

All notable changes to this project are documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [1.5.0] - 2026-06-15

This release modernizes the package without changing its computational results.
A behavioral baseline captured from v1.4.0 is preserved in `benchmarks/` and is
used as a regression gate to guarantee identical query outputs.

### Added

- Behavioral baseline harness and regression test suite in `benchmarks/` that
lock query, scenario, `importdata`, and CLI outputs to the v1.4.0 results.
- `pyproject.toml` as the single source of build metadata and configuration.
- `CHANGELOG.md` to track project changes.

### Changed

- Migrated packaging from `setup.py` and `setup.cfg` to `pyproject.toml`
(setuptools backend).
- Raised the minimum supported Python version to 3.11.
- Replaced the Click based command line interface (and the
`click-default-group-wheel` dependency) with a Typer based CLI.
- Relaxed the pinned `requests~=2.20.0` requirement to a modern minimum and
refreshed the `pandas` and `lxml` minimum versions.
- Modernized `querymi.py`: removed Python 2 and Python 3.5 compatibility
branches, replaced `pkg_resources` with `importlib.resources`, and added type
hints and complete docstrings.
- Moved the test suite to a top level `tests/` directory and the example
notebooks to a top level `notebooks/` directory.

### Fixed

- Result parsing in `_parserslt` now aggregates with `dropna=False`, so rows
that contain missing values in one or more grouping columns are retained
instead of being silently dropped during the `groupby().sum()` step (PR #40).

### Removed

- `setup.py`, `setup.cfg`, `requirements.txt`, and `MANIFEST.in` (superseded by
`pyproject.toml`).

### Release verification

**Result: PASS — v1.5.0 reproduces the v1.4.0 outputs exactly.**

A behavioral baseline captured from v1.4.0 (`benchmarks/baseline/`) is re-run
against the v1.5.0 code by `benchmarks/test_regression.py`. Every fixture
matches: CSV outputs are compared byte-for-byte by SHA-256 checksum, and
DataFrame outputs are compared with `pandas.testing.assert_frame_equal` after a
deterministic sort.

| Operation | Result | Comparison | Java |
| --- | --- | --- | --- |
| `parse_batch_query` (query structure) | identical | exact title/region/query strings | not required |
| `listScenariosInDB` | identical | `assert_frame_equal` | required |
| `runQuery` (land-allocation query) | identical | `assert_frame_equal` (sorted) | required |
| `importdata` (land-allocation query) | identical | `assert_frame_equal` (sorted) | required |
| `gcamreader local` CLI CSV output | identical | SHA-256 (byte-for-byte) | required |

Baseline captured with gcamreader 1.4.0 on Python 3.13.3, OpenJDK 23.0.2
(Homebrew), macOS 26.5.1 (arm64). Reproduce locally with:

```bash
pytest benchmarks/test_regression.py
```

[Unreleased]: https://github.com/JGCRI/gcamreader/compare/v1.5.0...HEAD
[1.5.0]: https://github.com/JGCRI/gcamreader/compare/v1.4.0...v1.5.0
5 changes: 0 additions & 5 deletions MANIFEST.in

This file was deleted.

Loading
Loading