Skip to content

Forecast

Forecast #554

Workflow file for this run

name: Forecast
on:
schedule:
# :08 and :38 of every hour — aligned with GFZ 30-min nowcast cadence,
# with an offset that gives publishers time to post and absorbs Actions
# scheduler drift.
- cron: '8,38 * * * *'
workflow_dispatch:
inputs:
now:
description: 'Pin anchor time (ISO8601, e.g. 2026-04-24T12:00:00). Leave empty for live run.'
required: false
default: ''
permissions:
contents: write
pages: write
id-token: write
concurrency:
group: forecast
cancel-in-progress: false
env:
ASSETS_TAG: v0.1.1-assets
REALTIME_REPO: eunsu-park/realtime-regression-sw
jobs:
build-and-deploy:
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: vendor/realtime-regression-sw/requirements.txt
- name: Install CPU-only PyTorch
run: pip install torch --index-url https://download.pytorch.org/whl/cpu
- name: Install realtime dependencies
run: pip install -r vendor/realtime-regression-sw/requirements.txt
- name: Cache checkpoint assets
id: cache-checkpoint
uses: actions/cache@v4
with:
path: vendor/realtime-regression-sw/checkpoint
key: release-${{ env.ASSETS_TAG }}
- name: Download checkpoint + stats
if: steps.cache-checkpoint.outputs.cache-hit != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p vendor/realtime-regression-sw/checkpoint
gh release download "$ASSETS_TAG" \
--repo "$REALTIME_REPO" \
--dir vendor/realtime-regression-sw/checkpoint \
--pattern 'model_best.pth' \
--pattern 'table_stats.pkl'
- name: Run inference
id: infer
working-directory: vendor/realtime-regression-sw
run: |
set +e
ARGS="--config ../../configs/realtime.ci.yaml --device cpu --verbose"
if [ -n "${{ inputs.now }}" ]; then
ARGS="$ARGS --now ${{ inputs.now }}"
fi
python scripts/run_realtime.py $ARGS
CODE=$?
echo "exit_code=$CODE" >> "$GITHUB_OUTPUT"
# Never fail this step — failure handling is done in update_site_data.py.
exit 0
- name: Update site data
run: python scripts/update_site_data.py --exit-code ${{ steps.infer.outputs.exit_code }}
- name: Commit site data
run: |
git config user.name 'github-actions[bot]'
git config user.email 'github-actions[bot]@users.noreply.github.com'
git add site/data
if git diff --cached --quiet; then
echo "No site data changes to commit."
else
git commit -m "chore: update forecast data ($(date -u +%Y-%m-%dT%H:%M:%SZ))"
git push
fi
- name: Job summary
if: always()
run: |
echo "## Forecast run" >> "$GITHUB_STEP_SUMMARY"
echo "- Inference exit code: ${{ steps.infer.outputs.exit_code }}" >> "$GITHUB_STEP_SUMMARY"
if [ -f site/data/latest.json ]; then
python - <<'PY' >> "$GITHUB_STEP_SUMMARY"
import json, pathlib
d = json.loads(pathlib.Path("site/data/latest.json").read_text())
f = d["forecast"][0]
print(f"- Anchor: `{d['anchor_timestamp_utc']}`")
print(f"- First horizon ({f['horizon_minutes']} min): ap30 = {f['ap30']:.2f}")
PY
fi
- uses: actions/configure-pages@v5
- uses: actions/upload-pages-artifact@v3
with:
path: site
- name: Deploy to Pages
id: deploy
uses: actions/deploy-pages@v4