diff --git a/.github/actions/verify-tag-version/action.yml b/.github/actions/verify-tag-version/action.yml index a21e155f0..437de3c5a 100644 --- a/.github/actions/verify-tag-version/action.yml +++ b/.github/actions/verify-tag-version/action.yml @@ -1,7 +1,10 @@ name: Verify tag version description: > - Check that the pushed tag is the expected prefix followed by exactly the - version about to be published, refusing to publish on any mismatch. + Check that the pushed tag is the expected prefix followed by the version + about to be published, refusing to publish on any mismatch. Tags carry + the full `{version}+payjoin-{version}` string; when the packed version + has no build metadata (npm, PyPI, and NuGet artifacts cannot carry it), + the tag's metadata is stripped before comparing. inputs: tag-prefix: description: Expected tag prefix, e.g. payjoin-csharp- @@ -30,8 +33,16 @@ runs: exit 1 fi tag_version="${TAG#"$PREFIX"}" - if [[ $tag_version != "$VERSION" ]]; then - echo "::error::tag $TAG implies version $tag_version but the packed version is $VERSION; refusing to publish" + compare_version="$tag_version" + # A packed version without build metadata comes from a registry + # that cannot represent it, so the tag is compared with its + # metadata stripped; a packed version that carries metadata must + # match the tag exactly. + if [[ $VERSION != *+* ]]; then + compare_version="${tag_version%%+*}" + fi + if [[ $compare_version != "$VERSION" ]]; then + echo "::error::tag $TAG implies version $compare_version but the packed version is $VERSION; refusing to publish" exit 1 fi echo "version=$tag_version" >>"$GITHUB_OUTPUT" diff --git a/payjoin-ffi/csharp/Payjoin.csproj b/payjoin-ffi/csharp/Payjoin.csproj index 5dd9357ad..5257adb08 100644 --- a/payjoin-ffi/csharp/Payjoin.csproj +++ b/payjoin-ffi/csharp/Payjoin.csproj @@ -7,7 +7,7 @@ true true Payjoin - 0.24.0-preview.1 + 0.1.0+payjoin-1.0.0 Payjoin Payjoin Dev Kit Contributors C# bindings for payjoin-ffi, generated from rust-payjoin via UniFFI. diff --git a/payjoin-ffi/csharp/README.md b/payjoin-ffi/csharp/README.md index fcc807eae..b6dce951a 100644 --- a/payjoin-ffi/csharp/README.md +++ b/payjoin-ffi/csharp/README.md @@ -36,9 +36,9 @@ A sender session starts from a BIP 21 URI scanned from the receiver (`Payjoin.Ur Sessions persist each step to an event log through a persister you implement over your own storage; replaying the log with `PayjoinMethods.ReplayReceiverEventLog` recovers the current state after a crash or restart. Every `Save` has a `SaveAsync` counterpart, with async persister interfaces for database-backed storage. -## Preview status +## Stability -The package is in preview while the C# API stabilizes alongside the Rust core's 1.0 release candidates. Expect breaking changes between previews; the package version tracks the underlying `payjoin-ffi` crate. +The package is pre-1.0 while the C# API stabilizes; expect breaking changes between 0.x releases. The version's build metadata names the wrapped payjoin core release, so `0.1.0+payjoin-1.0.0` packages payjoin 1.0.0, the first stable payjoin release. ## Documentation and help diff --git a/payjoin-ffi/csharp/RELEASING.md b/payjoin-ffi/csharp/RELEASING.md index 44a478e1f..a5995ccaa 100644 --- a/payjoin-ffi/csharp/RELEASING.md +++ b/payjoin-ffi/csharp/RELEASING.md @@ -7,12 +7,23 @@ package readme. ## Versioning - The package version is set in `Payjoin.csproj` (``). -- It tracks the `payjoin-ffi` crate version from `payjoin-ffi/Cargo.toml`, - with a `-preview.N` suffix while the C# API stabilizes. For example, - `0.24.0-preview.1` packages `payjoin-ffi 0.24.0`. Pre-release suffixes - follow [SemVer], per NuGet's [package versioning] guidance. -- Bump only the `-preview.N` suffix for packaging-only fixes. Bump - `MAJOR.MINOR.PATCH` together with a `payjoin-ffi` version bump. +- It is the package's own semantic version, independent of the + `payjoin-ffi` crate version. The language bindings follow a + `{version}+payjoin-{version}` convention: the [SemVer] build metadata + names the wrapped payjoin core release, so `0.1.0+payjoin-1.0.0` + packages payjoin 1.0.0. NuGet accepts build metadata per its + [package versioning] guidance but ignores it for version comparison + and strips it from the `.nupkg` filename, so the package identity is + the bare version. +- Bump `MAJOR.MINOR.PATCH` for C# API changes, and update the build + metadata whenever the wrapped payjoin core version changes. +- A release that only changes the wrapped payjoin core version still + needs at least a patch bump: the package identity ignores the build + metadata, and nuget.org rejects republishing an identity that + already exists. +- Versions up to `0.24.0-preview.1` tracked the `payjoin-ffi` crate + version instead. They predate this scheme and are unlisted on + nuget.org so they do not resolve as the latest version. - `Payjoin.csproj` is the only place the version is maintained: the CI smoke test derives the version from the packed artifact. @@ -57,8 +68,9 @@ Review before every publish to nuget.org. Grounded in the NuGet - [ ] Native assets are release-profile builds without `_test-utils` (the pack step's validation target enforces both; confirm it ran in CI). - [ ] The package is under nuget.org's 250 MB size limit. -- [ ] Package version in `Payjoin.csproj` matches `payjoin-ffi`'s crate - version plus the intended pre-release suffix. +- [ ] Package version in `Payjoin.csproj` carries the intended C# version + and its `+payjoin-{version}` build metadata matches the wrapped + payjoin core release. ### Metadata and trust @@ -105,11 +117,16 @@ is ever stored. The workflow is 1. Work through the release readiness checklist above on the release commit in `master`; confirm every `Build and Test CSharp` job is green. 2. Tag that commit `payjoin-csharp-`, where `` is the - `Payjoin.csproj` `` exactly, and push the tag: + `Payjoin.csproj` `` exactly, build metadata included. NuGet + strips the metadata from the `Payjoin..nupkg` filename, so + the publish job strips it from the tag as well before comparing. The + tag must be annotated and signed by a maintainer key in + `contrib/release/keys/`, and the tagged commit must be on `master`; + `verify-tag` refuses to publish otherwise. ```shell - git tag payjoin-csharp-0.24.0-preview.1 - git push upstream payjoin-csharp-0.24.0-preview.1 + git tag -s payjoin-csharp-0.1.0+payjoin-1.0.0 -m payjoin-csharp-0.1.0+payjoin-1.0.0 + git push upstream payjoin-csharp-0.1.0+payjoin-1.0.0 ``` The tag reruns the full build/pack/smoke graph at the tagged commit, then diff --git a/payjoin-ffi/javascript/RELEASING.md b/payjoin-ffi/javascript/RELEASING.md index b0c114b42..84cb87491 100644 --- a/payjoin-ffi/javascript/RELEASING.md +++ b/payjoin-ffi/javascript/RELEASING.md @@ -8,7 +8,16 @@ lives in [`README.md`](README.md). - The package version is set in `package.json`. - It is the package's own semantic version, independent of the - `payjoin-ffi` crate version while the JavaScript API stabilizes. + `payjoin-ffi` crate version. The language bindings follow a + `{version}+payjoin-{version}` convention where the build metadata + names the wrapped payjoin core release, but npm strips build metadata + from published versions, so `package.json` carries the bare version + and records the full one in a `releaseTag` field for traceability. + The release tag carries the full version too. Keep `releaseTag` in + sync when bumping the version. +- A release that only changes the wrapped payjoin core version still + needs at least a patch bump: npm sees only the bare version and + rejects republishing one that already exists. - `package.json` is the only place the version is maintained: the publish job derives the version from the packed tarball and refuses to publish if it does not match the pushed tag. @@ -24,13 +33,15 @@ TypeScript), which is platform-independent. 1. Confirm every `Build and Test JavaScript` job is green on the release commit in `master`. 2. Tag that commit `payjoin-javascript-`, where `` is the - `package.json` version exactly. The tag must be annotated and signed by - a maintainer key in `contrib/release/keys/`, and the tagged commit must - be on `master`; `verify-tag` refuses to publish otherwise. + `package.json` `releaseTag` value exactly; the publish job strips the + build metadata before comparing the tag against the packed tarball. + The tag must be annotated and signed by a maintainer key in + `contrib/release/keys/`, and the tagged commit must be on `master`; + `verify-tag` refuses to publish otherwise. ```shell - git tag -s payjoin-javascript-0.1.1 -m payjoin-javascript-0.1.1 - git push upstream payjoin-javascript-0.1.1 + git tag -s payjoin-javascript-0.2.0+payjoin-1.0.0 -m payjoin-javascript-0.2.0+payjoin-1.0.0 + git push upstream payjoin-javascript-0.2.0+payjoin-1.0.0 ``` The tag reruns the full build/pack/smoke graph at the tagged commit, diff --git a/payjoin-ffi/javascript/package-lock.json b/payjoin-ffi/javascript/package-lock.json index 59d64f613..7733b7940 100644 --- a/payjoin-ffi/javascript/package-lock.json +++ b/payjoin-ffi/javascript/package-lock.json @@ -1,12 +1,12 @@ { "name": "payjoin", - "version": "0.1.1", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "payjoin", - "version": "0.1.1", + "version": "0.2.0", "dependencies": { "@ubjs/core": "^0.31.0-3", "uniffi-bindgen-react-native": "github:spacebear21/uniffi-bindgen-react-native#d10f04d83299" diff --git a/payjoin-ffi/javascript/package.json b/payjoin-ffi/javascript/package.json index 0805956d1..d59a973d4 100644 --- a/payjoin-ffi/javascript/package.json +++ b/payjoin-ffi/javascript/package.json @@ -1,6 +1,7 @@ { "name": "payjoin", - "version": "0.1.1", + "version": "0.2.0", + "releaseTag": "0.2.0+payjoin-1.0.0", "description": "JavaScript/WASM bindings for rust-payjoin (EXPERIMENTAL)", "scripts": { "ubrn:nodejs": "ubrn build web --config ubrn.nodejs.config.yaml --and-generate", diff --git a/payjoin-ffi/python/CHANGELOG.md b/payjoin-ffi/python/CHANGELOG.md index fcbb96ee9..a78b0d5c8 100644 --- a/payjoin-ffi/python/CHANGELOG.md +++ b/payjoin-ffi/python/CHANGELOG.md @@ -1,3 +1,13 @@ +## [0.2.0] + +- Bindings for payjoin-1.0.0, the first stable payjoin release +- The package now carries its own version, independent of the + payjoin-ffi crate version: 0.2.0 succeeds 0.1.0.dev0, the only version + previously published to PyPI. Earlier entries in this changelog used + the crate version +- See the [payjoin-ffi changelog](../CHANGELOG.md) for the shared API + changes since 0.20.0 + ## [0.20.0] #### APIs added diff --git a/payjoin-ffi/python/RELEASING.md b/payjoin-ffi/python/RELEASING.md index 839261268..6c56ca1da 100644 --- a/payjoin-ffi/python/RELEASING.md +++ b/payjoin-ffi/python/RELEASING.md @@ -6,12 +6,21 @@ Maintainer documentation for publishing the `payjoin` package to ## Versioning -- The package version is the `payjoin-ffi` crate version: `setup.py` reads - it from `payjoin-ffi/Cargo.toml` at build time, so a release always - requires the crate version to be correct first. -- There is no separate Python version to maintain: the publish job derives - the version from the built wheels and refuses to publish if it does not - match the pushed tag. +- The package version is set in `pyproject.toml` (`project.version`). +- It is the package's own semantic version, independent of the + `payjoin-ffi` crate version. The language bindings follow a + `{version}+payjoin-{version}` convention where the build metadata + names the wrapped payjoin core release, but PyPI rejects PEP 440 + local version labels (the `+` part), so the package publishes the + bare version. The release tag carries the full version, and the + wrapped payjoin core version is also recorded in + [`CHANGELOG.md`](CHANGELOG.md). +- A release that only changes the wrapped payjoin core version still + needs at least a patch bump: PyPI sees only the bare version and + rejects re-uploading one that already exists. +- `pyproject.toml` is the only place the version is maintained: the + publish job derives the version from the built wheels and refuses to + publish if it does not match the pushed tag. ## Producing the wheels @@ -35,13 +44,16 @@ CPython satisfying `requires-python` can install them. 1. Confirm every `Build and Test Python` job is green on the release commit in `master`, including the per-platform smoke tests. 2. Tag that commit `payjoin-python-`, where `` is the - `payjoin-ffi` crate version exactly. The tag must be annotated and - signed by a maintainer key in `contrib/release/keys/`, and the tagged - commit must be on `master`; `verify-tag` refuses to publish otherwise. + `pyproject.toml` version plus `+payjoin-` build metadata + naming the wrapped payjoin core release; the publish job strips the + metadata before comparing the tag against the built wheels. The tag + must be annotated and signed by a maintainer key in + `contrib/release/keys/`, and the tagged commit must be on `master`; + `verify-tag` refuses to publish otherwise. ```shell - git tag -s payjoin-python-0.24.0 -m payjoin-python-0.24.0 - git push upstream payjoin-python-0.24.0 + git tag -s payjoin-python-0.2.0+payjoin-1.0.0 -m payjoin-python-0.2.0+payjoin-1.0.0 + git push upstream payjoin-python-0.2.0+payjoin-1.0.0 ``` The tag reruns the full build/wheel/smoke graph at the tagged commit, diff --git a/payjoin-ffi/python/pyproject.toml b/payjoin-ffi/python/pyproject.toml index 8ac9a8b63..aad065392 100644 --- a/payjoin-ffi/python/pyproject.toml +++ b/payjoin-ffi/python/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=83", "wheel", "toml"] +requires = ["setuptools>=83", "wheel"] build-backend = "setuptools.build_meta" [project] @@ -8,7 +8,7 @@ description = "The Python language bindings for the Payjoin Dev Kit" readme = "README.md" requires-python = ">=3.10" license = "MIT" -dynamic = ["version"] +version = "0.2.0" dependencies = ["httpx>=0.28.1,<1.0"] [tool.setuptools] @@ -20,4 +20,4 @@ include-package-data = true pythonpath = ["."] [dependency-groups] -dev = ["toml==0.10.2", "yapf==0.43.0"] +dev = ["yapf==0.43.0"] diff --git a/payjoin-ffi/python/setup.py b/payjoin-ffi/python/setup.py index 3e33e278d..04fe89d78 100644 --- a/payjoin-ffi/python/setup.py +++ b/payjoin-ffi/python/setup.py @@ -1,13 +1,6 @@ #!/usr/bin/env python -import os from setuptools import setup -import toml - -# Read version from Cargo.toml -cargo_toml_path = os.path.join(os.path.dirname(__file__), "..", "Cargo.toml") -cargo_toml = toml.load(cargo_toml_path) -version = cargo_toml["package"]["version"] LONG_DESCRIPTION = """# payjoin This repository creates libraries for various programming languages, all using the Rust-based [Payjoin](https://github.com/payjoin/rust-payjoin) @@ -35,7 +28,6 @@ zip_safe=False, packages=["payjoin"], package_dir={"payjoin": "./src/payjoin"}, - version=version, license="MIT or Apache 2.0", has_ext_modules=lambda: True, ) diff --git a/payjoin-ffi/python/uv.lock b/payjoin-ffi/python/uv.lock index 591efc5b4..b43b15e09 100644 --- a/payjoin-ffi/python/uv.lock +++ b/payjoin-ffi/python/uv.lock @@ -82,6 +82,7 @@ wheels = [ [[package]] name = "payjoin" +version = "0.2.0" source = { editable = "." } dependencies = [ { name = "httpx" }, @@ -89,7 +90,6 @@ dependencies = [ [package.dev-dependencies] dev = [ - { name = "toml" }, { name = "yapf" }, ] @@ -97,10 +97,7 @@ dev = [ requires-dist = [{ name = "httpx", specifier = ">=0.28.1,<1.0" }] [package.metadata.requires-dev] -dev = [ - { name = "toml", specifier = "==0.10.2" }, - { name = "yapf", specifier = "==0.43.0" }, -] +dev = [{ name = "yapf", specifier = "==0.43.0" }] [[package]] name = "platformdirs" @@ -120,15 +117,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] -[[package]] -name = "toml" -version = "0.10.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, -] - [[package]] name = "tomli" version = "2.2.1"