Skip to content

Commit cb49520

Browse files
committed
Update PolicyEngine bundle to 4.18.5
1 parent 3868997 commit cb49520

8 files changed

Lines changed: 180 additions & 48 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
CHECK_ONLY_IF_CHANGED=0
6+
BASE_REF=""
7+
VERSION_GUARD_SCRIPT="${SIMULATION_VERSION_GUARD_SCRIPT:-.github/request-simulation-model-versions.sh}"
8+
9+
usage() {
10+
echo "Usage: $0 [--if-changed-from-base <base_ref>]"
11+
exit 1
12+
}
13+
14+
while [ $# -gt 0 ]; do
15+
case "$1" in
16+
--if-changed-from-base)
17+
CHECK_ONLY_IF_CHANGED=1
18+
BASE_REF="$2"
19+
shift 2
20+
;;
21+
-h|--help)
22+
usage
23+
;;
24+
*)
25+
echo "Error: Unknown option $1"
26+
usage
27+
;;
28+
esac
29+
done
30+
31+
extract_policyengine_version() {
32+
sed -n 's/.*policyengine\[models\]==\([0-9.][0-9.]*\).*/\1/p' | head -n 1
33+
}
34+
35+
current_version="$(extract_policyengine_version < pyproject.toml)"
36+
if [ -z "$current_version" ]; then
37+
echo "ERROR: policyengine[models] pin not found in pyproject.toml"
38+
exit 1
39+
fi
40+
41+
if [ "$CHECK_ONLY_IF_CHANGED" = "1" ]; then
42+
if [ -z "$BASE_REF" ]; then
43+
echo "ERROR: --if-changed-from-base requires a base ref"
44+
exit 1
45+
fi
46+
47+
git fetch --no-tags --depth=1 origin "$BASE_REF"
48+
base_version="$(
49+
git show "origin/${BASE_REF}:pyproject.toml" \
50+
| extract_policyengine_version \
51+
|| true
52+
)"
53+
54+
if [ "$current_version" = "$base_version" ]; then
55+
echo "PolicyEngine .py bundle pin is unchanged; skipping simulation API support check."
56+
exit 0
57+
fi
58+
fi
59+
60+
bash "$VERSION_GUARD_SCRIPT" -py "$current_version"

.github/workflows/pr.yml

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,27 @@ env:
66
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
77

88
jobs:
9+
ensure-policyengine-bundle-supported-by-simulation-api:
10+
name: Ensure PolicyEngine bundle is supported by simulation API
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
steps:
15+
- name: Checkout repo
16+
uses: actions/checkout@v4
17+
with:
18+
fetch-depth: 0
19+
- name: Install jq
20+
run: sudo apt-get install -y jq
21+
- name: Check simulation API supports updated PolicyEngine bundle
22+
env:
23+
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
24+
run: bash .github/check-policyengine-bundle-supported.sh --if-changed-from-base "${{ github.base_ref }}"
25+
926
lint:
1027
name: Lint
1128
runs-on: ubuntu-latest
29+
needs: ensure-policyengine-bundle-supported-by-simulation-api
1230
steps:
1331
- name: Checkout repo
1432
uses: actions/checkout@v4
@@ -21,6 +39,7 @@ jobs:
2139
quality-guards:
2240
name: Quality guards
2341
runs-on: ubuntu-latest
42+
needs: ensure-policyengine-bundle-supported-by-simulation-api
2443
steps:
2544
- name: Checkout repo
2645
uses: actions/checkout@v4
@@ -33,13 +52,15 @@ jobs:
3352
check-changelog:
3453
name: Check changelog fragment
3554
runs-on: ubuntu-latest
55+
needs: ensure-policyengine-bundle-supported-by-simulation-api
3656
steps:
3757
- uses: actions/checkout@v4
3858
- name: Check for changelog fragment
3959
run: bash .github/scripts/check_changelog_fragment.sh
4060
test_container_builds:
4161
name: Docker
4262
runs-on: ubuntu-latest
63+
needs: ensure-policyengine-bundle-supported-by-simulation-api
4364
permissions:
4465
contents: read
4566
packages: write
@@ -57,6 +78,7 @@ jobs:
5778
test_cloud_run_container_builds:
5879
name: Cloud Run container
5980
runs-on: ubuntu-latest
81+
needs: ensure-policyengine-bundle-supported-by-simulation-api
6082
permissions:
6183
contents: read
6284
steps:
@@ -67,6 +89,7 @@ jobs:
6789
test_env_vars:
6890
name: Test environment variables
6991
runs-on: ubuntu-latest
92+
needs: ensure-policyengine-bundle-supported-by-simulation-api
7093
permissions:
7194
contents: read
7295
id-token: write
@@ -95,7 +118,9 @@ jobs:
95118
test:
96119
name: Test
97120
runs-on: ubuntu-latest
98-
needs: test_env_vars
121+
needs:
122+
- ensure-policyengine-bundle-supported-by-simulation-api
123+
- test_env_vars
99124
permissions:
100125
contents: read
101126
id-token: write

