Skip to content

Commit 24bb0e9

Browse files
vahid-ahmadiclaude
andcommitted
Merge main into joss-paper, resolving conflicts
Resolve conflicts in Makefile, README.md, and docs/dev.md by adopting main's MyST version variable and docs-serve target. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2 parents 626edfc + 3d70790 commit 24bb0e9

29 files changed

Lines changed: 2139 additions & 108 deletions

.github/bump_version.py

Lines changed: 65 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,21 @@
11
"""Infer semver bump from towncrier fragment types and update version."""
22

33
import re
4+
import subprocess
45
import sys
56
from pathlib import Path
67

8+
SEMVER_PATTERN = re.compile(r"^(\d+)\.(\d+)\.(\d+)$")
79

8-
def get_current_version(pyproject_path: Path) -> str:
10+
11+
def parse_version(version: str) -> tuple[int, int, int]:
12+
match = SEMVER_PATTERN.match(version)
13+
if not match:
14+
raise ValueError(f"Invalid semver: {version}")
15+
return tuple(int(part) for part in match.groups())
16+
17+
18+
def get_pyproject_version(pyproject_path: Path) -> str:
919
text = pyproject_path.read_text()
1020
match = re.search(r'^version\s*=\s*"(\d+\.\d+\.\d+)"', text, re.MULTILINE)
1121
if not match:
@@ -17,6 +27,45 @@ def get_current_version(pyproject_path: Path) -> str:
1727
return match.group(1)
1828

1929

