build: Support custom release channel

This commit is contained in:
Ayaz Salikhov
2026-09-29 12:40:47 +03:00
parent 97cddd6721
commit 6131a95d53
3 changed files with 22 additions and 6 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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-<channel> and rpm-<channel>-hosted repositories",
)
parser.add_argument(