.github/workflows/push.yml

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,12 @@ jobs:
3737
steps:
3838
- name: Checkout repo
3939
uses: actions/checkout@v4
40-
- name: Setup Python
41-
uses: actions/setup-python@v5
42-
with:
43-
python-version: "3.12"
44-
- name: Install dependencies (required for finding API model versions)
45-
run: make install
46-
- name: Install jq (required only for GitHub Actions)
40+
- name: Install jq
4741
run: sudo apt-get install -y jq
48-
- name: Find API model versions and write to environment variable
49-
run: python3 .github/find-api-model-versions.py
50-
- name: Ensure full API and simulation API model versions are in sync
51-
run: ".github/request-simulation-model-versions.sh -py ${{ env.POLICYENGINE_VERSION }} -us ${{ env.US_VERSION }} -uk ${{ env.UK_VERSION }}"
42+
- name: Check simulation API supports PolicyEngine bundle
5243
env:
5344
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
45+
run: bash .github/check-policyengine-bundle-supported.sh
5446

5547
versioning:
5648
name: Update versioning
@@ -365,20 +357,12 @@ jobs:
365357
steps:
366358
- name: Checkout repo
367359
uses: actions/checkout@v4
368-
- name: Setup Python
369-
uses: actions/setup-python@v5
370-
with:
371-
python-version: "3.12"
372-
- name: Install dependencies (required for finding API model versions)
373-
run: make install
374-
- name: Install jq (required only for GitHub Actions)
360+
- name: Install jq
375361
run: sudo apt-get install -y jq
376-
- name: Find API model versions and write to environment variable
377-
run: python3 .github/find-api-model-versions.py
378-
- name: Ensure full API and simulation API model versions are in sync
379-
run: ".github/request-simulation-model-versions.sh -py ${{ env.POLICYENGINE_VERSION }} -us ${{ env.US_VERSION }} -uk ${{ env.UK_VERSION }}"
362+
- name: Check simulation API supports PolicyEngine bundle
380363
env:
381364
SIMULATION_API_URL: ${{ secrets.SIMULATION_API_URL }}
365+
run: bash .github/check-policyengine-bundle-supported.sh
382366

