diff --git a/.github/workflows/package-rpm.yml b/.github/workflows/package-rpm.yml index 60aa68da..27e5257a 100644 --- a/.github/workflows/package-rpm.yml +++ b/.github/workflows/package-rpm.yml @@ -44,7 +44,9 @@ jobs: - name: Install RPM build tools run: | - dnf install -y rpm-build git systemd-rpm-macros + # rpmbuild checks BuildRequires against installed RPMs; distro golang + # satisfies the spec. setup-go prepends a newer go to PATH for %build. + dnf install -y rpm-build git systemd-rpm-macros golang - name: Build RPMs run: | @@ -57,7 +59,8 @@ jobs: cp packaging/dnsplane.spec "${HOME}/rpmbuild/SPECS/" rpmbuild -ba "${HOME}/rpmbuild/SPECS/dnsplane.spec" \ --define "dnsplane_base ${DNSPLANE_VERSION_BASE}" \ - --define "dnsplane_short ${DNSPLANE_GIT_SHORT}" + --define "dnsplane_short ${DNSPLANE_GIT_SHORT}" \ + --define "dnsplane_go_min ${DNSPLANE_GO_MOD}" mkdir -p "${GITHUB_WORKSPACE}/rpm-artifacts" shopt -s nullglob for f in "${HOME}/rpmbuild/RPMS"/*/*.rpm "${HOME}/rpmbuild/SRPMS"/*.src.rpm; do diff --git a/debian/control b/debian/control index f7096827..4e741f5b 100644 --- a/debian/control +++ b/debian/control @@ -3,6 +3,7 @@ Section: net Priority: optional Maintainer: dnsplane packagers Rules-Requires-Root: no +# Minimum Go matches go.mod (toolchain / go line); install a new enough golang before debuild. Build-Depends: debhelper-compat (= 13), golang-go Standards-Version: 4.6.2 Homepage: https://github.com/network-plane/dnsplane diff --git a/packaging/README.md b/packaging/README.md index 5d4ff823..31995ecb 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -9,6 +9,7 @@ | `DNSPLANE_VERSION_BASE` | `1.4.175` | Semver core from the latest matching `v*.*.*` tag on `HEAD` when `.git` exists (suffixes after `X.Y.Z` ignored, e.g. `v1.4.175-rc1` → `1.4.175`); else `GITHUB_REF_NAME` when it looks like `vX.Y.Z` (CI tag builds without `.git`); else [VERSION](../VERSION); else `0.0.0` | | `DNSPLANE_GIT_SHORT` | `d977f1b` | `GITHUB_SHA` (first 7) in Actions when `.git` is absent; else `git rev-parse --short=7 HEAD`; else `unknown` | | `DNSPLANE_VERSION_FULL` | `1.4.175-d977f1b` | Embedded in the binary (`main.appVersion`) and shown in `%description` / docs | +| `DNSPLANE_GO_MOD` | `1.26.2` | From `go.mod` (`toolchain` line if set, else `go`); passed to `rpmbuild` as `dnsplane_go_min` | Usage: @@ -16,6 +17,7 @@ Usage: eval "$(./packaging/version.sh export)" echo "$DNSPLANE_VERSION_FULL" ./packaging/version.sh full # print FULL only +./packaging/version.sh go # print go.mod Go version (for rpmbuild --define dnsplane_go_min) ``` **RPM:** `Version` is `BASE`; `Release` is `1.SHORTSHA%{?dist}` so the NEVRA is policy-friendly while humans still see `FULL` in the description. @@ -31,7 +33,7 @@ echo "$DNSPLANE_VERSION_FULL" ## RPM (Fedora, RHEL-family, openSUSE) -Requirements: `git`, `golang` (see [go.mod](../go.mod); RHEL 9 may need a newer Go from AppStream or module streams), `rpm-build`, `systemd-rpm-macros`. +Requirements: `git`, `golang` (install the distro package so `rpmbuild` satisfies `BuildRequires`; the compiler must still meet [go.mod](../go.mod) — use a newer Go on `PATH` first, e.g. from [go.dev](https://go.dev/dl/) or `actions/setup-go`), `rpm-build`, `systemd-rpm-macros`. From the repository root: @@ -43,12 +45,13 @@ bash ./packaging/source-tarball.sh "${DNSPLANE_VERSION_BASE}" \ cp packaging/dnsplane.spec ~/rpmbuild/SPECS/ rpmbuild -ba ~/rpmbuild/SPECS/dnsplane.spec \ --define "dnsplane_base ${DNSPLANE_VERSION_BASE}" \ - --define "dnsplane_short ${DNSPLANE_GIT_SHORT}" + --define "dnsplane_short ${DNSPLANE_GIT_SHORT}" \ + --define "dnsplane_go_min ${DNSPLANE_GO_MOD}" ``` Artifacts under `~/rpmbuild/RPMS/` and `~/rpmbuild/SRPMS/`. -**RHEL / Rocky / Alma:** If the distro’s `golang` is older than required by `go.mod`, install a supported toolchain (vendor docs, EPEL, or upstream Go) before `rpmbuild`. +**RHEL / Rocky / Alma:** `BuildRequires` uses `dnsplane_go_min` from `go.mod` (see `version.sh go`). If the distro’s `golang` RPM is older than that (common on EL9), install a newer `golang` package (module stream, COPR, or vendor Go) so `rpm` dependency checks pass; the compiler on `PATH` must still satisfy `go.mod` / `toolchain`. ## Debian / Ubuntu diff --git a/packaging/dnsplane.spec b/packaging/dnsplane.spec index dd8c60db..1e011e53 100644 --- a/packaging/dnsplane.spec +++ b/packaging/dnsplane.spec @@ -14,7 +14,9 @@ License: GPL-2.0-only URL: https://github.com/network-plane/dnsplane Source0: %{name}-%{version}.tar.gz -BuildRequires: golang >= 1.22 +# Minimum Go: must match go.mod (toolchain or "go" line). CI passes --define dnsplane_go_min from packaging/version.sh go. +%{!?dnsplane_go_min:%global dnsplane_go_min 1.26.2} +BuildRequires: golang >= %{dnsplane_go_min} BuildRequires: git BuildRequires: systemd-rpm-macros @@ -24,6 +26,7 @@ BuildRequires: systemd-rpm-macros dnsplane is a DNS resolver with optional local records, DoT/DoH, and clustering. Packaged build id (version-git): %{dnsplane_full} +Build expects Go >= %{dnsplane_go_min} per go.mod (use matching toolchain on PATH). %prep %autosetup -n %{name}-%{version} @@ -31,6 +34,7 @@ Packaged build id (version-git): %{dnsplane_full} %build export CGO_ENABLED=0 export GOFLAGS=-buildvcs=false +go version go build -trimpath -ldflags "-X main.appVersion=%{dnsplane_full}" -o dnsplane . %install diff --git a/packaging/version.sh b/packaging/version.sh index f148c10f..655daf97 100755 --- a/packaging/version.sh +++ b/packaging/version.sh @@ -1,9 +1,31 @@ #!/usr/bin/env bash # Emit dnsplane version parts for RPM/DEB/CI. FULL = BASE-SHORTSHA (e.g. 1.4.175-d977f1b). +# Go version: ./packaging/version.sh go → from go.mod (toolchain line, else "go" directive). set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +# Effective Go version for builds (toolchain line wins, else "go" directive). Matches go.mod only. +go_mod_go_version() { + awk ' + /^toolchain go/ { + t = $2 + sub(/^go/, "", t) + print t + exit + } + /^go[ \t]/ { g = $2 } + END { + if (g != "") { + print g + exit + } + print "go.mod: missing go directive" > "/dev/stderr" + exit 1 + } + ' "$ROOT/go.mod" +} + short_sha() { # GitHub Actions container checkouts often have no .git; use workflow commit SHA. if [[ -n "${GITHUB_SHA:-}" ]] && [[ "${#GITHUB_SHA}" -ge 7 ]]; then @@ -55,6 +77,7 @@ base_version() { SHORTSHA="$(short_sha)" BASE="$(base_version)" FULL="${BASE}-${SHORTSHA}" +GO_MOD="$(go_mod_go_version)" cmd="${1:-export}" case "$cmd" in @@ -62,12 +85,14 @@ export) printf "export DNSPLANE_VERSION_BASE=%q\n" "$BASE" printf "export DNSPLANE_GIT_SHORT=%q\n" "$SHORTSHA" printf "export DNSPLANE_VERSION_FULL=%q\n" "$FULL" + printf "export DNSPLANE_GO_MOD=%q\n" "$GO_MOD" ;; base) echo "$BASE" ;; short | sha) echo "$SHORTSHA" ;; full) echo "$FULL" ;; +go) echo "$GO_MOD" ;; *) - echo "usage: $0 {export|base|short|full}" >&2 + echo "usage: $0 {export|base|short|full|go}" >&2 exit 1 ;; esac