Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ concurrency:
cancel-in-progress: true

jobs:
release_freebsd_port:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- run: bash release_files/freebsd-port-diff.sh
- run: bash release_files/freebsd-port-issue-body.sh
- name: upload freebsd port files
uses: actions/upload-artifact@v4
with:
name: freebsd-port-files
path: |
./netbird-*-issue.txt
./netbird-*.diff
retention-days: 30
release:
runs-on: ubuntu-latest-m
env:
Expand Down
208 changes: 208 additions & 0 deletions release_files/freebsd-port-diff.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
#!/bin/bash
#
# FreeBSD Port Diff Generator for NetBird
#
# This script generates the diff file required for submitting a FreeBSD port update.
# It works on macOS, Linux, and FreeBSD by fetching files from FreeBSD cgit and
# computing checksums from the Go module proxy.
#
# 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.

set -e

GITHUB_REPO="netbirdio/netbird"
PORTS_CGIT_BASE="https://cgit.freebsd.org/ports/plain/security/netbird"
GO_PROXY="https://proxy.golang.org/github.com/netbirdio/netbird/@v"
OUTPUT_DIR="${OUTPUT_DIR:-.}"

fetch_all_tags() {

Check warning on line 21 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpW&open=AZruPwh3gZYxGT1njWpW&pullRequest=4916
curl -sL "https://github.com/${GITHUB_REPO}/tags" 2>/dev/null | \
grep -oE '/releases/tag/v[0-9]+\.[0-9]+\.[0-9]+' | \
sed 's/.*\/v//' | \
sort -u -V
}

fetch_current_ports_version() {

Check warning on line 28 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpX&open=AZruPwh3gZYxGT1njWpX&pullRequest=4916
echo "Fetching current version from FreeBSD ports..." >&2
curl -sL "${PORTS_CGIT_BASE}/Makefile" 2>/dev/null | \
grep -E "^DISTVERSION=" | \
sed 's/DISTVERSION=[[:space:]]*//' | \
tr -d '\t '
}

fetch_latest_github_release() {

Check warning on line 36 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpY&open=AZruPwh3gZYxGT1njWpY&pullRequest=4916
echo "Fetching latest release from GitHub..." >&2
fetch_all_tags | tail -1
}

fetch_ports_file() {

Check warning on line 41 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpZ&open=AZruPwh3gZYxGT1njWpZ&pullRequest=4916
local filename="$1"
curl -sL "${PORTS_CGIT_BASE}/${filename}" 2>/dev/null
}