383367
deploy-production-candidate:
384368
name: Deploy production App Engine candidate
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update the PolicyEngine bundle to 4.18.5.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ dependencies = [
4141
"policyengine_canada==0.96.3",
4242
"policyengine-ng==0.5.1",
4343
"policyengine-il==0.1.0",
44-
"policyengine[models]==4.18.3",
44+
"policyengine[models]==4.18.5",
4545
"pydantic",
4646
"pymysql",
4747
"python-dotenv",

tests/unit/test_cloud_run_deploy_scripts.py

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import subprocess
88
from pathlib import Path
99

10-
1110
REPO = Path(__file__).resolve().parents[2]
1211
PRODUCTION_CLOUD_SQL_INSTANCE = "policyengine-api:us-central1:policyengine-api-data"
1312
DEDICATED_CLOUD_RUN_RUNTIME_SERVICE_ACCOUNT = (
@@ -182,6 +181,57 @@ def test_simulation_version_guard_accepts_bundle_and_compatible_country_routes()
182181
assert "SUCCESS: PolicyEngine bundle route is deployed and ready" in result.stdout
183182

184183

184+
def test_simulation_version_guard_accepts_policyengine_bundle_route_only():
185+
result = _run_simulation_version_guard(
186+
{
187+
"policyengine": {
188+
"latest": "4.18.5",
189+
"4.18.5": "policyengine-simulation-py4-18-5",
190+
},
191+
"us": {},
192+
"uk": {},
193+
},
194+
"-py",
195+
"4.18.5",
196+
)
197+
198+
assert result.returncode == 0, result.stderr
199+
assert "PolicyEngine .py bundle 4.18.5 is deployed" in result.stdout
200+
assert "SUCCESS: PolicyEngine bundle route is deployed and ready" in result.stdout
201+
202+
203+
def test_policyengine_bundle_support_check_passes_pyproject_pin_to_guard(tmp_path):
204+
capture_path = tmp_path / "guard-args.txt"
205+
guard_script = tmp_path / "request-simulation-model-versions.sh"
206+
guard_script.write_text(
207+
'printf "%s\\n" "$@" > "$CAPTURE_PATH"\n',
208+
encoding="utf-8",
209+
)
210+
211+
result = subprocess.run(
212+
["bash", ".github/check-policyengine-bundle-supported.sh"],
213+
cwd=REPO,
214+
env=_script_env(
215+
SIMULATION_VERSION_GUARD_SCRIPT=str(guard_script),
216+
CAPTURE_PATH=str(capture_path),
217+
),
218+
text=True,
219+
capture_output=True,
220+
check=False,
221+
)
222+
223+
pyproject = (REPO / "pyproject.toml").read_text(encoding="utf-8")
224+
current_version = re.search(r"policyengine\[models\]==([0-9.]+)", pyproject).group(
225+
1
226+
)
227+
228+
assert result.returncode == 0, result.stderr
229+
assert capture_path.read_text(encoding="utf-8").splitlines() == [
230+
"-py",
231+
current_version,
232+
]
233+
234+
185235
def test_simulation_version_guard_rejects_country_route_to_different_app():
186236
result = _run_simulation_version_guard(
187237
{

tests/unit/test_constants.py

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,17 @@
33
import sys
44

55
import pytest
6-
76
from policyengine_api.constants import (
87
COUNTRY_PACKAGE_VERSIONS,
98
POLICYENGINE_CORE_VERSION,
109
POLICYENGINE_VERSION,
1110
REGION_PREFIXES,
1211
UK_REGION_TYPES,
1312
US_REGION_TYPES,
14-
get_py_manifest,
1513
_load_policyengine_bundle,
1614
_normalize_distribution_name,
1715
_resolve_distribution_version,
16+
get_py_manifest,
1817
)
1918

2019

@@ -126,6 +125,23 @@ def test__resolve_distribution_version_falls_back_to_default(self):
126125

127126

128127
class TestPolicyEngineBundleVersions:
128+
@staticmethod
129+
def _expected_bundle_versions() -> dict[str, str]:
130+
manifest = json.loads(get_py_manifest().read_text(encoding="utf-8"))
131+
packages = manifest["packages"]
132+
normalized_packages = {
133+
_normalize_distribution_name(package.get("name") or package_key): package
134+
for package_key, package in packages.items()
135+
}
136+
return {
137+
"policyengine": str(
138+
manifest.get("policyengine_version") or manifest.get("bundle_version")
139+
),
140+
"core": str(normalized_packages["policyengine-core"]["version"]),
141+
"us": str(normalized_packages["policyengine-us"]["version"]),
142+
"uk": str(normalized_packages["policyengine-uk"]["version"]),
143+
}
144+
129145
def test__get_py_manifest_returns_packaged_manifest_path(self):
130146
manifest_path = get_py_manifest()
131147

@@ -173,12 +189,7 @@ def find_spec(self, fullname, path=None, target=None):
173189
)
174190

175191
assert result.returncode == 0, result.stderr
176-
assert json.loads(result.stdout) == {
177-
"policyengine": "4.18.3",
178-
"core": "3.27.1",
179-
"us": "1.729.0",
180-
"uk": "2.89.2",
181-
}
192+
assert json.loads(result.stdout) == self._expected_bundle_versions()
182193

183194
def test__load_policyengine_bundle_rejects_missing_manifest(
184195
self, monkeypatch, tmp_path
@@ -205,7 +216,8 @@ def test__load_policyengine_bundle_rejects_non_object_manifest(
205216
_load_policyengine_bundle()
206217

207218
def test__uses_policyengine_bundle_versions_for_us_uk_and_core(self):
208-
assert POLICYENGINE_VERSION == "4.18.3"
209-
assert POLICYENGINE_CORE_VERSION == "3.27.1"
210-
assert COUNTRY_PACKAGE_VERSIONS["us"] == "1.729.0"
211-
assert COUNTRY_PACKAGE_VERSIONS["uk"] == "2.89.2"
219+
expected_versions = self._expected_bundle_versions()
220+
assert POLICYENGINE_VERSION == expected_versions["policyengine"]
221+
assert POLICYENGINE_CORE_VERSION == expected_versions["core"]
222+
assert COUNTRY_PACKAGE_VERSIONS["us"] == expected_versions["us"]
223+
assert COUNTRY_PACKAGE_VERSIONS["uk"] == expected_versions["uk"]

0 commit comments

Comments
 (0)