-
Notifications
You must be signed in to change notification settings - Fork 0
ci: standardize release process #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7b970b1
19fb878
1a88941
d30cb94
6de937c
5e30081
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| name: Check release metadata | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'pyproject.toml' | ||
| - 'CHANGELOG.md' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| check: | ||
| name: Verify changelog matches version bump | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | ||
| with: | ||
| fetch-depth: 0 | ||
|
|
||
| - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | ||
| with: | ||
| python-version: '3.12' | ||
|
|
||
| - name: Check release metadata | ||
| run: python scripts/check-release.py |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: ["main", "master"] | ||
| pull_request: | ||
|
|
||
| concurrency: | ||
| group: ci-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| test: | ||
| name: Test (Python 3.12) | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | ||
|
|
||
| - uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v6 | ||
| with: | ||
| enable-cache: true | ||
|
|
||
| - name: Set up Python | ||
| run: uv python install 3.12 | ||
|
|
||
| - name: Install dependencies | ||
| run: uv sync --locked | ||
|
|
||
| - name: Test | ||
| run: uv run pytest -v |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| name: GitHub Release | ||
|
|
||
| on: | ||
| push: | ||
| tags: | ||
| - 'v[0-9]*' | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| jobs: | ||
| release: | ||
| name: Create GitHub Release | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | ||
|
|
||
| - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 | ||
| with: | ||
| python-version: '3.12' | ||
|
|
||
| - name: Read package metadata | ||
| id: meta | ||
| run: | | ||
| pkg_name=$(python -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['name'])") | ||
| pkg_version="${GITHUB_REF_NAME#v}" | ||
| echo "name=${pkg_name}" >> "$GITHUB_OUTPUT" | ||
| echo "version=${pkg_version}" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Extract changelog notes | ||
| id: notes | ||
| run: | | ||
| set -euo pipefail | ||
| version="${GITHUB_REF_NAME#v}" | ||
| if [[ -f CHANGELOG.md ]]; then | ||
| body="$(python scripts/extract-changelog.py "$version")" | ||
| else | ||
| body="Release ${version}." | ||
| fi | ||
| delimiter="EOF_${RANDOM}_${RANDOM}" | ||
| { | ||
| echo "body<<${delimiter}" | ||
| echo "$body" | ||
| echo "${delimiter}" | ||
| } >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Create GitHub Release | ||
| uses: softprops/action-gh-release@1e812e8210a4a8a0b23075e5795f2a4e2b2a0b7 # v2.2.2 | ||
| with: | ||
| tag_name: ${{ github.ref_name }} | ||
| name: ${{ steps.meta.outputs.name }} ${{ steps.meta.outputs.version }} | ||
| body: ${{ steps.notes.outputs.body }} | ||
| generate_release_notes: false | ||
| make_latest: true | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| # Changelog | ||
|
|
||
| All notable changes to this project will be documented in this file. | ||
|
|
||
| The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), | ||
| and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
|
||
| ## [Unreleased] | ||
|
|
||
| ## [0.2.0] - 2026-05-24 | ||
|
|
||
| ### Changed | ||
|
|
||
| - Switch managed database operations from the connections API to the dedicated `/databases` API (`hotdata>=0.2.3` required). | ||
| - `create_managed_database` first parameter renamed from `name` to `description` (keyword-only). | ||
| - `ManagedDatabase` dataclass: replace `name`/`source_type` fields with `description`/`default_connection_id`. | ||
| - `resolve_managed_database` tries direct ID lookup first, then falls back to a description scan. | ||
| - `list_managed_databases` now fetches all databases regardless of source type. | ||
| - `list_managed_tables`, `load_managed_table`, and `delete_managed_table` use `default_connection_id` instead of database `id` for connection-scoped operations. | ||
|
|
||
| ### Added | ||
|
|
||
| - `create_managed_database` accepts an optional `expires_at` parameter. | ||
|
|
||
| ### Removed | ||
|
|
||
| - `MANAGED_SOURCE_TYPE`, `build_managed_config`, and `create_connection_request` removed from the public API. | ||
|
|
||
| ## [0.1.1] - 2026-05-19 | ||
|
|
||
| ### Added | ||
|
|
||
| - Managed database helpers on `HotdataClient`. | ||
|
|
||
| ## [0.1.0] - 2026-05-06 | ||
|
|
||
| ### Added | ||
|
|
||
| - Initial release. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # Releasing | ||
|
|
||
| Every release uses `./scripts/release.sh`. Do not bump versions, tag, or create GitHub Releases manually. | ||
|
|
||
| ## One-time setup | ||
|
|
||
| - Install [GitHub CLI](https://cli.github.com/) (`gh`) and authenticate. | ||
| - Ensure PyPI [trusted publishing](https://docs.pypi.org/trusted-publishers/) is configured for this repo (`publish.yml` uses the `pypi` GitHub environment). | ||
|
|
||
| ## Release steps | ||
|
|
||
| 1. Add user-facing notes under `## [Unreleased]` in `CHANGELOG.md`. | ||
| 2. Prepare the release PR: | ||
|
|
||
| ```bash | ||
| ./scripts/release.sh prepare patch # or minor | major | 1.2.3 | ||
| ``` | ||
|
|
||
| 3. Merge the PR after CI passes (including the changelog check). | ||
| 4. Publish from a clean default branch checkout: | ||
|
|
||
| ```bash | ||
| git checkout main # or master for hotdata-marimo | ||
| git pull | ||
| ./scripts/release.sh publish | ||
| ``` | ||
|
|
||
| ## What happens automatically | ||
|
|
||
| Pushing a `vX.Y.Z` tag triggers two workflows: | ||
|
|
||
| | Workflow | Purpose | | ||
| |----------|---------| | ||
| | `publish.yml` | Build wheel/sdist and publish to PyPI | | ||
| | `release.yml` | Create the GitHub Release with notes from `CHANGELOG.md` | | ||
|
|
||
| ## Enforcement | ||
|
|
||
| - **PR check** (`check-release.yml`): if `pyproject.toml` version changes, `CHANGELOG.md` must contain a matching `## [X.Y.Z]` section. | ||
| - **Tag check** (`publish.yml`): the tag (without `v`) must match `[project].version` in `pyproject.toml`. | ||
| - **Publish guard** (`release.sh publish`): refuses to tag if the changelog section is missing. | ||
|
|
||
| Together, these make it hard to ship a version without changelog notes or a GitHub Release. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: using
EOFas the heredoc delimiter for multilineGITHUB_OUTPUTis fragile — if any future changelog entry contains a line that is exactlyEOF, this step will produce a malformed output and the release notes will be wrong or the step will fail. GitHub's own docs recommend a random delimiter. (not blocking)