compute_checksums() {
local version="$1"
local tmpdir
tmpdir=$(mktemp -d)
trap "rm -rf '$tmpdir'" EXIT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Use single quotes in trap to defer variable expansion.

Lines 50 and 166 use unquoted variables in trap commands, which expands them immediately rather than when the trap fires. This is a security best practice to ensure cleanup uses the variable value at exit time, not at definition time.

Apply these diffs to fix trap quoting per ShellCheck SC2064:

 compute_checksums() {
     local version="$1"
     local tmpdir
     tmpdir=$(mktemp -d)
-    trap "rm -rf '$tmpdir'" EXIT
+    trap "rm -rf \"$tmpdir\"" EXIT
 # Create temp files for diff
 TMPDIR=$(mktemp -d)
-trap "rm -rf '$TMPDIR'" EXIT
+trap "rm -rf \"$TMPDIR\"" EXIT

Actually, the safest approach is to use single quotes around the entire command:

-    trap "rm -rf '$tmpdir'" EXIT
+    trap 'rm -rf "$tmpdir"' EXIT

Also applies to: 166-166

🧰 Tools
🪛 Shellcheck (0.11.0)

[warning] 50-50: Use single quotes, otherwise this expands now rather than when signalled.

(SC2064)

🤖 Prompt for AI Agents
In release_files/freebsd-port-diff.sh around lines 50 and 166, the trap commands
use double quotes which cause immediate variable expansion (triggers ShellCheck
SC2064); replace them so variable expansion is deferred by quoting the entire
command and protecting the variable with inner double quotes — i.e. change the
trap definitions to use single quotes around the whole command and double quotes
around $tmpdir so the value is expanded at trap execution time.


echo "Downloading files from Go module proxy for v${version}..." >&2

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
Comment on lines +57 to +58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Go module proxy downloads lack validation and timeout.

The curl commands on lines 57–58 download files from proxy.golang.org without:

  1. Timeout specifications (could hang indefinitely)
  2. Size limits (could download unexpectedly large files)
  3. Checksum pre-validation

If the Go proxy is down or returns garbage, the script proceeds with invalid data.

Add timeouts, size limits, and pre-download validation:

-    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
+    curl -sfL --max-time 30 --max-filesize 10M "${GO_PROXY}/v${version}.mod" -o "$mod_file" 2>/dev/null || return 1
+    curl -sfL --max-time 30 --max-filesize 100M "${GO_PROXY}/v${version}.zip" -o "$zip_file" 2>/dev/null || return 1

This ensures:

  • -f: Fail on HTTP errors
  • --max-time 30: Abort if download exceeds 30 seconds
  • --max-filesize N: Reject files larger than expected
  • Exit code handling with || return 1
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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
curl -sfL --max-time 30 --max-filesize 10M "${GO_PROXY}/v${version}.mod" -o "$mod_file" 2>/dev/null || return 1
curl -sfL --max-time 30 --max-filesize 100M "${GO_PROXY}/v${version}.zip" -o "$zip_file" 2>/dev/null || return 1


if [ ! -s "$mod_file" ] || [ ! -s "$zip_file" ]; then

Check failure on line 60 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpL&open=AZruPwh3gZYxGT1njWpL&pullRequest=4916

Check failure on line 60 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpM&open=AZruPwh3gZYxGT1njWpM&pullRequest=4916
echo "Error: Could not download files from Go module proxy" >&2
return 1
fi

local mod_sha256 mod_size zip_sha256 zip_size

if command -v sha256sum &>/dev/null; then
mod_sha256=$(sha256sum "$mod_file" | awk '{print $1}')
zip_sha256=$(sha256sum "$zip_file" | awk '{print $1}')
elif command -v shasum &>/dev/null; then
mod_sha256=$(shasum -a 256 "$mod_file" | awk '{print $1}')
zip_sha256=$(shasum -a 256 "$zip_file" | awk '{print $1}')

Check warning on line 72 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of using the literal '{print $1}' 4 times.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpK&open=AZruPwh3gZYxGT1njWpK&pullRequest=4916
else
echo "Error: No sha256 command found" >&2
return 1
fi

if [[ "$OSTYPE" == "darwin"* ]]; then
mod_size=$(stat -f%z "$mod_file")
zip_size=$(stat -f%z "$zip_file")
else
mod_size=$(stat -c%s "$mod_file")
zip_size=$(stat -c%s "$zip_file")
fi

echo "TIMESTAMP = $(date +%s)"
echo "SHA256 (go/security_netbird/netbird-v${version}/v${version}.mod) = ${mod_sha256}"
echo "SIZE (go/security_netbird/netbird-v${version}/v${version}.mod) = ${mod_size}"
echo "SHA256 (go/security_netbird/netbird-v${version}/v${version}.zip) = ${zip_sha256}"
echo "SIZE (go/security_netbird/netbird-v${version}/v${version}.zip) = ${zip_size}"
}

generate_new_makefile() {

Check warning on line 93 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpa&open=AZruPwh3gZYxGT1njWpa&pullRequest=4916
local old_version="$1"

Check warning on line 94 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove the unused local variable 'old_version'.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpV&open=AZruPwh3gZYxGT1njWpV&pullRequest=4916
local new_version="$2"
local old_makefile="$3"

# Check if old version had PORTREVISION
if echo "$old_makefile" | grep -q "^PORTREVISION="; then
# Remove PORTREVISION line and update DISTVERSION
echo "$old_makefile" | \
sed "s/^DISTVERSION=.*/DISTVERSION= ${new_version}/" | \
grep -v "^PORTREVISION="
else
# Just update DISTVERSION
echo "$old_makefile" | \
sed "s/^DISTVERSION=.*/DISTVERSION= ${new_version}/"
fi
}

# Parse arguments
NEW_VERSION="${1:-}"

# Auto-detect versions if not provided
OLD_VERSION=$(fetch_current_ports_version)
if [ -z "$OLD_VERSION" ]; then

Check failure on line 116 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpN&open=AZruPwh3gZYxGT1njWpN&pullRequest=4916
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

Check failure on line 122 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpO&open=AZruPwh3gZYxGT1njWpO&pullRequest=4916
NEW_VERSION=$(fetch_latest_github_release)
if [ -z "$NEW_VERSION" ]; then

Check failure on line 124 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpP&open=AZruPwh3gZYxGT1njWpP&pullRequest=4916
echo "Error: Could not fetch latest release from GitHub" >&2
exit 1
fi
fi
echo "Target version: ${NEW_VERSION}" >&2

if [ "$OLD_VERSION" = "$NEW_VERSION" ]; then

Check failure on line 131 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpQ&open=AZruPwh3gZYxGT1njWpQ&pullRequest=4916
echo "Port is already at version ${NEW_VERSION}. Nothing to do." >&2
exit 0
fi

echo "" >&2

# Fetch current files
echo "Fetching current Makefile from FreeBSD ports..." >&2
OLD_MAKEFILE=$(fetch_ports_file "Makefile")
if [ -z "$OLD_MAKEFILE" ]; then

Check failure on line 141 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpR&open=AZruPwh3gZYxGT1njWpR&pullRequest=4916
echo "Error: Could not fetch Makefile" >&2
exit 1
fi

echo "Fetching current distinfo from FreeBSD ports..." >&2
OLD_DISTINFO=$(fetch_ports_file "distinfo")
if [ -z "$OLD_DISTINFO" ]; then

Check failure on line 148 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpS&open=AZruPwh3gZYxGT1njWpS&pullRequest=4916
echo "Error: Could not fetch distinfo" >&2
exit 1
fi

# Generate new files
echo "Generating new Makefile..." >&2
NEW_MAKEFILE=$(generate_new_makefile "$OLD_VERSION" "$NEW_VERSION" "$OLD_MAKEFILE")

echo "Computing checksums for new version..." >&2
NEW_DISTINFO=$(compute_checksums "$NEW_VERSION")
if [ -z "$NEW_DISTINFO" ]; then

Check failure on line 159 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpT&open=AZruPwh3gZYxGT1njWpT&pullRequest=4916
echo "Error: Could not compute checksums" >&2
exit 1
fi

# Create temp files for diff
TMPDIR=$(mktemp -d)
trap "rm -rf '$TMPDIR'" EXIT

mkdir -p "${TMPDIR}/a/security/netbird" "${TMPDIR}/b/security/netbird"

echo "$OLD_MAKEFILE" > "${TMPDIR}/a/security/netbird/Makefile"
echo "$OLD_DISTINFO" > "${TMPDIR}/a/security/netbird/distinfo"
echo "$NEW_MAKEFILE" > "${TMPDIR}/b/security/netbird/Makefile"
echo "$NEW_DISTINFO" > "${TMPDIR}/b/security/netbird/distinfo"

# Generate diff
OUTPUT_FILE="${OUTPUT_DIR}/netbird-${NEW_VERSION}.diff"

echo "" >&2
echo "Generating diff..." >&2

# Generate diff and clean up temp paths to show standard a/b paths
(cd "${TMPDIR}" && diff -ruN "a/security/netbird" "b/security/netbird") > "$OUTPUT_FILE" || true

if [ ! -s "$OUTPUT_FILE" ]; then

Check failure on line 184 in release_files/freebsd-port-diff.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwh3gZYxGT1njWpU&open=AZruPwh3gZYxGT1njWpU&pullRequest=4916
echo "Error: Generated diff is empty" >&2
exit 1
fi

echo "" >&2
echo "========================================="
echo "Diff saved to: ${OUTPUT_FILE}"
echo "========================================="
echo ""
cat "$OUTPUT_FILE"
echo ""
echo "========================================="
echo ""
echo "Next steps:"
echo "1. Review the diff above"
echo "2. Submit to https://bugs.freebsd.org/bugzilla/"
echo "3. Use ./freebsd-port-issue-body.sh to generate the issue content"
echo ""
echo "For FreeBSD testing (optional but recommended):"
echo " cd /usr/ports/security/netbird"
echo " patch < ${OUTPUT_FILE}"
echo " make stage && make stage-qa && make package && make install"
echo " netbird status"
echo " make deinstall"
154 changes: 154 additions & 0 deletions release_files/freebsd-port-issue-body.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#!/bin/bash
#
# FreeBSD Port Issue Body Generator for NetBird
#
# This script generates the issue body content for submitting a FreeBSD port update
# to the FreeBSD Bugzilla at https://bugs.freebsd.org/bugzilla/
#
# Usage: ./freebsd-port-issue-body.sh [old_version] [new_version]
# Example: ./freebsd-port-issue-body.sh 0.56.0 0.59.1
#
# If no versions are provided, the script will:
# - Fetch OLD version from FreeBSD ports cgit (current version in ports tree)
# - Fetch NEW version from latest NetBird GitHub release tag

set -e

GITHUB_REPO="netbirdio/netbird"
PORTS_CGIT_URL="https://cgit.freebsd.org/ports/plain/security/netbird/Makefile"

fetch_current_ports_version() {
echo "Fetching current version from FreeBSD ports..." >&2
local makefile_content
makefile_content=$(curl -sL "$PORTS_CGIT_URL" 2>/dev/null)
if [ -z "$makefile_content" ]; then

Check failure on line 24 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWo7&open=AZruPwdFgZYxGT1njWo7&pullRequest=4916
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 '
}

fetch_all_tags() {

Check warning on line 31 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpH&open=AZruPwdFgZYxGT1njWpH&pullRequest=4916
# 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]+' | \
sed 's/.*\/v//' | \
sort -u -V
}

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

Check failure on line 46 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWo8&open=AZruPwdFgZYxGT1njWo8&pullRequest=4916
# 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

Check failure on line 52 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWo9&open=AZruPwdFgZYxGT1njWo9&pullRequest=4916
echo "Error: Could not fetch latest release from GitHub" >&2
return 1
fi
echo "$latest"
}

