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
14 changes: 14 additions & 0 deletions .github/workflows/check-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,17 @@ jobs:

- name: Check release metadata
run: python scripts/check-release.py

# Build + install + import the wheel here rather than in the regen workflow.
# This job runs on any PR touching pyproject.toml/CHANGELOG.md — which every
# regen PR does (version bump + seeded changelog) — so a packaging or import
# regression surfaces as red CI on the PR instead of silently aborting the
# regen before it can open one. (Step name kept stable to preserve the

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

super nit: the parenthetical "Step name kept stable to preserve the required-check / branch-protection wiring" is misleading (not blocking). Required status checks key off the job name (check / "Verify changelog matches version bump"), not step names — and this step's name actually changed from the old regen step ("Verify built wheel installs and imports" → "Build, install, and import the wheel"). So nothing was kept stable here, and step naming has no bearing on branch protection. Consider dropping that clause so a future maintainer doesn't preserve the step name thinking it matters for required checks.

# required-check / branch-protection wiring.)
- name: Build, install, and import the wheel
run: |
python -m pip install --upgrade build
python -m build
python -m pip install dist/*.whl
# cd away from the source tree so the import resolves against the installed wheel.
cd /tmp && python -c "import hotdata; print(hotdata.__version__)"
63 changes: 54 additions & 9 deletions .github/workflows/regenerate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,15 @@ jobs:
https://api.github.com/repos/hotdata-dev/www.hotdata.dev/contents/api/openapi.yaml \
-o openapi.yaml

- name: Clean existing source
run: rm -rf src/
# Remove the generator-owned subtrees before regenerating so endpoints and
# models dropped from the spec don't linger as orphaned files. The package
# lives in hotdata/, so the previous `rm -rf src/` was a no-op and removed
# APIs (e.g. the sandbox endpoints) kept shipping as dead modules. The
# hand-written modules (hotdata/_auth.py, hotdata/arrow.py) live at the
# package root and are untouched; the integration tests in tests/ (plural)
# are distinct from the generated test/ (singular) unit tests.
- name: Clean generated source
run: rm -rf hotdata/api hotdata/models docs test

# pyproject.toml is hand-maintained (see .openapi-generator-ignore), so the
# generator no longer stamps the version. Bump the patch version directly,
Expand All @@ -71,6 +78,43 @@ jobs:
)
echo "version=$version" >> "$GITHUB_OUTPUT"

# check-release.yml gates merges on a `## [x.y.z]` CHANGELOG section
# matching the bumped version, so without a seeded entry every regen PR
# fails that check. Insert a stub (the spec-change title under ### Changed)
# just above the most recent released section; the PR author refines the
# wording before merge. Idempotent: skips if a section for this version
# already exists.
- name: Seed changelog entry
env:
VERSION: ${{ steps.pkg.outputs.version }}
TITLE: ${{ inputs.title }}
run: |
export CHANGELOG_DATE=$(date -u +%Y-%m-%d)
python3 - <<'PY'
import os, pathlib, re
version = os.environ["VERSION"]
date = os.environ["CHANGELOG_DATE"]
title = (os.environ.get("TITLE") or "").strip() \
or "Regenerate the client from the updated Hotdata OpenAPI spec"
path = pathlib.Path("CHANGELOG.md")
text = path.read_text()
if re.search(rf"^## \[{re.escape(version)}\]", text, re.M):
print(f"CHANGELOG already has a [{version}] section; leaving it untouched.")
raise SystemExit(0)
unreleased = re.search(r"^## \[Unreleased\]", text, re.M)
if not unreleased:
raise SystemExit("CHANGELOG.md has no '## [Unreleased]' section to anchor the new entry")
# Insert before the first released section after [Unreleased] (falling
# back to end of file) so any pending entries under [Unreleased] stay
# attributed to it rather than being absorbed by the new version.
nxt = re.search(r"^## \[", text[unreleased.end():], re.M)
insert_at = unreleased.end() + nxt.start() if nxt else len(text)
entry = f"## [{version}] - {date}\n\n### Changed\n\n- {title}\n\n"
text = text[:insert_at] + entry + text[insert_at:]
path.write_text(text)
print(f"Inserted CHANGELOG [{version}] section.")
PY

- name: Generate client
run: |
npx @openapitools/openapi-generator-cli generate \
Expand Down Expand Up @@ -234,13 +278,14 @@ jobs:
rm -f openapi.yaml
rm -f .github/workflows/python.yml

- name: Verify built wheel installs and imports
run: |
python -m pip install --upgrade build
python -m build
python -m pip install dist/*.whl
# cd away from the source tree so the import resolves against the installed wheel.
cd /tmp && python -c "import hotdata; print(hotdata.__version__)"
# NOTE: regeneration deliberately does NOT build/import the package. A

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

super nit: the rationale is sound, but note one small coverage gap (not blocking): the old step ran python -m build + installed the wheel, whereas integration-tests.yml only does pip install -e . (editable). So a packaging/wheel-build regression (sdist/MANIFEST, build-backend config) now surfaces only at publish time, not on the regen PR. Low risk here since pyproject.toml is hand-maintained and ignored by the generator, so regen rarely touches packaging — just worth being aware of.

# failure here used to abort the job before "Create PR", so a regen that
# produced valid-but-not-yet-wired output failed silently with no PR to act
# on. The PR is the artifact we want, and breakage surfaces on it as red CI:
# integration-tests.yml installs the package (`pip install -e .`) and runs
# pytest, and check-release.yml builds + installs + imports the wheel on
# every PR that bumps pyproject.toml/CHANGELOG.md (which every regen PR
# does). Auto-merge is gated on those checks, so a broken regen can't merge.

- name: Check integration test scenario parity
env:
Expand Down