From 6131a95d5357d8e007274bfa060170489df8f16e Mon Sep 17 00:00:00 2001 From: Ayaz Salikhov Date: Tue, 29 Sep 2026 12:40:47 +0300 Subject: [PATCH] build: Support custom release channel --- package/README.md | 9 ++++++++- package/build_pkg.py | 17 +++++++++++++---- package/docker/publish_pkg.py | 2 +- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/package/README.md b/package/README.md index 0615fe0218..1f81bd810a 100644 --- a/package/README.md +++ b/package/README.md @@ -214,6 +214,7 @@ The `release-info` action decides the channel from the event, and | tag | `X.Y.Z` | `stable` | `deb-stable` | `rpm-stable-hosted` | | tag | `X.Y.Z-rcN` | `rc` | `deb-rc` | `rpm-rc-hosted` | | tag | `X.Y.Z-bN` | `beta` | `deb-beta` | `rpm-beta-hosted` | +| tag, any other | `xrpld --version` | `custom` | `deb-custom` | `rpm-custom-hosted` | | push to `develop` | `xrpld --version` | `develop` | `deb-develop` | `rpm-develop-hosted` | | tag, non-public codebase | _any_ | `private` | `deb-private` | `rpm-private-hosted` | @@ -224,6 +225,8 @@ Only a tag names a channel — do not extend that to `develop`, where `BuildInfo.cpp`'s `versionString` moves through `-bN`, `-rcN` and even the final version during a release cycle, which would send develop builds into `stable`. Versions sort in row order, so moving to a more mature channel never downgrades. +A tag matching none of the release patterns, such as `X.Y.Z-hotfix1`, publishes +to `custom`, which sits outside that order. The action decides the package release number on the same split: a tag's version is unique, so its packages are release 1, while develop repeats the same version @@ -310,6 +313,7 @@ With `PKG_RELEASE=1`, the package metadata becomes: | `3.2.0-b0+abc1234` | `3.2.0~b0+abc1234-1%{?dist}` | `3.2.0~b0+abc1234-1` | | `3.2.0-b1` | `3.2.0~b1-1%{?dist}` | `3.2.0~b1-1` | | `3.2.0-rc1` | `3.2.0~rc1-1%{?dist}` | `3.2.0~rc1-1` | +| `3.2.0-custom-1` | `3.2.0~custom.1-1%{?dist}` | `3.2.0~custom.1-1` | `build_pkg.py` defines `dist` as `.el9` rather than letting rpmbuild take it from the build host, so the RHEL image can track a newer release without @@ -319,7 +323,10 @@ The Debian changelog entry carries the channel passed as `--channel`, which only accepts the channels in the table above plus `UNRELEASED`, the Debian convention for a build that targets no channel at all — what local and CMake builds pass, since nothing publishes them. An unsupported pre-release, and -build metadata on a final release such as `3.2.0+abc123`, are both rejected. +build metadata on a final release such as `3.2.0+abc123`, are both rejected, +except in the `custom` and `private` channels, which accept any version and +switch each further `-` in its pre-release to `.`, so `3.4.0-custom-1` packages +as `3.4.0~custom.1`. The RPM path intentionally uses `~` in `Version`, matching the Debian pre-release ordering convention, so RPM filenames/NVRs begin with forms like diff --git a/package/build_pkg.py b/package/build_pkg.py index 77ef8f3120..de3f705e31 100755 --- a/package/build_pkg.py +++ b/package/build_pkg.py @@ -21,6 +21,9 @@ SRC_DIR = Path(__file__).resolve().parents[1] PRE_RELEASE = re.compile(r"^(b|rc)(0|[1-9][0-9]*)(\+.*)?$") +# Channels a tag of any version is published to, rather than only bN/rcN. +ANY_VERSION_CHANNELS = ("custom", "private") + # The package name a variant suffixes, and the name every variant keeps for its # on-disk paths (/usr/bin/xrpld, /etc/xrpld, xrpld.service). BASE_NAME = "xrpld" @@ -68,13 +71,17 @@ def capture(*command: object) -> str: ).stdout.strip() -def package_version(reported: str) -> str: +def package_version(reported: str, channel: str) -> str: """Normalise a reported version into one the package formats accept. A pre-release switches to '~' (3.2.0-b1 -> 3.2.0~b1), which also sorts before - the final 3.2.0; a no-op for a final release. + the final 3.2.0; a no-op for a final release. The custom and private + channels accept any pre-release and build metadata, with any further '-' in + the pre-release switched to '.' (3.4.0-custom-1 -> 3.4.0~custom.1). """ base, _, pre_release = reported.partition("-") + if channel in ANY_VERSION_CHANNELS: + pre_release = pre_release.replace("-", ".") version = f"{base}~{pre_release}" if pre_release else base # BuildInfo already SemVer-validates the version. Packaging adds one narrower @@ -84,6 +91,8 @@ def package_version(reported: str) -> str: f"unsupported version {reported!r}: {version!r} cannot contain '-'. " "Use a single-token pre-release like 3.2.0-b1 or 3.2.0-rc2." ) + if channel in ANY_VERSION_CHANNELS: + return version assert pre_release or "+" not in reported, ( f"unsupported version {reported!r}: " "build metadata is only supported on bN/rcN pre-releases." @@ -301,7 +310,7 @@ def main() -> None: parser.add_argument( "--channel", required=True, - choices=("stable", "rc", "beta", "develop", "private", "UNRELEASED"), + choices=("stable", "rc", "beta", "custom", "develop", "private", "UNRELEASED"), help="release channel, written to debian/changelog", ) args = parser.parse_args() @@ -319,7 +328,7 @@ def main() -> None: check_binaries(build_dir) reported = read_version(build_dir / "xrpld") - version = package_version(reported) + version = package_version(reported, channel) epoch = source_date_epoch() # rpmbuild and dpkg-buildpackage both honour this for file timestamps. diff --git a/package/docker/publish_pkg.py b/package/docker/publish_pkg.py index a112e284aa..1dfdc71d66 100755 --- a/package/docker/publish_pkg.py +++ b/package/docker/publish_pkg.py @@ -87,7 +87,7 @@ def main() -> None: parser.add_argument( "--channel", required=True, - choices=("stable", "rc", "beta", "develop", "private"), + choices=("stable", "rc", "beta", "custom", "develop", "private"), help="release channel, selecting the deb- and rpm--hosted repositories", ) parser.add_argument(