Skip to content

ci(publish-python): drop PyPI wheel push, GH Release becomes canonical#44

Merged
ZhiXiao-Lin merged 1 commit into
mainfrom
ci/pypi-out-gh-only
May 24, 2026
Merged

ci(publish-python): drop PyPI wheel push, GH Release becomes canonical#44
ZhiXiao-Lin merged 1 commit into
mainfrom
ci/pypi-out-gh-only

Conversation

@ZhiXiao-Lin
Copy link
Copy Markdown
Contributor

Why

The Python SDK matrix (4 CPython × 3 platforms = 12 wheels per release, ~17 MB each) burned through PyPI's default 10 GB per-project quota and tripped v3.2.0 with `400 Project size too large` mid-upload (verbose error from #43). Even after manually clearing 1.x to drop from 9.99 GB → 1.58 GB, every future release would just refill the budget.

GitHub Releases has no per-project size cap and the workflow already uploads the full wheel set + `python-native-manifest.json` index there. Switch to GH Releases as the canonical wheel host.

Changes

  • `publish-python.yml` — remove the `Publish wheels to PyPI` step entirely.
  • `release.sh` — update the post-release summary text.
  • `README` + `sdk/python/README` — replace `pip install a3s-code` with a concrete GH-Release URL example. Note that ≤3.1.0 remains installable from PyPI.
  • `CHANGELOG` — add a [3.2.0] Packaging note documenting the change.

Follow-ups for you

  • The `PYPI_NATIVE_TOKEN` repo secret is unused now; revoke it from repo settings when convenient.
  • v3.2.0 on PyPI is half-published (1 wheel: cp310 macOS arm64). Decide whether to yank that one wheel so PyPI shows 3.1.0 as the last clean release, or leave it. I haven't touched PyPI state in this PR.
  • If you want `pip install a3s-code` to keep working transparently from v3.2.0 onwards, the natural next step is a tiny pure-Python bootstrap package on PyPI that consults the `python-native-manifest.json` and fetches the right wheel from GH Releases at install time. The manifest is already generated; the consumer side does not exist yet. Happy to set that up as a separate PR if you want.

The Python SDK matrix (4 CPython × 3 platforms = 12 wheels per release,
~17 MB each) burned through PyPI's 10 GB per-project quota and tripped
v3.2.0 with `400 Project size too large` mid-upload. PyPI offers no API
to delete files; even after manually clearing the 1.x series, every
future release would just refill the quota.

GitHub Releases has no per-project size cap and the workflow already
uploads the full wheel set + a `python-native-manifest.json` index
there. Stop pushing to PyPI and call GH Releases the canonical wheel
host.

Changes
- publish-python.yml: remove the `Publish wheels to PyPI` step entirely.
  The `if: startsWith(github.ref, 'refs/tags/')` guards on the GH-Release
  steps stay (they were added for debug dispatch and remain valid for
  branch dispatch).
- release.sh: update the post-release summary text to reflect the new
  Python distribution path.
- README + sdk/python/README: replace `pip install a3s-code` with a
  concrete GH-Release URL example, and explain why. Note that ≤3.1.0
  versions remain installable from PyPI.
- CHANGELOG: add a [3.2.0] Packaging note documenting the change.

PYPI_NATIVE_TOKEN repo secret is now unused — leave for the user to
revoke / delete from repo settings as a separate step.
@ZhiXiao-Lin ZhiXiao-Lin merged commit 1017051 into main May 24, 2026
1 check passed
@ZhiXiao-Lin ZhiXiao-Lin deleted the ci/pypi-out-gh-only branch May 24, 2026 02:09
ZhiXiao-Lin pushed a commit that referenced this pull request May 24, 2026
… from GH Releases

After v3.2.0 stopped publishing native wheels to PyPI (PR #44, GH
Releases is the canonical host), `pip install a3s-code` was broken on
every platform except cp310 macOS arm64 (the one wheel that snuck into
PyPI before the 10 GB project cap kicked in).

This commit restores `pip install a3s-code` by adding a tiny
pure-Python bootstrap package — also named `a3s-code` — that on first
`import a3s_code` downloads the matching native wheel for the current
interpreter and platform, verifies its sha256 against the release
manifest, extracts the compiled `_native` extension into a per-user
cache, and registers it as `sys.modules["a3s_code._native"]`.
Subsequent imports use the cache; cold start is one download per
(version, platform, interpreter) triple.

New package
- sdk/python-bootstrap/ — setuptools-built pure-Python wheel
  (a3s_code-X.Y.Z-py3-none-any.whl) and matching sdist.
  - src/a3s_code/__init__.py — calls ensure_native_loaded() then
    `from ._native import *`.
  - src/a3s_code/_bootstrap.py — wheel-name resolver, downloader,
    sha256 verifier, extension loader. Knobs: A3S_CODE_CACHE_DIR,
    A3S_CODE_RELEASES_BASE_URL, A3S_CODE_SKIP_HASH_CHECK.
  - tests/test_bootstrap.py — 15 unit tests (filename resolution,
    cache dir, sha256 mismatch, idempotency, manifest fallback) plus
    one live download test gated on A3S_CODE_BOOTSTRAP_LIVE=1.
  - README documenting install model and overrides.

Workflow
- publish-python-bootstrap.yml — runs bootstrap unit tests, builds
  wheel + sdist, twine check, twine upload on tag push.
- release.yml — adds the bootstrap publish job; runs after
  publish-python (which produces the GH Release the bootstrap points
  at) and gates github-release on both.

Release plumbing
- scripts/check_release_versions.sh now validates the bootstrap
  pyproject.toml and the runtime __version__ in _bootstrap.py — they
  must equal the core version so the bootstrap finds the matching GH
  Release tag.
- release.sh bumps both in lockstep with the other version files.
- README + sdk/python README rewritten to advertise pip install
  a3s-code again and explain the cache.

Bumps core / Node SDK / Python SDK from 3.2.0 to 3.2.1 since the
bootstrap is a user-facing addition. CHANGELOG [3.2.1] entry
documents the new package + rationale.

End-to-end verified locally: built the wheel, installed into a fresh
venv, ran `import a3s_code` with __version__ patched to 3.2.0 so the
bootstrap points at the real GH Release; Agent.create succeeded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants