Repository navigation
PRODUCE-PY P2r: release 0.1.0, and the owner's publish script (typedstandards#135) - #4
Merged
Merged
Conversation
…read-back DRY_RUN=1 checks the checkout (clean, HEAD equal to origin/main), the version (X.Y.Z), the CHANGELOG heading and that PyPI does not have the version yet; builds the sdist and the wheel, checks them (twine check --strict, the vendored CLI's version), installs the wheel into a fresh environment and runs the smoke check, runs uv publish --dry-run, and records dist/SHA256SUMS and dist/COMMIT. It uploads nothing. The live run (under op run, UV_PUBLISH_TOKEN) uploads exactly the files the dry run built and checked, then reads the release back from PyPI for about five minutes and installs it into a fresh environment, which must print CLI_VERSION. A failed upload says to read back before any retry; a read-back that times out says to run it again and never that the upload did not land. Refs npstorey/typedstandards#135 (G0 D4 = A). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru4PYga7Zf8HANgotZKs4u Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
A file PyPI lists with a different SHA-256 is final, since a version cannot be uploaded twice. The read-back now exits 2 at once and says so, where it waited out its window and said the upload might still appear. A file not listed yet still waits, and a timeout still says to run the read-back again. Refs npstorey/typedstandards#135. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru4PYga7Zf8HANgotZKs4u Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
…ckage The check compared the resolved package directory with the unresolved CLI entry, so it failed whenever the environment sat behind a symlink, as a venv under macOS's default temporary directory (/var -> /private/var) does. The wheel was correct; the check was not. Found by the publish script's dry run. Refs npstorey/typedstandards#135. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru4PYga7Zf8HANgotZKs4u Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
uv publish --dry-run prints "Uploading" for each file while sending nothing. The dry run now says so before it runs uv, and afterwards checks that PyPI still answers 404 for the version. Refs npstorey/typedstandards#135. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru4PYga7Zf8HANgotZKs4u Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
__version__ 0.1.0, and CHANGELOG.md's Unreleased entries, verbatim, under "## 0.1.0 — 2026-10-04", the publish day the owner named. uv.lock is unchanged: `uv lock --check` passes, since the lock records no version for the project. It pins @typedstandards/cli 0.2.0 (CLI_VERSION), as the version tests check. Refs npstorey/typedstandards#135 (G0 D3 = A: one release, 0.1.0, after P2). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru4PYga7Zf8HANgotZKs4u Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
An op:// reference that op run did not resolve, or a value kept with its quotes, was sent to PyPI as the token. The live run now refuses any UV_PUBLISH_TOKEN that does not start with "pypi-", right after checking that it is set, with a message naming the env file's one unquoted line and the op run command. The value is never printed. Asked by the seat at the P2r check. Refs npstorey/typedstandards#135. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ru4PYga7Zf8HANgotZKs4u Signed-off-by: Nathan Storey <npstorey@users.noreply.github.com>
Owner
Author
|
GO — CAT PLAN (the program seat), bound to head Read from GitHub and disk, 2026-10-04:
Condition: the merge and the publish land on the day the heading names, 2026-10-04 in the owner's local time; The owner merges with |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is the release PR for PRODUCE-PY phase P2r (npstorey/typedstandards#135; G0 D3 = A: one release, 0.1.0, after P2; D4 = A: the owner publishes from their terminal with a tested script). It cuts
typedstandards0.1.0, which pins@typedstandards/cli0.2.0, and adds the script that publishes it. The ORCH wrote it, and the owner publishes after the merge.Branch
ts135/p2r-release, head3db7f61ecfb5573a681a659afb4642bbfa53bd4e, onmainat36b59f3(the P2f merge).git diff --numstat main...HEAD:What lands
d02e59e):__version__ = "0.1.0". The## Unreleasedentries inCHANGELOG.mdmove, verbatim, under## 0.1.0 — 2026-10-04, the publish day the owner named.uv.lockis unchanged:uv lock --checkpasses, since the lock records no version for the project.CLI_VERSIONstays0.2.0.scripts/publish.sh, which the owner runs from a clean checkout ofmainat the release merge. It never prints the token.DRY_RUN=1 scripts/publish.shmakes these checks and uploads nothing:origin/main;X.Y.Z;## <version> — <date>heading exists;It then:
npm ci);twine check --strict;CLI_VERSION;scripts/smoke_wheel.py;uv publish --dry-run, then checks that PyPI still answers 404.It records
dist/SHA256SUMSanddist/COMMIT, and prints both files' SHA-256.op run --env-file=pypi.env -- scripts/publish.shis the live run. It refuses in five cases: the token is missing, the token does not start withpypi-(anop://referenceop rundid not resolve, or a quoted value;3db7f61, asked by the seat; the value is never printed), the CHANGELOG heading is not today's date,dist/was built at another commit, or a file does not matchSHA256SUMS. Otherwise it uploads exactly the two files the dry run built and checked, withuv publish --check-url https://pypi.org/simple/. Then:https://pypi.org/pypi/typedstandards/<v>/jsonback for up to 300 seconds and compares every file's SHA-256.typedstandards==<v>from PyPI into a fresh environment, which must printCLI_VERSION 0.2.0.READ_BACK=1 scripts/publish.shruns only the read-back and the install check.scripts/smoke_wheel.py(one word): it now resolves the CLI's entry path before comparing it with the resolved package path. It failed whenever the environment sat behind a symlink, which is what macOS's default temporary directory is (/var→/private/var). The wheel was correct; the check was not. The publish script's first full dry run found it.Evidence (driven on 2026-10-04 by the ORCH, macOS, Node 24.21.0, uv 0.11.25)
Red: a development version is refused (at
c8bccdb,__version__0.1.0.dev0):Red: the smoke check failed on a throwaway 0.1.0 candidate commit, at
assert entry.is_relative_to(package / "_vendor")(AssertionError: /var/folders/…/typedstandards/_vendor/node_modules/@typedstandards/cli/dist/bin/main.js). Green: afterf9d7711,smoke check passed.The read-back was driven against a release that exists on PyPI, httpx 0.28.1, with its two files downloaded and their SHA-256 recorded:
The live run refuses before any upload. This was driven on a throwaway 0.1.0 commit after a dry run there, with
scripts/publish.shas atd02e59e. The only change to the script since is the token check below (3db7f61).Red, then green: a token that is not a PyPI token (asked by the seat). Red at
d02e59e: anop://string and a quoted value both passed the token check, and each run stopped only at the next check:Green at
3db7f61, after a dry run in the same clean clone:Green: the release dry run from a clean clone at this head,
3db7f61:RELEASE_REF=HEADstands in fororigin/main, because this commit reachesmainonly at the merge. The owner's dry run uses the default.Also at the head:
uv run pytest: 238 passed (Python 3.12.13).ruff check: clean.main..HEAD: no leaks.G) with oneSigned-off-by: Nathan Storey <npstorey@users.noreply.github.com>.ab96e211…) is the same atd02e59eand3db7f61: the build is reproducible, and only the sdist, which carries the script, changed.After the merge: the owner's publish (today, 2026-10-04)
From a clean checkout of
mainat the merge, withnode,npmanduvonPATH:~/.config/typedstandards/pypi.envsits outside the repository and holds a reference, never a value:UV_PUBLISH_TOKEN=op://<vault>/<item>/<field>. Use an account-scoped token for this first upload, then replace it with a token scoped to thetypedstandardsproject.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ru4PYga7Zf8HANgotZKs4u