OLD_VERSION="${1:-}"
NEW_VERSION="${2:-}"

if [ -z "$OLD_VERSION" ]; then

Check failure on line 62 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWo-&open=AZruPwdFgZYxGT1njWo-&pullRequest=4916
OLD_VERSION=$(fetch_current_ports_version)
if [ -z "$OLD_VERSION" ]; then

Check failure on line 64 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWo_&open=AZruPwdFgZYxGT1njWo_&pullRequest=4916
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

Check failure on line 72 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpA&open=AZruPwdFgZYxGT1njWpA&pullRequest=4916
NEW_VERSION=$(fetch_latest_github_release)
if [ -z "$NEW_VERSION" ]; then

Check failure on line 74 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpB&open=AZruPwdFgZYxGT1njWpB&pullRequest=4916
echo "Error: Could not determine new version. Please provide it manually." >&2
echo "Usage: $0 <old_version> <new_version>" >&2
exit 1
fi
echo "Detected NEW version from GitHub: $NEW_VERSION" >&2
fi

if [ "$OLD_VERSION" = "$NEW_VERSION" ]; then

Check failure on line 82 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpC&open=AZruPwdFgZYxGT1njWpC&pullRequest=4916
echo "Warning: OLD and NEW versions are the same ($OLD_VERSION). Port may already be up to date." >&2
fi

