From 0707e1d1412b7ee57c56bbd673a74c08c008d365 Mon Sep 17 00:00:00 2001 From: Rohan Dsouza Date: Mon, 27 Jul 2026 20:31:54 +0530 Subject: [PATCH 1/2] chore: fix release.sh so release PRs pass CI, add publish-workflow.sh `release.sh prepare` bumped pyproject.toml and CHANGELOG.md but never relocked. uv.lock records this project's own version and ci.yml installs with `uv sync --locked`, so every release PR the script opened failed CI before it could be reviewed. Reproduced by bumping to 0.3.0 and running `uv lock --locked`: "The lockfile at uv.lock needs to be updated, but --locked was provided." Now runs `uv lock` and commits uv.lock alongside, and requires uv up front rather than failing midway. default_branch() chained `sed` into `||` fallbacks, but sed always exits 0, so neither fallback could ever run. Against a remote with no origin/HEAD it returned the empty string, and the caller then ran `git fetch origin ""`. Verified before and after in a scratch repo: [] -> [main]. Both fixes are taken from hotdata-dlt-destination, which shares this repo's --locked CI. publish-workflow.sh was the one release script missing here; it is byte-identical across the sibling repos and regenerates the checked-in publish.yml exactly (verified by diff). No package code changes, so no CHANGELOG entry. --- scripts/publish-workflow.sh | 75 +++++++++++++++++++++++++++++++++++++ scripts/release.sh | 20 ++++++++-- 2 files changed, 91 insertions(+), 4 deletions(-) create mode 100755 scripts/publish-workflow.sh diff --git a/scripts/publish-workflow.sh b/scripts/publish-workflow.sh new file mode 100755 index 0000000..713f872 --- /dev/null +++ b/scripts/publish-workflow.sh @@ -0,0 +1,75 @@ +#!/usr/bin/env bash +# Generate publish.yml for a package. Usage: publish-workflow.sh hotdata-framework +set -euo pipefail +pkg="${1:?package name}" +cat <&2 + exit 1 + fi + tag="\${GITHUB_REF_NAME#v}" + pkg_version=\$(python -c "import tomllib,pathlib; print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])") + if [ "\$tag" != "\$pkg_version" ]; then + echo "Release tag (\$tag) does not match pyproject.toml version (\$pkg_version)" >&2 + exit 1 + fi + + - name: Build sdist and wheel + run: python -m build + + - name: Check distribution metadata + run: python -m twine check --strict dist/* + + - uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5 + with: + name: dist + path: dist/ + + publish: + name: Publish to PyPI + needs: build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/${pkg} + permissions: + id-token: write + steps: + - uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5 + with: + name: dist + path: dist/ + + - name: Publish via Trusted Publishing + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 +EOF diff --git a/scripts/release.sh b/scripts/release.sh index 03aaeae..a9759e4 100755 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -82,9 +82,18 @@ PY default_branch() { local remote="${1:-origin}" - git symbolic-ref --quiet "refs/remotes/${remote}/HEAD" 2>/dev/null | sed "s|refs/remotes/${remote}/||" \ - || { git branch -r | sed -n "s|^ ${remote}/\\(main\\|master\\)$|\\1|p" | head -1; } \ - || echo main + local branch + branch="$(git symbolic-ref --quiet "refs/remotes/${remote}/HEAD" 2>/dev/null | sed "s|refs/remotes/${remote}/||")" + if [[ -n "$branch" ]]; then + echo "$branch" + return + fi + branch="$(git branch -r --list "${remote}/main" "${remote}/master" | sed "s|^[[:space:]]*${remote}/||" | head -1)" + if [[ -n "$branch" ]]; then + echo "$branch" + return + fi + echo main } ensure_clean() { @@ -103,6 +112,7 @@ cmd_prepare() { [[ -n "$bump" ]] || { usage; die "missing bump kind or explicit version"; } need gh need python3 + need uv ensure_clean local current new base branch pkg @@ -122,10 +132,12 @@ cmd_prepare() { set_version "$new" update_changelog "$new" + # uv.lock records this project's own version, and CI installs with --locked. + uv lock branch="release/v${new}" git checkout -b "$branch" - git add pyproject.toml CHANGELOG.md + git add pyproject.toml CHANGELOG.md uv.lock git commit -m "chore: release v${new}" pkg="$(get_pkg_name)" From ea14c76ff84ac3ac5eb62a54070ff171fdfd0713 Mon Sep 17 00:00:00 2001 From: Rohan Dsouza Date: Mon, 27 Jul 2026 20:50:14 +0530 Subject: [PATCH 2/2] docs: note the uv prerequisite in RELEASING.md prepare now calls need uv, so the one-time setup list was incomplete. --- RELEASING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/RELEASING.md b/RELEASING.md index 0b50ff4..41dc1e2 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -5,6 +5,7 @@ Every release uses `./scripts/release.sh`. Do not bump versions, tag, or create ## One-time setup - Install [GitHub CLI](https://cli.github.com/) (`gh`) and authenticate. +- Install [uv](https://docs.astral.sh/uv/). `prepare` relocks `uv.lock` with it, since the lock file records this project's own version and CI installs with `uv sync --locked`. - Ensure PyPI [trusted publishing](https://docs.pypi.org/trusted-publishers/) is configured for this repo (`publish.yml` uses the `pypi` GitHub environment). ## Release steps