mirror of
https://github.com/netbirdio/netbird.git
synced 2026-10-15 01:49:08 +02:00
[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.
This commit is contained in:
@@ -23,8 +23,50 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
freebsd_port_trigger:
|
||||
name: "FreeBSD Port / Trigger"
|
||||
runs-on: ubuntu-22.04
|
||||
outputs:
|
||||
run: ${{ steps.decide.outputs.run }}
|
||||
version: ${{ steps.decide.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Decide whether the port job runs
|
||||
id: decide
|
||||
env:
|
||||
BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
run=false
|
||||
case "$GITHUB_EVENT_NAME" in
|
||||
push)
|
||||
if [[ "$GITHUB_REF" == "refs/heads/main" ]]; then
|
||||
run=true
|
||||
elif [[ "$GITHUB_REF" == refs/tags/* && "$GITHUB_REF_NAME" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
||||
# The port tracks stable releases only, so a canary or rc tag has nothing to submit.
|
||||
run=true
|
||||
echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT"
|
||||
fi
|
||||
;;
|
||||
pull_request)
|
||||
git fetch --depth=1 origin "$BASE_SHA"
|
||||
if git diff --name-only "$BASE_SHA" HEAD | \
|
||||
grep -qE '^(release_files/freebsd-port-.*\.sh|\.github/workflows/release\.yml)$'; then
|
||||
run=true
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
echo "run=$run" >> "$GITHUB_OUTPUT"
|
||||
echo "FreeBSD port job runs: $run"
|
||||
|
||||
release_freebsd_port:
|
||||
name: "FreeBSD Port / Build & Test"
|
||||
needs: freebsd_port_trigger
|
||||
if: needs.freebsd_port_trigger.outputs.run == 'true'
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -33,18 +75,19 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Generate FreeBSD port diff
|
||||
run: bash -x release_files/freebsd-port-diff.sh
|
||||
|
||||
- name: Generate FreeBSD port issue body
|
||||
run: bash -x release_files/freebsd-port-issue-body.sh
|
||||
env:
|
||||
TARGET_VERSION: ${{ needs.freebsd_port_trigger.outputs.version }}
|
||||
run: bash -x release_files/freebsd-port-diff.sh "$TARGET_VERSION"
|
||||
|
||||
- name: Check if diff was generated
|
||||
id: check_diff
|
||||
run: |
|
||||
if ls netbird-*.diff 1> /dev/null 2>&1; then
|
||||
echo "diff_exists=true" >> $GITHUB_OUTPUT
|
||||
shopt -s nullglob
|
||||
diffs=(netbird-*.diff)
|
||||
if [[ ${#diffs[@]} -gt 0 ]]; then
|
||||
echo "diff_exists=true" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
echo "diff_exists=false" >> $GITHUB_OUTPUT
|
||||
echo "diff_exists=false" >> "$GITHUB_OUTPUT"
|
||||
echo "No diff file generated (port may already be up to date)"
|
||||
fi
|
||||
|
||||
@@ -52,10 +95,18 @@ jobs:
|
||||
if: steps.check_diff.outputs.diff_exists == 'true'
|
||||
id: version
|
||||
run: |
|
||||
VERSION=$(ls netbird-*.diff | sed 's/netbird-\(.*\)\.diff/\1/')
|
||||
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
||||
diffs=(netbird-*.diff)
|
||||
VERSION="${diffs[0]#netbird-}"
|
||||
VERSION="${VERSION%.diff}"
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "Generated files for version: $VERSION"
|
||||
cat netbird-*.diff
|
||||
cat "${diffs[0]}"
|
||||
|
||||
- name: Generate FreeBSD port issue body
|
||||
if: steps.check_diff.outputs.diff_exists == 'true'
|
||||
env:
|
||||
TARGET_VERSION: ${{ steps.version.outputs.version }}
|
||||
run: bash -x release_files/freebsd-port-issue-body.sh "" "$TARGET_VERSION"
|
||||
|
||||
- name: Read Go version from go.mod
|
||||
id: goversion
|
||||
|
||||
@@ -9,62 +9,19 @@
|
||||
# Usage: ./freebsd-port-diff.sh [new_version]
|
||||
# Example: ./freebsd-port-diff.sh 0.60.7
|
||||
#
|
||||
# If no version is provided, it fetches the latest from GitHub.
|
||||
# If no version is provided, it uses the latest stable release from GitHub.
|
||||
# Prerelease versions (canary, rc, ...) are rejected: the port only tracks
|
||||
# stable releases.
|
||||
|
||||
set -e
|
||||
|
||||
GITHUB_REPO="netbirdio/netbird"
|
||||
PORTS_MIRROR_BASE="https://raw.githubusercontent.com/freebsd/freebsd-ports/main/security/netbird"
|
||||
# shellcheck source=release_files/freebsd-port-lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/freebsd-port-lib.sh"
|
||||
|
||||
GO_PROXY="https://proxy.golang.org/github.com/netbirdio/netbird/@v"
|
||||
OUTPUT_DIR="${OUTPUT_DIR:-.}"
|
||||
AWK_FIRST_FIELD='{print $1}'
|
||||
|
||||
fetch_all_tags() {
|
||||
curl -sL "https://github.com/${GITHUB_REPO}/tags" 2>/dev/null | \
|
||||
grep -oE '/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+([^"]+)?' | \
|
||||
grep -iv 'rc' | \
|
||||
sed 's/.*\/v//' | \
|
||||
sort -u -V
|
||||
return 0
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
fetch_latest_github_release() {
|
||||
echo "Fetching latest release from GitHub..." >&2
|
||||
fetch_all_tags | tail -1
|
||||
return 0
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
compute_checksums() {
|
||||
local version="$1"
|
||||
local tmpdir
|
||||
@@ -77,11 +34,15 @@ compute_checksums() {
|
||||
local mod_file="${tmpdir}/v${version}.mod"
|
||||
local zip_file="${tmpdir}/v${version}.zip"
|
||||
|
||||
curl -sL "${GO_PROXY}/v${version}.mod" -o "$mod_file" 2>/dev/null
|
||||
curl -sL "${GO_PROXY}/v${version}.zip" -o "$zip_file" 2>/dev/null
|
||||
local -a curl_opts=(-fsL --proto '=https' --proto-redir '=https' --retry 3)
|
||||
if ! curl "${curl_opts[@]}" "${GO_PROXY}/v${version}.mod" -o "$mod_file" 2>/dev/null || \
|
||||
! curl "${curl_opts[@]}" "${GO_PROXY}/v${version}.zip" -o "$zip_file" 2>/dev/null; then
|
||||
echo "Error: Could not download v${version} from the Go module proxy" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ ! -s "$mod_file" ]] || [[ ! -s "$zip_file" ]]; then
|
||||
echo "Error: Could not download files from Go module proxy" >&2
|
||||
echo "Error: Go module proxy returned empty files for v${version}" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -133,25 +94,12 @@ generate_new_makefile() {
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
NEW_VERSION="${1:-}"
|
||||
|
||||
# Auto-detect versions if not provided
|
||||
OLD_VERSION=$(fetch_current_ports_version)
|
||||
if [[ -z "$OLD_VERSION" ]]; then
|
||||
echo "Error: Could not fetch current version from FreeBSD ports" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Current FreeBSD ports version: ${OLD_VERSION}" >&2
|
||||
|
||||
if [[ -z "$NEW_VERSION" ]]; then
|
||||
NEW_VERSION=$(fetch_latest_github_release)
|
||||
if [[ -z "$NEW_VERSION" ]]; then
|
||||
echo "Error: Could not fetch latest release from GitHub" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
NEW_VERSION=$(resolve_target_version "${1:-}")
|
||||
echo "Target version: ${NEW_VERSION}" >&2
|
||||
|
||||
OLD_VERSION=$(fetch_current_ports_version)
|
||||
echo "Current FreeBSD ports version: ${OLD_VERSION}" >&2
|
||||
|
||||
if [[ "$OLD_VERSION" = "$NEW_VERSION" ]]; then
|
||||
echo "Port is already at version ${NEW_VERSION}. Nothing to do." >&2
|
||||
exit 0
|
||||
|
||||
@@ -10,81 +10,29 @@
|
||||
#
|
||||
# If no versions are provided, the script will:
|
||||
# - Fetch OLD version from the FreeBSD ports GitHub mirror (current version in ports tree)
|
||||
# - Fetch NEW version from latest NetBird GitHub release tag
|
||||
# - Fetch NEW version from the latest stable NetBird release tag on GitHub
|
||||
#
|
||||
# Prerelease versions (canary, rc, ...) are rejected: the port only tracks
|
||||
# stable releases.
|
||||
|
||||
set -e
|
||||
|
||||
GITHUB_REPO="netbirdio/netbird"
|
||||
PORTS_MAKEFILE_URL="https://raw.githubusercontent.com/freebsd/freebsd-ports/main/security/netbird/Makefile"
|
||||
|
||||
fetch_current_ports_version() {
|
||||
echo "Fetching current version from FreeBSD ports..." >&2
|
||||
local makefile_content
|
||||
makefile_content=$(curl -fsL --proto '=https' --proto-redir '=https' --retry 3 "$PORTS_MAKEFILE_URL" 2>/dev/null) || makefile_content=""
|
||||
if [[ "$makefile_content" == \<* ]]; then
|
||||
echo "Error: Received HTML instead of Makefile from ${PORTS_MAKEFILE_URL}" >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ -z "$makefile_content" ]]; then
|
||||
echo "Error: Could not fetch Makefile from FreeBSD ports" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "$makefile_content" | grep -E "^DISTVERSION=" | sed 's/DISTVERSION=[[:space:]]*//' | tr -d '\t '
|
||||
return 0
|
||||
}
|
||||
|
||||
fetch_all_tags() {
|
||||
# Fetch tags from GitHub tags page (no rate limiting, no auth needed)
|
||||
curl -sL "https://github.com/${GITHUB_REPO}/tags" 2>/dev/null | \
|
||||
grep -oE '/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+([^"]+)?' | \
|
||||
grep -iv 'rc' | \
|
||||
sed 's/.*\/v//' | \
|
||||
sort -u -V
|
||||
return 0
|
||||
}
|
||||
|
||||
fetch_latest_github_release() {
|
||||
echo "Fetching latest release from GitHub..." >&2
|
||||
local latest
|
||||
|
||||
# Fetch from GitHub tags page
|
||||
latest=$(fetch_all_tags | tail -1)
|
||||
|
||||
if [[ -z "$latest" ]]; then
|
||||
# Fallback to GitHub API
|
||||
latest=$(curl -sL "https://api.github.com/repos/${GITHUB_REPO}/releases/latest" 2>/dev/null | \
|
||||
grep '"tag_name"' | sed 's/.*"tag_name": *"v\([^"]*\)".*/\1/')
|
||||
fi
|
||||
|
||||
if [[ -z "$latest" ]]; then
|
||||
echo "Error: Could not fetch latest release from GitHub" >&2
|
||||
return 1
|
||||
fi
|
||||
echo "$latest"
|
||||
return 0
|
||||
}
|
||||
# shellcheck source=release_files/freebsd-port-lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/freebsd-port-lib.sh"
|
||||
|
||||
OLD_VERSION="${1:-}"
|
||||
NEW_VERSION="${2:-}"
|
||||
|
||||
if [[ -z "$OLD_VERSION" ]]; then
|
||||
OLD_VERSION=$(fetch_current_ports_version)
|
||||
if [[ -z "$OLD_VERSION" ]]; then
|
||||
echo "Error: Could not determine old version. Please provide it manually." >&2
|
||||
echo "Usage: $0 <old_version> <new_version>" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Detected OLD version from FreeBSD ports: $OLD_VERSION" >&2
|
||||
fi
|
||||
|
||||
if [[ -z "$NEW_VERSION" ]]; then
|
||||
NEW_VERSION=$(fetch_latest_github_release)
|
||||
if [[ -z "$NEW_VERSION" ]]; then
|
||||
echo "Error: Could not determine new version. Please provide it manually." >&2
|
||||
echo "Usage: $0 <old_version> <new_version>" >&2
|
||||
exit 1
|
||||
fi
|
||||
NEW_VERSION=$(resolve_target_version "")
|
||||
echo "Detected NEW version from GitHub: $NEW_VERSION" >&2
|
||||
else
|
||||
NEW_VERSION=$(resolve_target_version "$NEW_VERSION")
|
||||
fi
|
||||
|
||||
if [[ "$OLD_VERSION" = "$NEW_VERSION" ]]; then
|
||||
@@ -98,8 +46,11 @@ OUTPUT_DIR="${OUTPUT_DIR:-.}"
|
||||
fetch_releases_between_versions() {
|
||||
echo "Fetching release history from GitHub..." >&2
|
||||
|
||||
# Fetch all tags and filter to those between OLD and NEW versions
|
||||
fetch_all_tags | \
|
||||
local tags
|
||||
tags=$(fetch_stable_tags) || return 1
|
||||
|
||||
# List the stable releases after OLD up to and including NEW
|
||||
echo "$tags" | \
|
||||
while read -r ver; do
|
||||
if [[ "$(printf '%s\n' "$OLD_VERSION" "$ver" | sort -V | head -n1)" = "$OLD_VERSION" ]] && \
|
||||
[[ "$(printf '%s\n' "$ver" "$NEW_VERSION" | sort -V | head -n1)" = "$ver" ]] && \
|
||||
@@ -112,7 +63,7 @@ fetch_releases_between_versions() {
|
||||
|
||||
generate_changelog_section() {
|
||||
local releases
|
||||
releases=$(fetch_releases_between_versions)
|
||||
releases=$(fetch_releases_between_versions) || return 1
|
||||
|
||||
echo "Changelogs:"
|
||||
if [[ -n "$releases" ]]; then
|
||||
@@ -127,7 +78,10 @@ generate_changelog_section() {
|
||||
|
||||
OUTPUT_FILE="${OUTPUT_DIR}/netbird-${NEW_VERSION}-issue.txt"
|
||||
|
||||
cat << EOF > "$OUTPUT_FILE"
|
||||
# Built before the heredoc: a failing substitution inside it would not stop the script.
|
||||
CHANGELOG=$(generate_changelog_section)
|
||||
|
||||
cat << EOT > "$OUTPUT_FILE"
|
||||
BUGZILLA ISSUE DETAILS
|
||||
======================
|
||||
|
||||
@@ -139,11 +93,11 @@ Description:
|
||||
------------
|
||||
security/netbird: Update ${OLD_VERSION} => ${NEW_VERSION}
|
||||
|
||||
$(generate_changelog_section)
|
||||
${CHANGELOG}
|
||||
|
||||
Commit log:
|
||||
https://github.com/${GITHUB_REPO}/compare/v${OLD_VERSION}...v${NEW_VERSION}
|
||||
EOF
|
||||
EOT
|
||||
|
||||
echo "========================================="
|
||||
echo "Issue body saved to: ${OUTPUT_FILE}"
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#!/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
|
||||
}
|
||||
Reference in New Issue
Block a user