echo "" >&2

OUTPUT_DIR="${OUTPUT_DIR:-.}"

fetch_releases_between_versions() {

Check warning on line 90 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpI&open=AZruPwdFgZYxGT1njWpI&pullRequest=4916
echo "Fetching release history from GitHub..." >&2

# Fetch all tags and filter to those between OLD and NEW versions
fetch_all_tags | \
while read -r ver; do
if [ "$(printf '%s\n' "$OLD_VERSION" "$ver" | sort -V | head -n1)" = "$OLD_VERSION" ] && \

Check failure on line 96 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpD&open=AZruPwdFgZYxGT1njWpD&pullRequest=4916
[ "$(printf '%s\n' "$ver" "$NEW_VERSION" | sort -V | head -n1)" = "$ver" ] && \

Check failure on line 97 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpE&open=AZruPwdFgZYxGT1njWpE&pullRequest=4916
[ "$ver" != "$OLD_VERSION" ]; then

Check failure on line 98 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpF&open=AZruPwdFgZYxGT1njWpF&pullRequest=4916
echo "$ver"
fi
done
}
Comment on lines +90 to +102
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Test 1: Standard version range filtering (as provided in review)
OLD_VERSION="0.56.0"
NEW_VERSION="0.59.1"

SAMPLE_TAGS="0.55.0
0.56.0
0.57.0
0.58.0
0.59.0
0.59.1
0.60.0"

