Compare commits

...

5 Commits

Author SHA1 Message Date
Ayaz Salikhov
12b04adcd4 Another commit 2026-09-29 19:50:46 +01:00
Ayaz Salikhov
223739e8ac Rewrite conan recipe upload 2026-09-29 15:14:45 +03:00
Ayaz Salikhov
c150b7075e Update XRPLF/actions 2026-09-29 15:05:08 +03:00
Ayaz Salikhov
07a6f9b5c6 Split metadata first 2026-09-29 13:05:28 +03:00
Ayaz Salikhov
6131a95d53 build: Support custom release channel 2026-09-29 12:40:47 +03:00
9 changed files with 39 additions and 36 deletions

View File

@@ -41,4 +41,4 @@ runs:
- name: Determine release channel and package release
id: release_info
uses: XRPLF/actions/release-info@7cc0e4a8d9d0b838f92c48d312856b190341bbba
uses: XRPLF/actions/release-info@ebcf6cea14eee258697308a51fea55cad777581b

View File

@@ -58,7 +58,7 @@ jobs:
base_image: debian:bookworm
- name: rhel
base_image: registry.access.redhat.com/ubi9/ubi:latest
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@034e87065fcd0100214cf0672923bd38d193cf78
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@696384b292577293292daed06af0306d1b83bd7d
with:
image_name: xrpld/nix-${{ matrix.distro.name }}
dockerfile: nix/docker/Dockerfile

View File

@@ -41,7 +41,7 @@ jobs:
# AlmaLinux rather than UBI, which does not ship rpm-sign.
- name: rhel
base_image: almalinux:10
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@034e87065fcd0100214cf0672923bd38d193cf78
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@696384b292577293292daed06af0306d1b83bd7d
with:
image_name: xrpld/packaging-${{ matrix.distro.name }}
dockerfile: package/docker/Dockerfile

View File

@@ -30,7 +30,7 @@ jobs:
permissions:
contents: read
packages: write
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@034e87065fcd0100214cf0672923bd38d193cf78
uses: XRPLF/actions/.github/workflows/build-multiarch-image.yml@696384b292577293292daed06af0306d1b83bd7d
with:
image_name: xrpld/pre-commit
dockerfile: bin/pre-commit/Dockerfile

View File

@@ -68,33 +68,17 @@ jobs:
run: conan remote login "${REMOTE_NAME}" "${CONAN_LOGIN_USERNAME_XRPLF}" --password "${CONAN_PASSWORD_XRPLF}"
- name: Upload Conan recipe (version)
env:
VERSION: ${{ steps.release_info.outputs.version }}
run: |
conan export . --version=${{ steps.release_info.outputs.version }}
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/${{ steps.release_info.outputs.version }}
conan export . --version="${VERSION}"
conan upload --confirm --check --remote="${REMOTE_NAME}" "xrpl/${VERSION}"
# When this workflow is triggered by a push event, it will always be when merging into the
# 'develop' branch, see on-trigger.yml.
- name: Upload Conan recipe (develop)
if: ${{ github.event_name == 'push' }}
if: ${{ github.ref == 'refs/heads/develop' }}
run: |
conan export . --version=develop
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/develop
# When this workflow is triggered by a pull request event, it will always be when merging into
# one of the 'release' branches, see on-pr.yml.
- name: Upload Conan recipe (rc)
if: ${{ github.event_name == 'pull_request' }}
run: |
conan export . --version=rc
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/rc
# When this workflow is triggered by a push event, it will always be when tagging a final
# release, see on-tag.yml.
- name: Upload Conan recipe (release)
if: ${{ startsWith(github.ref, 'refs/tags/') }}
run: |
conan export . --version=release
conan upload --confirm --check --remote="${REMOTE_NAME}" xrpl/release
outputs:
ref: xrpl/${{ steps.release_info.outputs.version }}

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 `-` inside the pre-release or build metadata 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

@@ -19,7 +19,10 @@ from pathlib import Path
# This script lives in the repository it packages.
SRC_DIR = Path(__file__).resolve().parents[1]
PRE_RELEASE = re.compile(r"^(b|rc)(0|[1-9][0-9]*)(\+.*)?$")
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).
@@ -68,14 +71,21 @@ 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 '-' inside
either switched to '.' (3.4.0-custom-1 -> 3.4.0~custom.1).
"""
base, _, pre_release = reported.partition("-")
version = f"{base}~{pre_release}" if pre_release else base
# Metadata first, as it may contain '-' too.
release, plus, metadata = reported.partition("+")
base, _, pre_release = release.partition("-")
if channel in ANY_VERSION_CHANNELS:
pre_release = pre_release.replace("-", ".")
metadata = metadata.replace("-", ".")
version = (f"{base}~{pre_release}" if pre_release else base) + plus + metadata
# BuildInfo already SemVer-validates the version. Packaging adds one narrower
# constraint: after normalisation the version must not contain '-', because
@@ -84,7 +94,9 @@ 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."
)
assert pre_release or "+" not in reported, (
if channel in ANY_VERSION_CHANNELS:
return version
assert pre_release or not plus, (
f"unsupported version {reported!r}: "
"build metadata is only supported on bN/rcN pre-releases."
)
@@ -301,7 +313,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 +331,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(

View File

@@ -23,7 +23,7 @@ namespace {
//------------------------------------------------------------------------------
// clang-format off
// NOLINTNEXTLINE(readability-identifier-naming)
char const* const versionString = "3.5.0-b0"
char const* const versionString = "3.5.0-custom-1"
// clang-format on
;