30+
def get_changelog_versions(changelog_path: Path) -> list[str]:
31+
if not changelog_path.exists():
32+
return []
33+
return re.findall(
34+
r"^## \[(\d+\.\d+\.\d+)\]", changelog_path.read_text(), re.MULTILINE
35+
)
36+
37+
38+
def get_git_tag_versions(repo_root: Path) -> list[str]:
39+
try:
40+
result = subprocess.run(
41+
["git", "tag"],
42+
cwd=repo_root,
43+
capture_output=True,
44+
text=True,
45+
check=True,
46+
)
47+
except (FileNotFoundError, subprocess.CalledProcessError):
48+
return []
49+
50+
versions = []
51+
for tag in result.stdout.splitlines():
52+
normalized = tag.removeprefix("v").strip()
53+
if SEMVER_PATTERN.match(normalized):
54+
versions.append(normalized)
55+
return versions
56+
57+
58+
def get_current_version(
59+
pyproject_path: Path,
60+
changelog_path: Path,
61+
repo_root: Path,
62+
) -> str:
63+
candidates = [get_pyproject_version(pyproject_path)]
64+
candidates.extend(get_changelog_versions(changelog_path))
65+
candidates.extend(get_git_tag_versions(repo_root))
66+
return max(candidates, key=parse_version)
67+
68+
2069
def infer_bump(changelog_dir: Path) -> str:
2170
fragments = [
2271
f for f in changelog_dir.iterdir() if f.is_file() and f.name != ".gitkeep"
@@ -48,12 +97,20 @@ def bump_version(version: str, bump: str) -> str:
4897
return f"{major}.{minor}.{patch + 1}"
4998

5099

51-
def update_file(path: Path, old_version: str, new_version: str):
100+
def update_file(path: Path, new_version: str):
52101
text = path.read_text()
53-
updated = text.replace(
54-
f'version = "{old_version}"',
55-
f'version = "{new_version}"',
102+
updated, replacements = re.subn(
103+
r'(^version\s*=\s*")(\d+\.\d+\.\d+)(")',
104+
rf"\g<1>{new_version}\g<3>",
105+
text,
106+
flags=re.MULTILINE,
56107
)
108+
if replacements == 0:
109+
print(
110+
f"Could not update version in {path}",
111+
file=sys.stderr,
112+
)
113+
sys.exit(1)
57114
if updated != text:
58115
path.write_text(updated)
59116
print(f" Updated {path}")
@@ -62,15 +119,16 @@ def update_file(path: Path, old_version: str, new_version: str):
62119
def main():
63120
root = Path(__file__).resolve().parent.parent
64121
pyproject = root / "pyproject.toml"
122+
changelog = root / "CHANGELOG.md"
65123
changelog_dir = root / "changelog.d"
66124

67-
current = get_current_version(pyproject)
125+
current = get_current_version(pyproject, changelog, root)
68126
bump = infer_bump(changelog_dir)
69127
new = bump_version(current, bump)
70128

71129
print(f"Version: {current} -> {new} ({bump})")
72130

73-
update_file(pyproject, current, new)
131+
update_file(pyproject, new)
74132

75133

76134
if __name__ == "__main__":

.github/workflows/push.yaml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,8 @@ jobs:
8181
- uses: actions/setup-node@v4
8282
with:
8383
node-version: 18.x
84-
- name: Install MyST
85-
run: npm install -g mystmd
8684
- name: Build HTML Assets
87-
run: cd docs && myst build --html
85+
run: make docs
8886
- name: Upload artifact
8987
uses: actions/upload-pages-artifact@v3
9088
with:
@@ -108,6 +106,9 @@ jobs:
108106
uses: actions/checkout@v4
109107
with:
110108
token: ${{ steps.app-token.outputs.token }}
109+
fetch-depth: 0
110+
- name: Fetch tags
111+
run: git fetch --tags --force
111112
- name: Setup Python
112113
uses: actions/setup-python@v5
113114
with:

CHANGELOG.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,38 @@
1+
## [3.4.4] - 2026-04-13
2+
3+
### Changed
4+
5+
- Add TRACE TRO export helpers for certified runtime bundles and expose them through `policyengine.core`.
6+
7+
8+
## [3.4.3] - 2026-04-13
9+
10+
### Fixed
11+
12+
- Fix the release versioning workflow so it bumps from the highest known released version instead of regressing to a stale version from `pyproject.toml`.
13+
14+
15+
## [3.4.1] - 2026-04-13
16+
17+
### Changed
18+
19+
- Add certified bundle metadata that records runtime model pins alongside build-time data artifact provenance and compatibility fingerprints.
20+
21+
22+
## [3.4.2] - 2026-04-12
23+
24+
### Changed
25+
26+
- Align the bundled UK release manifest with the pinned `policyengine-uk` package version and updated data package revisions.
27+
28+
29+
## [3.4.1] - 2026-04-09
30+
31+
### Fixed
32+
33+
- Fixed the UK paper reproduction workflow so the checked-in example runs on Python 3.14 and the associated analysis helpers handle that path cleanly.
34+
35+
136
## [3.4.0] - 2026-04-08
237

338
### Added

Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
.PHONY: docs
1+
.PHONY: docs docs-serve
2+
3+
MYSTMD_VERSION ?= 1.8.3
4+
MYST_CMD = npx --yes mystmd@$(MYSTMD_VERSION)
25

36
all: build-package
47

58
docs:
6-
cd docs && npx mystmd build --html
9+
cd docs && $(MYST_CMD) build --html
10+
11+
docs-serve:
12+
cd docs && $(MYST_CMD) start
713

814
install:
915
uv pip install -e ".[dev]"

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ uv pip install -e ".[dev]" # install with dev dependencies (pytest, ruff, m
105105
```bash
106106
make format # ruff format
107107
make test # pytest with coverage
108-
make docs # run the MyST docs build used in CI via npx
108+
make docs # build static MyST/Jupyter Book 2 HTML docs
109+
make docs-serve # preview the docs locally
109110
make clean # remove caches, build artifacts, .h5 files
110111
```
111112

changelog.d/codex.paper-repro-314.fixed.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

docs/dev.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ dependencies used in CI (pytest, ruff, mypy, towncrier).
2323
```bash
2424
make format # ruff format
2525
make test # pytest with coverage
26-
make docs # run the MyST docs build used in CI via npx
26+
make docs # build static MyST/Jupyter Book 2 HTML docs
27+
make docs-serve # preview the docs locally
2728
make clean # remove caches, build artifacts, .h5 files
2829
```
2930

@@ -74,6 +75,8 @@ echo "Description of change" > changelog.d/my-change.added
7475

7576
On merge, the versioning workflow bumps the version, builds the changelog, and creates a GitHub Release.
7677

78+
For the target release-bundle architecture, see [Release bundles](release-bundles.md). That document defines the split between country `*-data` build manifests and `policyengine.py` certified runtime bundles.
79+
7780
## Architecture
7881

7982
### Package layout

docs/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,5 @@ We do this by:
1616
- [US tax-benefit model](country-models-us.md): Entities, parameters, reform examples
1717
- [Examples](examples.md): Complete working scripts
1818
- [Visualisation](visualisation.md): Publication-ready charts with Plotly
19+
- [Release bundles](release-bundles.md): Reproducible model-plus-data certification and provenance
1920
- [Development](dev.md): Setup, testing, CI, architecture

docs/myst.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ project:
1717
- file: country-models-us.md
1818
- file: examples.md
1919
- file: visualisation.md
20+
- file: release-bundles.md
2021
- file: dev.md
2122

2223
site:

0 commit comments

Comments
 (0)