echo "=== Test 1: Standard version range filtering ==="
echo "OLD_VERSION=$OLD_VERSION, NEW_VERSION=$NEW_VERSION"
echo "Expected: 0.57.0, 0.58.0, 0.59.0, 0.59.1"
echo "Results:"
echo "$SAMPLE_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" ] && \
       [ "$ver" != "$OLD_VERSION" ]; then
        echo "$ver"
    fi
done

# Test 2: Pre-release versions
echo ""
echo "=== Test 2: Pre-release versions ==="
OLD_VERSION="0.56.0"
NEW_VERSION="0.59.1"

PRERELEASE_TAGS="0.56.0
0.57.0-rc1
0.57.0-beta
0.57.0
0.58.0-alpha
0.58.0
0.59.0
0.59.1-rc1
0.59.1
0.60.0"

echo "Testing with pre-release versions:"
echo "$PRERELEASE_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" ] && \
       [ "$ver" != "$OLD_VERSION" ]; then
        echo "$ver"
    fi
done

# Test 3: Malformed/edge case versions
echo ""
echo "=== Test 3: Edge cases with malformed versions ==="
OLD_VERSION="1.0.0"
NEW_VERSION="2.0.0"

EDGE_TAGS="1.0.0
1.5.0
1.5.0.1
1.5
2.0.0
2.1.0
v1.7.0
1.0.0a"

echo "Testing with malformed/edge case versions:"
echo "$EDGE_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" ] && \
       [ "$ver" != "$OLD_VERSION" ]; then
        echo "$ver (included)"
    else
        echo "$ver (excluded)"
    fi
done

# Test 4: Verify sort -V behavior directly
echo ""
echo "=== Test 4: Direct sort -V behavior with edge cases ==="
printf '%s\n' "1.0.0" "1.5.0-rc1" "1.5.0" "2.0.0" | sort -V

Repository: netbirdio/netbird

Length of output: 757


Add version validation and handle Git tag prefixes.

