Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
91 commits
Select commit Hold shift + click to select a range
df5bdd9
Fix FERC EQR job launch & sensor issues
zaneselvans May 25, 2026
513d30a
Fix dagster location
zaneselvans May 25, 2026
16c3041
background it
zaneselvans May 25, 2026
0c571b9
Omit --location because there is only one
zaneselvans May 25, 2026
3b91384
have to use dagster dev not dg dev or it no work
zaneselvans May 25, 2026
eb6d01a
Merge branch 'main' into ferceqr-sensor-race
zaneselvans May 26, 2026
bab8382
Bigger EQR VM; fix log save path; transactions high memory table
zaneselvans May 26, 2026
e3cc5b5
Merge branch 'main' into ferceqr-sensor-race
zaneselvans May 26, 2026
d1681c8
Merge branch 'main' into ferceqr-sensor-race
zaneselvans May 26, 2026
0a29d53
Refactor FERC EQR deployment sensors and notifications
zaneselvans May 27, 2026
0ddf52c
Shush some logging noise
zaneselvans May 27, 2026
905266e
Use ZULIP_API_KEY not SLACK_TOKEN, raise error on notification failure
zaneselvans May 27, 2026
5bf2ebf
Merge branch 'main' into ferceqr-sensor-race
zaneselvans May 27, 2026
22177e0
Merge branch 'main' into ferceqr-sensor-race
zaneselvans May 27, 2026
f13d673
Merge branch 'main' into ferceqr-sensor-race
zaneselvans May 29, 2026
1802109
wip: backfill-based sensors for FERC EQR
zaneselvans May 29, 2026
f992ed5
Revert Zulip notifications in EQR deployment; keep Slack
zaneselvans May 29, 2026
27bc9c9
Rewrite FERC EQR batch job for Dagster 1.x
zaneselvans May 29, 2026
6d7787e
Revert to dagster-pudl.yaml from main
zaneselvans May 29, 2026
67d15f3
Update docstrings I forgot to save
zaneselvans May 29, 2026
16b8632
Revert some batch container/script changes for simplicity.
zaneselvans May 29, 2026
896f5d2
Refactor FERC EQR deployment config
zaneselvans May 29, 2026
41cbb43
set PUDL_FERCEQR_ARCHIVE_PATH; VS Code chat autoApprove
zaneselvans May 29, 2026
0c8e6ab
Clean up FERCEQR sentinel files
zaneselvans May 30, 2026
3bc80c5
Add FERCEQR deployment preflight checks
zaneselvans May 30, 2026
7787453
Deploy only requested FERCEQR partitions
zaneselvans May 30, 2026
db0b0b4
Add FERCEQR test deployment mode
zaneselvans May 30, 2026
fb5e3f1
Generalize and improve path permission checking CLI
zaneselvans May 31, 2026
96ddba9
Tweak deployment action & script
zaneselvans May 31, 2026
297d5a6
Simplify EQR GHA Workflow
zaneselvans May 31, 2026
73d26d1
Merge branch 'main' into ferceqr-sensor-race
zaneselvans May 31, 2026
2bccc9c
Allow high memory assets to run pandera schema checks
zaneselvans May 31, 2026
c478379
Simplify pudl_batch.sh based on learning from ferceqr_batch.sh
zaneselvans May 31, 2026
614d8e5
Cleanup of ferceqr_batch.sh
zaneselvans May 31, 2026
722a18f
Exclude ferceqr_deployment group from PUDL jobs
zaneselvans May 31, 2026
77a40b5
Tweak markdown notifications.
zaneselvans May 31, 2026
7beffd3
Tweak message formatting; disable transactions deep schema check.
zaneselvans May 31, 2026
c349d93
Merge branch 'ferceqr-sensor-race' into pudl-better-batch
zaneselvans May 31, 2026
cf16c62
Tweak EQR notification messages
zaneselvans May 31, 2026
15e7532
Merge branch 'ferceqr-sensor-race' into pudl-better-batch
zaneselvans May 31, 2026
800a14f
Add high-memory assets back in. Polars update no fix
zaneselvans Jun 1, 2026
f4ccb34
Merge branch 'ferceqr-sensor-race' into pudl-better-batch
zaneselvans Jun 1, 2026
285b448
Merge branch 'main' into pudl-better-batch
zaneselvans Jun 8, 2026
a1c36af
Merge branch 'main' into pudl-better-batch
zaneselvans Jun 8, 2026
31ef085
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 8, 2026
9f95f2a
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 8, 2026
c3b8bc9
Simplify UPath permission checking script slightly.
zaneselvans Jun 9, 2026
e70f024
Consolidate local/remote path validation into one Pydantic validator.
zaneselvans Jun 9, 2026
a76b05e
Clean up FERC EQR sensors and deployment
zaneselvans Jun 9, 2026
6e7ded9
Don't repeat definition of FERCEQR_BACKFILL_TAG constant.
zaneselvans Jun 9, 2026
ab0ead9
Simplify EQR deploy helper functions
zaneselvans Jun 9, 2026
597576a
Stop excluding ferceqr from test coverage; lower fail_under threshold
zaneselvans Jun 9, 2026
de5fba9
Rename misleading FERCEQR_BACKFILL_TAG to DAGSTER_BACKFILL_TAG
zaneselvans Jun 9, 2026
218bd38
Better sensor docstrings
zaneselvans Jun 9, 2026
b175823
Add some comments in the dagster API munging functions
zaneselvans Jun 9, 2026
3000560
Improve comments in ferceqr deploy
zaneselvans Jun 9, 2026
ad75285
Better logging message
zaneselvans Jun 9, 2026
daea6d9
Atomic staging-then-rename FERC EQR deployment; better timeout forensics
zaneselvans Jun 9, 2026
2fbcb20
Consolidate and parametrize Dagster unit tests
zaneselvans Jun 9, 2026
68055c6
Temporarily bump VM resources for fast test run
zaneselvans Jun 9, 2026
7b061ab
Re-order notifications in build-deploy-ferceqr workflow.
zaneselvans Jun 9, 2026
f112164
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 9, 2026
337e52e
Bump pixi Dockerfile version
zaneselvans Jun 9, 2026
4e190c6
Log traceback when _promote_staging() fails and send Zulip notification.
zaneselvans Jun 10, 2026
351fee9
Fix staging cleanup and shush EQR extract logging
zaneselvans Jun 10, 2026
55f5ac8
Suppress DuckDB progress bars; try to fix cloud path cleanup issues
zaneselvans Jun 10, 2026
634856d
Silence DuckDB progress bars in other places.
zaneselvans Jun 10, 2026
d0c4653
Guard against trying to remove paths that don't exist.
zaneselvans Jun 10, 2026
8f81e9c
Drop concurrency to 10 runs; fix wayward logger name
zaneselvans Jun 10, 2026
fb84fea
Add requester_pays=True to gcs deployment target args...
zaneselvans Jun 10, 2026
bf4be5e
Actually pass storage_options all the way through function calls
zaneselvans Jun 10, 2026
b952f43
Add preflight-failure notification + target in launch notification
zaneselvans Jun 10, 2026
b542162
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 11, 2026
3a21c32
Reduce devcontainer size by not installing coding harnesses.
zaneselvans Jun 12, 2026
6c21f62
Track and report FERC EQR deploy duration alongside backfill duration
zaneselvans Jun 12, 2026
0613f09
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 12, 2026
6d98dfd
Add some missing datasets to README.rst
zaneselvans Jun 12, 2026
33163fc
Update README data sources & sustainer tiers
zaneselvans Jun 12, 2026
67a45df
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 13, 2026
4081ebb
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 15, 2026
4a3eaf4
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 16, 2026
4e2b78b
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 18, 2026
490ba68
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 18, 2026
2810101
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 19, 2026
321a317
Remove duplicated logic in FERC EQR deployment / staging
zaneselvans Jun 19, 2026
a56b591
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 22, 2026
22d1347
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 23, 2026
54e68c0
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 23, 2026
33fa5ad
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 23, 2026
5d12bcd
Merge branch 'main' into ferceqr-sensor-race
zaneselvans Jun 24, 2026
f15f0b4
Simplify FERC EQR sensor definitions using decorators directly.
zaneselvans Jun 24, 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
3 changes: 3 additions & 0 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
"containerEnv": {
"PUDL_INPUT": "/workspaces/pudl-input",
"PUDL_OUTPUT": "/workspaces/pudl-output",
"PUDL_ROOT_PATH": "/workspaces/pudl",
"PUDL_FERCEQR_ARCHIVE_PATH": "/workspaces/pudl-input/archives.catalyst.coop/ferceqr/",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an ad-hoc path but I needed it to be somehwere inside the container for testing and this seemed better than creating a whole new mount. Also not a terrible path to adopt more broadly for stuff that we need to pull from our GCS archives bucket.

"DAGSTER_HOME": "/workspaces/dagster-home",
"ANTHROPIC_API_KEY": "${localEnv:ANTHROPIC_API_KEY}",
"GEMINI_API_KEY": "${localEnv:GEMINI_API_KEY}",
Expand Down Expand Up @@ -52,6 +54,7 @@
"chat.agent.sandbox.enabled": "off",
"chat.tools.global.autoApprove": true,
"chat.agent.sandbox.allowUnsandboxedCommands": true,
"chat.permissions.default": "autoApprove",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

YOLO

"claudeCode.allowDangerouslySkipPermissions": true,
"claudeCode.initialPermissionMode": "bypassPermissions",
"evenBetterToml.taplo.path": "/home/ubuntu/.pixi/bin/taplo",
Expand Down
10 changes: 5 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ PUDL_FORCE_FERC_TO_SQLITE=true

# Optional: nonstandard path to FERC EQR input data archive.
# Useful for working with local EQR data in development
FERCEQR_ARCHIVE_PATH=/abs/path/to/ferceqr/zipfile/dir
PUDL_FERCEQR_ARCHIVE_PATH=/abs/path/to/ferceqr/zipfile/dir

# Optional: If set to any value, FERCEQR_BUILD triggers deployment of the EQR data after
# the end of the ferceqr job. Read by src/pudl/dagster/sensors.py and
# src/pudl/dagster/assets/__init__.py
FERCEQR_BUILD=true
# Optional: path to a file that specifies FERC EQR deployment targets.
# If unset, local development will skip FERC EQR deployment.
# Production batch runs should point this at the packaged config file inside the repo.
PUDL_FERCEQR_DEPLOYMENT_CONFIG_PATH=/absolute/path/to/ferceqr_deployment_targets.yml

# Optional: required for devcontainer to work correctly.
PUDL_ROOT_PATH=/absolute/path/to/pudl/repo
Expand Down
110 changes: 71 additions & 39 deletions .github/workflows/build-deploy-ferceqr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,39 @@
name: build-deploy-ferceqr
on:
workflow_dispatch:
inputs:

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameters that let us test just a little bit of data while not clobbering the production outputs.

start_partition:
description: First partition (e.g. 2013q3). Optional. If set, requires end_partition. If both unset, process all available data.
required: false
type: string
end_partition:
description: Last partition (e.g. 2013q4). Optional. If set, requires start_partition. If both unset, process all available data.
required: false
type: string
deployment_mode:
description: Deployment target. If none, do not deploy the data.
required: false
default: test
type: choice
options:
- test
- production
- none
schedule:
- cron: "48 0 3 * *" # 00:48 UTC on the third of every month

env:
GCP_BILLING_PROJECT: ${{ secrets.GCP_BILLING_PROJECT }}
GCS_OUTPUT_BUCKET: gs://pudl.catalyst.coop/ferceqr

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These paths are replaced in favor of a configuration file that can specify any number of different deployment targets.

GCS_LOGS_BUCKET: gs://builds.catalyst.coop/ferceqr_logs
S3_OUTPUT_BUCKET: s3://pudl.catalyst.coop/ferceqr
BATCH_JOB_JSON: batch_job.json
BUILD_ID: ""
BATCH_JOB_ID: ""
PUDL_FERCEQR_DEPLOYMENT_CONFIG_PATH: ""
emoji: ":warning:"

jobs:
build_and_deploy_eqr:
name: Build Docker image, push to Docker Hub and deploy to Google Batch
build_and_deploy_ferceqr:
name: Kick off a FERC EQR build and deployment with Google Batch
runs-on: ubuntu-latest
permissions:
contents: write
Expand All @@ -27,6 +45,43 @@ jobs:
with:
fetch-depth: 0

- name: Set environment variables for the FERC EQR batch job
run: |
batch_job_id="$(date +%Y-%m-%d-%H%M)-$(git rev-parse --short HEAD)"
build_id="$(date +%Y-%m-%d-%H%M)-$(git rev-parse --short HEAD)-${{ github.ref_name }}"
case "${{ github.event_name == 'workflow_dispatch' && inputs.deployment_mode || 'production' }}" in
test)
ferceqr_config_path='/home/ubuntu/pudl/src/pudl/package_data/settings/ferceqr_test_deployment_targets.yml'
;;
none)
ferceqr_config_path=''
;;
*)
ferceqr_config_path='/home/ubuntu/pudl/src/pudl/package_data/settings/ferceqr_deployment_targets.yml'
;;
esac
{
echo "BATCH_JOB_ID=$batch_job_id"
echo "BUILD_ID=$build_id"
echo "PUDL_FERCEQR_DEPLOYMENT_CONFIG_PATH=$ferceqr_config_path"
} >> "$GITHUB_ENV"
echo "BUILD_ID: $build_id"
echo "BATCH_JOB_ID: $batch_job_id"
echo "PUDL_FERCEQR_DEPLOYMENT_CONFIG_PATH: $ferceqr_config_path"

- name: Notify Zulip of FERC EQR build launch
if: ${{ always() }}
uses: zulip/github-actions-zulip/send-message@v2
with:
api-key: ${{ secrets.ZULIP_API_KEY }}
email: "build-status-bot@catalyst-cooperative.zulipchat.com"
organization-url: "https://catalyst-cooperative.zulipchat.com"
type: "stream"
to: "pudl-deployments"
topic: "build-deploy-ferceqr"
content: >
:rocket: Launching FERC EQR Build: ${{ env.BUILD_ID }}; :bulls_eye: Target: ${{ inputs.deployment_mode }}

- name: Docker Metadata
id: docker_metadata
uses: docker/metadata-action@v6
Expand Down Expand Up @@ -59,30 +114,17 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max

- id: "auth"
- name: Authenticate with Google Cloud
id: "gcloud-auth"
uses: "google-github-actions/auth@v3"
with:
workload_identity_provider: "projects/345950277072/locations/global/workloadIdentityPools/gh-actions-pool/providers/gh-actions-provider"
service_account: "deploy-pudl-github-action@catalyst-cooperative-pudl.iam.gserviceaccount.com"

- name: Set action environment variables
run: |
{
echo "BATCH_JOB_ID=$(date +%Y-%m-%d-%H%M)-$(git rev-parse --short HEAD)";
echo "BUILD_ID=$(date +%Y-%m-%d-%H%M)-$(git rev-parse --short HEAD)-${{ github.ref_name }}";
} >> "$GITHUB_ENV"

