Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 3 additions & 1 deletion .github/scripts/modal-deploy-versioned.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash
# Deploy versioned simulation app to Modal
# Usage: ./modal-deploy-versioned.sh <modal-environment>
# Required env vars: POLICYENGINE_US_VERSION, POLICYENGINE_UK_VERSION
# Required env vars: POLICYENGINE_VERSION, POLICYENGINE_US_VERSION, POLICYENGINE_UK_VERSION
#
# Deploys a versioned app named policyengine-us{X}-uk{Y} and updates
# the Modal Dict version registries so Cloud Run can route to it.
Expand All @@ -14,6 +14,7 @@ MODAL_ENV="${1:?Modal environment required (staging or main)}"
# Validate required env vars
: "${POLICYENGINE_US_VERSION:?POLICYENGINE_US_VERSION must be set}"
: "${POLICYENGINE_UK_VERSION:?POLICYENGINE_UK_VERSION must be set}"
: "${POLICYENGINE_VERSION:?POLICYENGINE_VERSION must be set}"

# Generate versioned app name (dots replaced with dashes)
US_VERSION_SAFE="${POLICYENGINE_US_VERSION//./-}"
Expand All @@ -24,6 +25,7 @@ echo "========================================"
echo "Deploying versioned Modal simulation app"
echo " Environment: $MODAL_ENV"
echo " App name: $APP_NAME"
echo " policyengine.py: ${POLICYENGINE_VERSION}"
echo " US version: ${POLICYENGINE_US_VERSION}"
echo " UK version: ${POLICYENGINE_UK_VERSION}"
echo "========================================"
Expand Down
11 changes: 7 additions & 4 deletions .github/scripts/modal-extract-versions.sh
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
#!/bin/bash
# Extract policyengine-us and policyengine-uk versions from uv.lock
# Extract policyengine, policyengine-us, and policyengine-uk versions from uv.lock
# Usage: ./modal-extract-versions.sh [project-dir]
# Outputs: Sets us_version and uk_version in GITHUB_OUTPUT
# Outputs: Sets policyengine_version, us_version, and uk_version in GITHUB_OUTPUT

set -euo pipefail

PROJECT_DIR="${1:-.}"

cd "$PROJECT_DIR"

POLICYENGINE_VERSION=$(grep -A1 'name = "policyengine"' uv.lock | grep version | head -1 | sed 's/.*"\(.*\)".*/\1/')
US_VERSION=$(grep -A1 'name = "policyengine-us"' uv.lock | grep version | head -1 | sed 's/.*"\(.*\)".*/\1/')
UK_VERSION=$(grep -A1 'name = "policyengine-uk"' uv.lock | grep version | head -1 | sed 's/.*"\(.*\)".*/\1/')

if [ -z "$US_VERSION" ] || [ -z "$UK_VERSION" ]; then
if [ -z "$POLICYENGINE_VERSION" ] || [ -z "$US_VERSION" ] || [ -z "$UK_VERSION" ]; then
echo "ERROR: Could not extract versions from uv.lock"
echo " POLICYENGINE_VERSION=$POLICYENGINE_VERSION"
echo " US_VERSION=$US_VERSION"
echo " UK_VERSION=$UK_VERSION"
exit 1
fi

echo "policyengine_version=$POLICYENGINE_VERSION" >> "$GITHUB_OUTPUT"
echo "us_version=$US_VERSION" >> "$GITHUB_OUTPUT"
echo "uk_version=$UK_VERSION" >> "$GITHUB_OUTPUT"
echo "Extracted versions: policyengine-us=$US_VERSION, policyengine-uk=$UK_VERSION"
echo "Extracted versions: policyengine=$POLICYENGINE_VERSION, policyengine-us=$US_VERSION, policyengine-uk=$UK_VERSION"
102 changes: 102 additions & 0 deletions .github/workflows/db-reseed.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: Reseed database

on:
workflow_dispatch:
inputs:
target:
description: "Target database"
required: true
type: choice
options:
- staging
- production
preset:
description: "Seeding preset"
required: true
default: "full"
type: choice
options:
- full
- lite
- minimal
- uk-lite
- uk-minimal
- us-lite
- us-minimal
- testing
confirm:
description: "Type 'reseed-staging' or 'reseed-prod' to confirm"
required: true
type: string
pull_request:
paths:
- ".github/workflows/db-reseed.yml"

