diff --git a/README.md b/README.md index 9952543..cbed687 100644 --- a/README.md +++ b/README.md @@ -114,28 +114,7 @@ This package bundles a pinned `gomc-rest` binary (currently **v1.4.0**, set in that raises its minimum server version can't be installed without also bumping the bundled binary. -## Releasing / bundled binaries - -The bundled server version is pinned in `GOMC_REST_VERSION`. Binaries are not -committed to git; they are fetched from the matching gomc-rest GitHub release. - -- Locally: `python scripts/vendor_binaries.py` downloads all three binaries - into `src/gomc_rest/binaries/`, verifying each against the trusted SHA-256 - values committed in `checksums/.sha256`. -- On a `v*` tag, `.github/workflows/release.yml` builds one platform-specific - wheel per OS (each bundling only its matching binary) and publishes to PyPI - via trusted publishing. The release job verifies the tag equals - `project.version`; `workflow_dispatch` builds wheels for verification only and - never publishes. - -To cut a release: - -1. To change the bundled server, edit `GOMC_REST_VERSION` (keep it within the - range accepted by the pinned `gomc-rest-client`) and add a matching - `checksums/.sha256` with the trusted SHA-256 of each asset. If the - new binaries change their glibc requirement, update the `plat` tags in - `release.yml` accordingly. -2. Bump the package version in **both** `pyproject.toml` (`project.version`) - and `src/gomc_rest/__init__.py` (`__version__`) — they must match. -3. Tag that exact version, e.g. `git tag v0.2.0 && git push origin v0.2.0` - (the tag must equal `project.version` or the release job fails). +## Development + +Release procedure and bundled-binary maintenance are documented in +[RELEASING.md](https://github.com/Moge800/gomc_rest_python/blob/main/RELEASING.md). diff --git a/README_JP.md b/README_JP.md index ac8cab6..7285af5 100644 --- a/README_JP.md +++ b/README_JP.md @@ -125,28 +125,8 @@ finally: これにより、より新しいサーバーを必要とするクライアントが意図せず インストールされることを防ぎます。 -## リリースと同梱バイナリ +## 開発者向け -バイナリはGitリポジトリへコミットせず、対応するgomc-restのGitHub Releaseから -取得します。 - -- ローカルでは `python scripts/vendor_binaries.py` を実行すると、3種類の - バイナリが `src/gomc_rest/binaries/` にダウンロードされます。各ファイルは - `checksums/.sha256` に記録されたSHA-256ハッシュと照合されます。 -- `v*` タグをpushすると、`.github/workflows/release.yml` がOS別の `wheel` と - クライアント専用の `sdist` をビルドし、PyPIのTrusted Publishingを使用して - 公開します。`workflow_dispatch` では検証用のビルドのみを行い、公開しません。 - -### リリース手順 - -1. 同梱サーバーを変更する場合は `GOMC_REST_VERSION` を更新し、各バイナリの - SHA-256ハッシュを記載した `checksums/.sha256` を追加します。 - 必要なglibcバージョンが変わる場合は、`release.yml` の `plat` タグも更新します。 -2. `pyproject.toml` の `project.version` と - `src/gomc_rest/__init__.py` の `__version__` を同じバージョンへ更新します。 -3. パッケージバージョンと同じタグを作成してpushします。 - -```bash -git tag v0.2.0 -git push origin v0.2.0 -``` +リリース手順と同梱バイナリの管理方法は +[RELEASING.md](https://github.com/Moge800/gomc_rest_python/blob/main/RELEASING.md) +を参照してください。 diff --git a/RELEASING.md b/RELEASING.md new file mode 100644 index 0000000..2073510 --- /dev/null +++ b/RELEASING.md @@ -0,0 +1,72 @@ +# Releasing + +Maintainer notes. Users don't need anything here — see [README.md](README.md). + +## What a tag push does + +Pushing a `v*` tag runs `.github/workflows/release.yml`: + +1. **Guard** — the tag must equal `project.version` in `pyproject.toml`, + or every job fails immediately. +2. **Build wheels** (one per platform, each bundling only its matching + server binary, downloaded and SHA-256-verified at build time): + - `win_amd64` — `gomc-rest.exe` + - `manylinux_2_34_x86_64` — `gomc-rest-linux-amd64` (dynamically linked, + needs glibc ≥ 2.34; hence the 2_34 tag) + - `manylinux2014_aarch64` — `gomc-rest-linux-arm64` (statically linked) +3. **Build sdist** — no binary; the client-only fallback for platforms + without a wheel (macOS, Windows arm64, older glibc). +4. **Publish to PyPI** — trusted publishing (OIDC) via the `pypi` + environment. `skip-existing` makes re-running a tag safe. +5. **GitHub Release** — created only after PyPI publish succeeds, with + generated notes and all dist files attached as assets. + +`workflow_dispatch` runs the builds for verification but never publishes. + +## Cutting a release + +1. Bump the package version in **both** places (they must match the tag): + - `pyproject.toml` → `project.version` + - `src/gomc_rest/__init__.py` → `__version__` +2. Merge to `main`, then tag that exact version: + + ```bash + git tag v0.2.0 + git push origin v0.2.0 + ``` + +If publish fails transiently, re-run the failed jobs for that tag's run +from the GitHub Actions UI — PyPI skips files it already has, and the +release job then attaches the assets. Only delete and recreate the tag if +the fix requires new commits (which means a new version anyway). + +## Bumping the bundled gomc-rest server + +Only needed when changing the bundled server version: + +1. Edit `GOMC_REST_VERSION`. Keep it within the range accepted by the + pinned `gomc-rest-client` (its `MINIMUM_SUPPORTED_GOMC_REST_VERSION`); + bump the client pin in `pyproject.toml` together if needed. +2. Add `checksums/.sha256` with the trusted SHA-256 of each + release asset (`gomc-rest.exe`, `gomc-rest-linux-amd64`, + `gomc-rest-linux-arm64`). These are committed so a swapped release + asset is detected; vendoring fails closed without them. +3. If the new binaries change their glibc requirement (check with + `readelf -V | grep GLIBC`), update the `plat` tags in + `release.yml` and the CI floor test image in `ci.yml`. + +## Local builds (testing without PyPI) + +```bash +python scripts/vendor_binaries.py # fetch + verify all binaries +python -m build --wheel +python -m wheel tags --platform-tag manylinux_2_34_x86_64 --remove dist/*.whl +rm src/gomc_rest/binaries/gomc-rest* # drop vendored binaries for a clean sdist +python -m build --sdist +``` + +## One-time infrastructure (already done) + +- PyPI trusted publisher: repo `Moge800/gomc_rest_python`, workflow + `release.yml`, environment `pypi`. +- GitHub environment `pypi` on the repository.