- name: Show freshly set envvars
run: |
echo "BUILD_ID: $BUILD_ID"
echo "BATCH_JOB_ID: $BATCH_JOB_ID"

# Setup gcloud CLI
- name: Set up Cloud SDK
- name: Set up Google Cloud SDK
id: "gcloud-sdk"
uses: google-github-actions/setup-gcloud@v3

# Deploy PUDL image to GCE
# Dagster Postgres connection configured in builds/dagster.yaml - otherwise we get a str for port num
Comment on lines -84 to -85

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed the postgresql DB since it turns out it's no longer necessary.

- name: Make GCP Batch config file
run: |-
./devtools/generate_batch_config.py \
Expand All @@ -96,32 +138,22 @@ jobs:
--container-env AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} \
--container-env BUILD_REF=${{ github.ref_name }} \
--container-env BUILD_ID=${{ env.BUILD_ID }} \
--container-env FERCEQR_START_PARTITION=${{ github.event_name == 'workflow_dispatch' && inputs.start_partition || '' }} \
--container-env FERCEQR_END_PARTITION=${{ github.event_name == 'workflow_dispatch' && inputs.end_partition || '' }} \
Comment on lines +141 to +142

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Necessary to be able to process just a little bit of EQR. As a treat.

--container-env FERCEQR_BUILD=true \
--container-env PUDL_FERCEQR_ARCHIVE_PATH=gs://archives.catalyst.coop/ferceqr/published \
--container-env PUDL_FERCEQR_DEPLOYMENT_CONFIG_PATH="${{ env.PUDL_FERCEQR_DEPLOYMENT_CONFIG_PATH }}" \
--container-env ZULIP_API_KEY=${{ secrets.ZULIP_API_KEY }} \
--container-env GCP_BILLING_PROJECT=${{ secrets.GCP_BILLING_PROJECT }} \
--container-env GCS_OUTPUT_BUCKET=${{ env.GCS_OUTPUT_BUCKET }} \
--container-env GCS_LOGS_BUCKET=${{ env.GCS_LOGS_BUCKET }} \
--container-env S3_OUTPUT_BUCKET=${{ env.S3_OUTPUT_BUCKET }} \
--container-env GITHUB_ACTION_TRIGGER=${{ github.event_name }} \
--container-env OMP_NUM_THREADS=4 \
--container-env OMP_NUM_THREADS=8 \
--container-env PUDL_BOT_PAT=${{ secrets.PUDL_BOT_PAT }} \
--vcpu 16 \
--mem-gb 127 \
--disk-gb 1000 \
--output ${{ env.BATCH_JOB_JSON }}