jobs:
validate:
name: Validate workflow
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'

steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Validate workflow syntax
run: |
bash <(curl -sSL https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash)
./actionlint -color

reseed-db:
name: Reseed ${{ inputs.target }} database
runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch'
environment: ${{ inputs.target }}

steps:
- name: Verify confirmation
run: |
EXPECTED="reseed-staging"
if [ "${{ inputs.target }}" = "production" ]; then
EXPECTED="reseed-prod"
fi
if [ "${{ inputs.confirm }}" != "$EXPECTED" ]; then
echo "Confirmation failed. You must type '$EXPECTED' to proceed."
exit 1
fi
echo "Confirmation verified for ${{ inputs.target }}"

- name: Checkout code
uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v8.1.0
with:
save-cache: false

- name: Setup Python
run: uv python install 3.13

- name: Sync dependencies
run: uv sync

- name: Reseed database
env:
SUPABASE_DB_URL: ${{ secrets.SUPABASE_DB_URL }}
SUPABASE_URL: ${{ secrets.SUPABASE_URL }}
SUPABASE_KEY: ${{ secrets.SUPABASE_KEY }}
SUPABASE_SECRET_KEY: ${{ secrets.SUPABASE_SECRET_KEY }}
HUGGING_FACE_TOKEN: ${{ secrets.HUGGING_FACE_TOKEN }}
STORAGE_BUCKET: ${{ vars.STORAGE_BUCKET }}
LOGFIRE_TOKEN: ${{ secrets.LOGFIRE_TOKEN }}
LOGFIRE_ENVIRONMENT: ${{ inputs.target }}
run: |
echo "Reseeding ${{ inputs.target }} database with preset '${{ inputs.preset }}'..."
uv run python scripts/seed.py --preset="${{ inputs.preset }}"

- name: Summary
run: |
echo "Database reseed complete."
echo "Target: ${{ inputs.target }}"
echo "Preset: ${{ inputs.preset }}"
echo "Triggered by: ${{ github.actor }}"
17 changes: 10 additions & 7 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,14 +131,14 @@ jobs:
uses: google-github-actions/setup-gcloud@v3

- name: Configure Docker for Artifact Registry
run: gcloud auth configure-docker ${{ vars.GCP_REGION }}-docker.pkg.dev
run: gcloud auth configure-docker "${{ vars.GCP_REGION }}-docker.pkg.dev"

- name: Build and push Docker image
run: |
docker build -t $IMAGE_URL:${{ github.sha }} .
docker tag $IMAGE_URL:${{ github.sha }} $IMAGE_URL:latest
docker push $IMAGE_URL:${{ github.sha }}
docker push $IMAGE_URL:latest
docker build -t "${IMAGE_URL}:${{ github.sha }}" .
docker tag "${IMAGE_URL}:${{ github.sha }}" "${IMAGE_URL}:latest"
docker push "${IMAGE_URL}:${{ github.sha }}"
docker push "${IMAGE_URL}:latest"

