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"