- name: Send notification to Zulip build status stream
if: ${{ always() }}
uses: zulip/github-actions-zulip/send-message@v2
with:
api-key: ${{ secrets.ZULIP_API_KEY }}
email: "build-status-bot@catalyst-cooperative.zulipchat.com"
organization-url: "https://catalyst-cooperative.zulipchat.com"
type: "stream"
to: "pudl-deployments"
topic: "FERC EQR Builds"
content: >
:rocket: Launching FERC EQR Build: ${{ env.BUILD_ID }}

# Start the batch job
- name: Launch Google Batch job
run: gcloud batch jobs submit run-ferceqr-etl-${{ env.BATCH_JOB_ID }} --config ${{ env.BATCH_JOB_JSON }} --location us-east1

Expand All @@ -143,6 +175,6 @@ jobs:
organization-url: "https://catalyst-cooperative.zulipchat.com"
type: "stream"
to: "pudl-deployments"
topic: "FERC EQR Builds"
topic: "build-deploy-ferceqr"
content: >
${{ env.emoji }} Google Batch job for ${{ env.BUILD_ID }} launched with status: ${{ job.status }}.
9 changes: 0 additions & 9 deletions .secrets.baseline

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

6 changes: 4 additions & 2 deletions builds/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ ENV DAGSTER_HOME=${CONTAINER_PUDL_WORKSPACE}/dagster_home