The version filtering logic relies on sort -V for version comparison, which has edge case issues. Testing reveals:

  1. Git tag prefix handling: Versions with "v" prefix (e.g., v1.7.0) are excluded, failing silently. If GitHub releases are tagged with "v" prefixes, they won't be included in the changelog.
  2. Pre-release sorting anomaly: sort -V places pre-release versions (e.g., 0.59.1-rc1) after their release versions (e.g., 0.59.1), which is semantically incorrect. This may cause pre-releases to be unexpectedly included or excluded depending on the version range.
  3. Malformed version handling: Ambiguous formats like 1.0.0a or 1.5.0.1 are accepted without validation, potentially including unintended tags.

Add explicit version validation before filtering and strip common tag prefixes (like v) to handle real-world GitHub tag formats reliably.

🧰 Tools
🪛 GitHub Check: SonarCloud Code Analysis

[warning] 90-90: Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpI&open=AZruPwdFgZYxGT1njWpI&pullRequest=4916


[failure] 96-96: Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpD&open=AZruPwdFgZYxGT1njWpD&pullRequest=4916


[failure] 97-97: Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpE&open=AZruPwdFgZYxGT1njWpE&pullRequest=4916


[failure] 98-98: Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpF&open=AZruPwdFgZYxGT1njWpF&pullRequest=4916

🤖 Prompt for AI Agents
In release_files/freebsd-port-issue-body.sh around lines 90 to 102, the tag
filtering loop must be made robust: normalize tags by stripping common Git tag
prefixes (e.g., leading "v" or "V" and "refs/tags/"), validate each tag against
a strict semver regex (e.g. major.minor.patch with optional prerelease/build)
and skip malformed tags, and replace the current sort -V reliance with a
semver-aware comparison (e.g., call a small Python snippet using
packaging.version.Version or a system semver tool) so prereleases compare
correctly relative to releases; finally, use the normalized, validated,
semver-sorted list to apply the OLD/NEW range check and echo only tags that fall
strictly between OLD_VERSION and NEW_VERSION (ensure OLD_VERSION and NEW_VERSION
themselves are normalized/validated the same way).


generate_changelog_section() {

Check warning on line 104 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add an explicit return statement at the end of the function.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpJ&open=AZruPwdFgZYxGT1njWpJ&pullRequest=4916
local releases
releases=$(fetch_releases_between_versions)

echo "Changelogs:"
if [ -n "$releases" ]; then

Check failure on line 109 in release_files/freebsd-port-issue-body.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=netbirdio_netbird&issues=AZruPwdFgZYxGT1njWpG&open=AZruPwdFgZYxGT1njWpG&pullRequest=4916
echo "$releases" | while read -r ver; do
echo "https://github.com/${GITHUB_REPO}/releases/tag/v${ver}"
done
else
echo "https://github.com/${GITHUB_REPO}/releases/tag/v${NEW_VERSION}"
fi
}

OUTPUT_FILE="${OUTPUT_DIR}/netbird-${NEW_VERSION}-issue.txt"

cat << EOF > "$OUTPUT_FILE"
BUGZILLA ISSUE DETAILS
======================

Severity: Affects Some People

Summary: security/netbird: Update to ${NEW_VERSION}

Description:
------------
security/netbird: Update ${OLD_VERSION} => ${NEW_VERSION}

$(generate_changelog_section)

Commit log:
https://github.com/${GITHUB_REPO}/compare/v${OLD_VERSION}...v${NEW_VERSION}
EOF

echo "========================================="
echo "Issue body saved to: ${OUTPUT_FILE}"
echo "========================================="
echo ""
cat "$OUTPUT_FILE"
echo ""
echo "========================================="
echo ""
echo "Next steps:"
echo "1. Go to https://bugs.freebsd.org/bugzilla/ and login"
echo "2. Click 'Report an update or defect to a port'"
echo "3. Fill in:"
echo " - Severity: Affects Some People"
echo " - Summary: security/netbird: Update to ${NEW_VERSION}"
echo " - Description: Copy content from ${OUTPUT_FILE}"
echo "4. Attach diff file: netbird-${NEW_VERSION}.diff"
echo "5. Submit the bug report"
Loading