infra:
name: Apply infrastructure
Expand Down Expand Up @@ -262,6 +262,7 @@ jobs:
env:
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
POLICYENGINE_VERSION: ${{ steps.versions.outputs.policyengine_version }}
POLICYENGINE_US_VERSION: ${{ steps.versions.outputs.us_version }}
POLICYENGINE_UK_VERSION: ${{ steps.versions.outputs.uk_version }}
run: |
Expand Down Expand Up @@ -304,7 +305,7 @@ jobs:
run: |
gcloud run deploy ${{ vars.API_SERVICE_NAME }} \
--region=${{ vars.GCP_REGION }} \
--image=$IMAGE_URL:${{ github.sha }} \
--image="${IMAGE_URL}:${{ github.sha }}" \
--tag=staging \
--no-traffic \
--update-env-vars=MODAL_ENVIRONMENT=staging,LOGFIRE_ENVIRONMENT=staging,SUPABASE_URL=${{ secrets.SUPABASE_URL }},SUPABASE_KEY=${{ secrets.SUPABASE_KEY }},SUPABASE_SECRET_KEY=${{ secrets.SUPABASE_SECRET_KEY }},SUPABASE_DB_URL=${{ secrets.SUPABASE_DB_URL }}
Expand Down Expand Up @@ -400,6 +401,7 @@ jobs:
env:
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
POLICYENGINE_VERSION: ${{ steps.prod-versions.outputs.policyengine_version }}
POLICYENGINE_US_VERSION: ${{ steps.prod-versions.outputs.us_version }}
POLICYENGINE_UK_VERSION: ${{ steps.prod-versions.outputs.uk_version }}
run: |
Expand All @@ -417,6 +419,7 @@ jobs:
env:
MODAL_TOKEN_ID: ${{ secrets.MODAL_TOKEN_ID }}
MODAL_TOKEN_SECRET: ${{ secrets.MODAL_TOKEN_SECRET }}
POLICYENGINE_VERSION: ${{ steps.prod-versions.outputs.policyengine_version }}
POLICYENGINE_US_VERSION: ${{ steps.prod-versions.outputs.us_version }}
POLICYENGINE_UK_VERSION: ${{ steps.prod-versions.outputs.uk_version }}
run: |
Expand Down Expand Up @@ -469,7 +472,7 @@ jobs:
run: |
gcloud run deploy ${{ vars.API_SERVICE_NAME }} \
--region=${{ vars.GCP_REGION }} \
--image=$IMAGE_URL:${{ github.sha }} \
--image="${IMAGE_URL}:${{ github.sha }}" \
--tag=canary \
--no-traffic \
--update-env-vars=MODAL_ENVIRONMENT=main,LOGFIRE_ENVIRONMENT=prod
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ modal-deploy:
"SUPABASE_KEY=$$SUPABASE_KEY" \
"STORAGE_BUCKET=$$STORAGE_BUCKET" \
--force
@export POLICYENGINE_US_VERSION=$$(grep -A1 'name = "policyengine-us"' uv.lock | grep version | head -1 | sed 's/.*"\(.*\)".*/\1/') && \
@export POLICYENGINE_VERSION=$$(grep -A1 'name = "policyengine"' uv.lock | grep version | head -1 | sed 's/.*"\(.*\)".*/\1/') && \
export POLICYENGINE_US_VERSION=$$(grep -A1 'name = "policyengine-us"' uv.lock | grep version | head -1 | sed 's/.*"\(.*\)".*/\1/') && \
export POLICYENGINE_UK_VERSION=$$(grep -A1 'name = "policyengine-uk"' uv.lock | grep version | head -1 | sed 's/.*"\(.*\)".*/\1/') && \
.github/scripts/modal-deploy-versioned.sh main

Expand Down
1 change: 1 addition & 0 deletions changelog.d/update-policyengine-runtime.changed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Pin the Modal simulation image to the locked policyengine.py version and add a reseed-only database workflow.
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ dependencies = [
"psycopg2-binary>=2.9.10",
"supabase>=2.10.0",
"storage3>=0.8.1",
"policyengine>=3.2.3",
"policyengine-uk==2.75.1",
"policyengine-us==1.666.1",
"policyengine==4.4.4",
"policyengine-uk==2.88.14",
"policyengine-us==1.691.3",
"pydantic>=2.9.2",
"pydantic-settings>=2.6.0",
"rich>=13.9.4",
Expand Down
9 changes: 5 additions & 4 deletions src/policyengine_api/modal/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@

import modal

US_VERSION = os.environ.get("POLICYENGINE_US_VERSION", "1.592.4")
UK_VERSION = os.environ.get("POLICYENGINE_UK_VERSION", "2.75.1")
POLICYENGINE_VERSION = os.environ.get("POLICYENGINE_VERSION", "4.4.4")
US_VERSION = os.environ.get("POLICYENGINE_US_VERSION", "1.691.3")
UK_VERSION = os.environ.get("POLICYENGINE_UK_VERSION", "2.88.14")

base_image = (
modal.Image.debian_slim(python_version="3.13")
.apt_install("libhdf5-dev", "git")
.pip_install("uv")
.run_commands(
"uv pip install --system --upgrade "
"policyengine>=3.2.0 "
f"uv pip install --system --upgrade "
f"policyengine=={POLICYENGINE_VERSION} "
"sqlmodel>=0.0.22 "
"psycopg2-binary>=2.9.10 "
"supabase>=2.10.0 "
Expand Down
35 changes: 18 additions & 17 deletions uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.