RUN mkdir -p ${PUDL_INPUT} ${PUDL_OUTPUT} ${DAGSTER_HOME} ${PUDL_ROOT_PATH}

# Copy dagster configuration file
COPY builds/dagster.yaml ${DAGSTER_HOME}/dagster.yaml
# Copy job-specific dagster configuration files; each batch script selects
# the appropriate one at startup by copying it to $DAGSTER_HOME/dagster.yaml.
COPY builds/dagster-pudl.yaml ${DAGSTER_HOME}/dagster-pudl.yaml
COPY builds/dagster-ferceqr.yaml ${DAGSTER_HOME}/dagster-ferceqr.yaml
Comment on lines +50 to +51

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the moment these need different dagster configurations. The individual scripts rename their respective config file to dagster.yml.


# Copy the entire PUDL repo into the image.
# We can't install the PUDL package without .git/ because the version is dynamically
Expand Down
5 changes: 5 additions & 0 deletions builds/dagster-ferceqr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
run_coordinator:
module: dagster
class: QueuedRunCoordinator
config:
max_concurrent_runs: 10
Empty file added builds/dagster-pudl.yaml

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previously this had the postgresql setup in it, but it turns out that SQLite now works fine for Dagster's event logging, so we don't need postgres any more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool that this is working with SQLite. Without the postgres setup we might be able to migrate everything into python.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for shits and giggles I tried disabling postgres on the PUDL build too, and it also worked fine with SQLite.

Empty file.
8 changes: 0 additions & 8 deletions builds/dagster.yaml

This file was deleted.

Loading