Files
netbird/release_files/freebsd-port-lib.sh
T
Maycon Santos 405bbb8997 [infrastructure] Restrict the FreeBSD port job to stable releases (#8204)
* [infrastructure] Restrict the FreeBSD port job to stable releases

The port scripts picked the target version by scraping the GitHub tags
page and only dropped tags containing "rc". A canary tag such as
v0.81.0-canary.pr-8098.1 sorts above the latest stable release, so the
job tried to package a prerelease, and the page only lists ten tags, so
a run of prereleases could leave no candidate at all. Both scripts now
share one helper that reads the tags API, keeps MAJOR.MINOR.PATCH
versions only, and rejects an explicitly requested prerelease. Go proxy
downloads fail instead of hashing an error page.

The job moves out of the release workflow into its own, so it runs on
pushes to main, on release tags, and on pull requests that touch the
scripts or the workflow itself. Prerelease tags skip the job, and a
stable tag is packaged directly rather than whatever happens to be the
latest release at the time.

* [infrastructure] Keep the FreeBSD port job in the release workflow

A separate workflow would rename the check and detach the job from the
release run, so the job stays in release.yml behind a small trigger job
that decides when it runs: pushes to main, stable release tags, and pull
requests that touch the port scripts or the workflow. Prerelease tags
and other branches skip it.

Tags are now listed with git ls-remote, which returns every tag in one
call and needs neither a token nor pagination, and the Go module proxy
downloads are limited to HTTPS like the other fetches.

* [infrastructure] Address Sonar findings in the FreeBSD port helper

Read the version into a local and return explicitly from is_stable_version.

* [infrastructure] Address review findings in the FreeBSD port job

Only a full vMAJOR.MINOR.PATCH tag starts the port job, so a tag like
v1.2 skips it instead of failing in the resolver. The diff detection
steps use a glob array rather than parsing ls, and quote GITHUB_OUTPUT.

A failed tag listing now stops the issue body script instead of writing
an incomplete changelog, and a bare "v" argument is rejected rather than
treated as a request for the latest release.
2026-10-14 15:50:16 +02:00

99 lines
3.2 KiB
Bash

#!/bin/bash
#
# Shared helpers for the FreeBSD port scripts. Source this file, do not run it.
#
# The FreeBSD port tracks stable NetBird releases only, so every helper here
# works on plain MAJOR.MINOR.PATCH versions and ignores canary, release
# candidate and any other prerelease tag.
GITHUB_REPO="netbirdio/netbird"
GITHUB_REPO_URL="https://github.com/${GITHUB_REPO}.git"
PORTS_MIRROR_BASE="https://raw.githubusercontent.com/freebsd/freebsd-ports/main/security/netbird"
STABLE_VERSION_RE='^[0-9]+\.[0-9]+\.[0-9]+$'
# is_stable_version reports whether the version is a plain MAJOR.MINOR.PATCH release.
is_stable_version() {
local version="$1"
if [[ "$version" =~ $STABLE_VERSION_RE ]]; then
return 0
fi
return 1
}
# fetch_stable_tags prints the stable release versions known to GitHub, oldest
# first. git ls-remote returns every tag in one round trip, with no API
# pagination or rate limit to work around.
fetch_stable_tags() {
local refs
if ! refs=$(git ls-remote --tags --refs "$GITHUB_REPO_URL" 2>/dev/null); then
echo "Error: Could not list tags of ${GITHUB_REPO_URL}" >&2
return 1
fi
echo "$refs" | \
sed -nE 's#.*refs/tags/v([0-9]+\.[0-9]+\.[0-9]+)$#\1#p' | \
sort -u -V
return 0
}
# resolve_target_version validates an explicitly requested version, or picks the
# latest stable release from GitHub when none was given. A leading "v" is
# accepted so a git tag name can be passed as is.
resolve_target_version() {
local raw="$1"
local requested="${raw#v}"
if [[ -n "$raw" ]]; then
if ! is_stable_version "$requested"; then
echo "Error: '${raw}' is not a stable release. The FreeBSD port only tracks MAJOR.MINOR.PATCH versions." >&2
return 1
fi
echo "$requested"
return 0
fi
echo "Fetching latest stable release from GitHub..." >&2
local latest
latest=$(fetch_stable_tags | tail -1)
if [[ -z "$latest" ]]; then
echo "Error: Could not determine the latest stable release from GitHub" >&2
return 1
fi
echo "$latest"
return 0
}
# fetch_ports_file prints a file from the security/netbird port on the FreeBSD
# ports GitHub mirror.
fetch_ports_file() {
local filename="$1"
local content
if ! content=$(curl -fsL --proto '=https' --proto-redir '=https' --retry 3 "${PORTS_MIRROR_BASE}/${filename}" 2>/dev/null); then
echo "Error: Could not fetch ${filename} from ${PORTS_MIRROR_BASE}" >&2
return 1
fi
if [[ "$content" == \<* ]]; then
echo "Error: Received HTML instead of ${filename} from ${PORTS_MIRROR_BASE}" >&2
return 1
fi
printf '%s' "$content"
return 0
}
# fetch_current_ports_version prints the DISTVERSION currently in the ports tree.
fetch_current_ports_version() {
echo "Fetching current version from FreeBSD ports..." >&2
local makefile version
makefile=$(fetch_ports_file "Makefile") || return 1
version=$(echo "$makefile" | \
grep -E "^DISTVERSION=" | \
sed 's/DISTVERSION=[[:space:]]*//' | \
tr -d '\t ')
if [[ -z "$version" ]]; then
echo "Error: Could not extract DISTVERSION from ports Makefile" >&2
return 1
fi
echo "$version"
return 0
}