mirror of
https://github.com/netbirdio/netbird.git
synced 2026-09-24 23:59:08 +02:00
[client] Fix RPM metadata for Red Hat certification (#7614)
Goreleaser's RPM build is split into one nfpm entry per architecture, each pinned to a single-arch build, with the version substituted from the release job. The deb package, archives, and container images are unaffected. Also fixes rpmlint: incoherent-version-in-changelog, found while investigating: nfpm writes the changelog title straight from semver and never appends the release, so entries read 0.79.0 against a 0.79.0-1 package.
This commit is contained in:
@@ -191,6 +191,9 @@ jobs:
|
||||
# requires a changelog. Generated, not committed (see .gitignore).
|
||||
# chglog is a go.mod tool directive, so go.sum pins it and its deps.
|
||||
run: bash release_files/rpm-changelog.sh
|
||||
- name: Fill the RPM ISA provide version
|
||||
# nfpm cannot emit rpmbuild's ISA provide and GoReleaser cannot template it.
|
||||
run: bash release_files/rpm-provides.sh
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 #v4.1.0
|
||||
- name: Set up Docker Buildx
|
||||
@@ -230,14 +233,18 @@ jobs:
|
||||
uses: goreleaser/goreleaser-action@5daf1e915a5f0af01ddbcd89a43b8061ff4f1a89 # v7.2.2
|
||||
with:
|
||||
version: ${{ env.GORELEASER_VER }}
|
||||
args: release --clean ${{ env.flags }}
|
||||
args: release --config .goreleaser.generated.yaml --clean ${{ env.flags }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
|
||||
UPLOAD_DEBIAN_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
||||
UPLOAD_YUM_SECRET: ${{ secrets.PKG_UPLOAD_SECRET }}
|
||||
GPG_RPM_KEY_FILE: ${{ env.GPG_RPM_KEY_FILE }}
|
||||
NFPM_NETBIRD_RPM_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
||||
# One per nfpm id: GoReleaser looks the passphrase up as NFPM_<ID>_PASSPHRASE.
|
||||
NFPM_NETBIRD_RPM_AMD64_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
||||
NFPM_NETBIRD_RPM_ARM64_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
||||
NFPM_NETBIRD_RPM_ARM_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
||||
NFPM_NETBIRD_RPM_386_PASSPHRASE: ${{ secrets.GPG_RPM_PASSPHRASE }}
|
||||
SKIP_PUBLISH: ${{ env.SKIP_PUBLISH }}
|
||||
SKIP_DOCKER_PUSH: ${{ env.SKIP_DOCKER_PUSH }}
|
||||
- name: Verify RPM signatures
|
||||
|
||||
@@ -38,4 +38,7 @@ management/server/types/testdata/
|
||||
|
||||
# generated by chglog in the release workflow, embedded into the RPM
|
||||
changelog.yml
|
||||
|
||||
# generated by rpm-provides.sh, the config GoReleaser actually runs
|
||||
.goreleaser.generated.yaml
|
||||
.chglog.yml
|
||||
|
||||
+60
-5
@@ -40,6 +40,32 @@ builds:
|
||||
tags:
|
||||
- load_wgnt_from_rsrc
|
||||
|
||||
# Single-arch builds: nfpm provides is not templated, so the RPM splits per arch.
|
||||
- &netbird_rpm_build
|
||||
id: netbird-rpm-amd64
|
||||
dir: client
|
||||
binary: netbird
|
||||
env: [CGO_ENABLED=0]
|
||||
goos: [linux]
|
||||
goarch: [amd64]
|
||||
ldflags:
|
||||
- -s -w -X github.com/netbirdio/netbird/version.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} -X main.builtBy=goreleaser
|
||||
mod_timestamp: "{{ .CommitTimestamp }}"
|
||||
tags:
|
||||
- load_wgnt_from_rsrc
|
||||
|
||||
- <<: *netbird_rpm_build
|
||||
id: netbird-rpm-arm64
|
||||
goarch: [arm64]
|
||||
|
||||
- <<: *netbird_rpm_build
|
||||
id: netbird-rpm-arm
|
||||
goarch: [arm]
|
||||
|
||||
- <<: *netbird_rpm_build
|
||||
id: netbird-rpm-386
|
||||
goarch: [386]
|
||||
|
||||
- id: netbird-static
|
||||
dir: client
|
||||
binary: netbird
|
||||
@@ -223,17 +249,22 @@ nfpms:
|
||||
postinstall: "release_files/post_install.sh"
|
||||
preremove: "release_files/pre_remove.sh"
|
||||
|
||||
- maintainer: Netbird <dev@netbird.io>
|
||||
- &netbird_rpm
|
||||
maintainer: Netbird <dev@netbird.io>
|
||||
description: Netbird client.
|
||||
homepage: https://netbird.io/
|
||||
license: BSD-3-Clause
|
||||
vendor: NetBird
|
||||
id: netbird_rpm
|
||||
id: netbird_rpm_amd64
|
||||
bindir: /usr/bin
|
||||
builds:
|
||||
- netbird
|
||||
ids:
|
||||
- netbird-rpm-amd64
|
||||
formats:
|
||||
- rpm
|
||||
# Red Hat certification (RPM Version Handling) requires rpmbuild's ISA
|
||||
# provide, which nfpm does not emit. The version is filled in by the release job.
|
||||
provides:
|
||||
- "netbird(x86-64) = @RPM_EVR@"
|
||||
# The client verifies TLS to management and signal against the system trust
|
||||
# store. Red Hat software certification (RPM Dependency Tracking) also
|
||||
# rejects packages that declare no dependencies at all.
|
||||
@@ -263,6 +294,27 @@ nfpms:
|
||||
packager: NetBird <dev@netbird.io>
|
||||
signature:
|
||||
key_file: '{{ if index .Env "GPG_RPM_KEY_FILE" }}{{ .Env.GPG_RPM_KEY_FILE }}{{ end }}'
|
||||
|
||||
- <<: *netbird_rpm
|
||||
id: netbird_rpm_arm64
|
||||
ids:
|
||||
- netbird-rpm-arm64
|
||||
provides:
|
||||
- "netbird(aarch-64) = @RPM_EVR@"
|
||||
|
||||
- <<: *netbird_rpm
|
||||
id: netbird_rpm_arm
|
||||
ids:
|
||||
- netbird-rpm-arm
|
||||
provides:
|
||||
- "netbird(armv6hl-32) = @RPM_EVR@"
|
||||
|
||||
- <<: *netbird_rpm
|
||||
id: netbird_rpm_386
|
||||
ids:
|
||||
- netbird-rpm-386
|
||||
provides:
|
||||
- "netbird(x86-32) = @RPM_EVR@"
|
||||
dockers_v2:
|
||||
- id: netbird
|
||||
disable: "{{ .Env.SKIP_DOCKER_PUSH }}"
|
||||
@@ -513,7 +565,10 @@ uploads:
|
||||
- name: yum
|
||||
skip: "{{ .Env.SKIP_PUBLISH }}"
|
||||
ids:
|
||||
- netbird_rpm
|
||||
- netbird_rpm_amd64
|
||||
- netbird_rpm_arm64
|
||||
- netbird_rpm_arm
|
||||
- netbird_rpm_386
|
||||
mode: archive
|
||||
target: https://pkgs.wiretrustee.com/yum/{{ .Arch }}{{ if .Arm }}{{ .Arm }}{{ end }}
|
||||
username: dev@wiretrustee.com
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
# template headings, review checklists, HTML comments and Co-authored-by
|
||||
# trailers. None of that belongs in a package on Red Hat's catalog, and it is
|
||||
# most of the changelog's size. Keep the subject line and drop the rest.
|
||||
#
|
||||
# chglog also records the bare tag as each entry's version, while nfpm writes
|
||||
# that string into the changelog header verbatim and never appends the release.
|
||||
# rpmlint then reports incoherent-version-in-changelog, because the entry reads
|
||||
# 0.79.0 while the package is 0.79.0-1. Rewrite each version the way nfpm
|
||||
# renders the package EVR.
|
||||
|
||||
set -eu
|
||||
|
||||
@@ -20,14 +26,29 @@ path = sys.argv[1]
|
||||
lines = open(path, encoding="utf-8").read().split("\n")
|
||||
|
||||
NOTE = re.compile(r"^ note: (.*)$")
|
||||
SEMVER = re.compile(r"^- semver: (.*)$")
|
||||
BLOCK = {"|", "|-", "|+", ">", ">-", ">+"}
|
||||
|
||||
# nfpm defaults the RPM release to 1 and the packaging sets no other value.
|
||||
RELEASE = "1"
|
||||
|
||||
|
||||
def quote(text):
|
||||
"""Render text as a YAML single-quoted scalar."""
|
||||
return " note: '{}'".format(text.replace("'", "''"))
|
||||
|
||||
|
||||
def evr(version):
|
||||
"""Render a semver tag the way nfpm renders the package EVR."""
|
||||
version, _, metadata = version.partition("+")
|
||||
core, _, prerelease = version.partition("-")
|
||||
if prerelease:
|
||||
core += "~" + prerelease.replace("-", "_")
|
||||
if metadata:
|
||||
core += "+" + metadata
|
||||
return "{}-{}".format(core, RELEASE)
|
||||
|
||||
|
||||
def first_line_of_double_quoted(value):
|
||||
"""Text of a double-quoted scalar up to its first \\n escape."""
|
||||
out = []
|
||||
@@ -52,6 +73,13 @@ seen = 0
|
||||
i = 0
|
||||
while i < len(lines):
|
||||
line = lines[i]
|
||||
|
||||
m = SEMVER.match(line)
|
||||
if m:
|
||||
out.append("- semver: '{}'".format(evr(m.group(1))))
|
||||
i += 1
|
||||
continue
|
||||
|
||||
m = NOTE.match(line)
|
||||
if not m:
|
||||
out.append(line)
|
||||
@@ -107,4 +135,11 @@ if grep -nE '^ note: ".*\\n' changelog.yml; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Every entry must carry the release, or rpmlint reports the changelog version
|
||||
# as incoherent with the package again.
|
||||
if grep -nE "^- semver: " changelog.yml | grep -vE -- "-[0-9]+'$"; then
|
||||
echo "changelog entries without the RPM release survived the rewrite" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
test -s changelog.yml
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Write .goreleaser.generated.yaml with the @RPM_EVR@ placeholder filled in.
|
||||
#
|
||||
# Red Hat certification (RPM Version Handling) expects rpmbuild's ISA provide,
|
||||
# netbird(x86-64) = <evr>. nfpm does not emit it and GoReleaser does not template
|
||||
# the provides field, so the version is substituted before GoReleaser runs.
|
||||
#
|
||||
# The value has to match what nfpm derives from the same tag: a semver
|
||||
# prerelease becomes a tilde suffix, and the release defaults to 1.
|
||||
|
||||
set -eu
|
||||
|
||||
OUT=.goreleaser.generated.yaml
|
||||
|
||||
TAG="${GITHUB_REF#refs/tags/}"
|
||||
case "$TAG" in
|
||||
v*) ;;
|
||||
*) TAG=$(git describe --tags --abbrev=0) ;;
|
||||
esac
|
||||
|
||||
EVR=$(python3 - "$TAG" <<'PYEOF'
|
||||
import sys
|
||||
|
||||
version = sys.argv[1].lstrip("v")
|
||||
version, _, metadata = version.partition("+")
|
||||
core, _, prerelease = version.partition("-")
|
||||
if prerelease:
|
||||
core += "~" + prerelease.replace("-", "_")
|
||||
if metadata:
|
||||
core += "+" + metadata
|
||||
print("{}-1".format(core))
|
||||
PYEOF
|
||||
)
|
||||
|
||||
# Written to a separate, ignored file: GoReleaser refuses to release from a
|
||||
# dirty tree, so .goreleaser.yaml itself must stay untouched.
|
||||
sed "s/@RPM_EVR@/${EVR}/g" .goreleaser.yaml > "$OUT"
|
||||
|
||||
# A surviving placeholder means the provides entries moved or were renamed.
|
||||
if grep -n "@RPM_EVR@" "$OUT"; then
|
||||
echo "unsubstituted @RPM_EVR@ left in $OUT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "rpm provides version: ${EVR} -> ${OUT}"
|
||||
Reference in New Issue
Block a user