diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a9bc1b979cb..c29898593b8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,6 +19,87 @@ concurrency: cancel-in-progress: true jobs: + release_freebsd_port: + name: "FreeBSD Port / Build & Test" + runs-on: ubuntu-22.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Generate FreeBSD port diff + run: bash release_files/freebsd-port-diff.sh + + - name: Generate FreeBSD port issue body + run: bash release_files/freebsd-port-issue-body.sh + + - name: Extract version + id: version + run: | + VERSION=$(ls netbird-*.diff | sed 's/netbird-\(.*\)\.diff/\1/') + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Generated files for version: $VERSION" + cat netbird-*.diff + + - name: Test FreeBSD port + uses: vmactions/freebsd-vm@v1 + with: + usesh: true + copyback: false + release: "15.0" + prepare: | + # Install required packages + pkg install -y git curl portlint go + + # Install Go for building + GO_TARBALL="go1.24.10.freebsd-amd64.tar.gz" + GO_URL="https://go.dev/dl/$GO_TARBALL" + curl -LO "$GO_URL" + tar -C /usr/local -xzf "$GO_TARBALL" + + # Clone ports tree (shallow, only what we need) + git clone --depth 1 --filter=blob:none https://git.FreeBSD.org/ports.git /usr/ports + cd /usr/ports + + run: | + set -e -x + export PATH=$PATH:/usr/local/go/bin + + # Find the diff file + echo "Finding diff file..." + DIFF_FILE=$(find $PWD -name "netbird-*.diff" -type f 2>/dev/null | head -1) + echo "Found: $DIFF_FILE" + + if [ -z "$DIFF_FILE" ]; then + echo "ERROR: Could not find diff file" + find ~ -name "*.diff" -type f 2>/dev/null || true + exit 1 + fi + + # Apply the generated diff from /usr/ports (diff has a/security/netbird/... paths) + cd /usr/ports + patch -p1 -V none < "$DIFF_FILE" + + # Show patched Makefile + version=$(cat security/netbird/Makefile | grep -E '^DISTVERSION=' | awk '{print $NF}') + + cd /usr/ports/security/netbird + export BATCH=yes + make package + pkg add ./work/pkg/netbird-*.pkg + + netbird version | grep $version + + echo "FreeBSD port test completed successfully!" + + - 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: diff --git a/release_files/freebsd-port-diff.sh b/release_files/freebsd-port-diff.sh new file mode 100755 index 00000000000..8122ab173df --- /dev/null +++ b/release_files/freebsd-port-diff.sh @@ -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() { + 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() { + 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() { + echo "Fetching latest release from GitHub..." >&2 + fetch_all_tags | tail -1 +} + +fetch_ports_file() { + 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 + + 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 + + if [ ! -s "$mod_file" ] || [ ! -s "$zip_file" ]; then + 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}') + 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() { + local old_version="$1" + 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 + 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 +echo "Target version: ${NEW_VERSION}" >&2 + +if [ "$OLD_VERSION" = "$NEW_VERSION" ]; then + 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 + 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 + 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 + 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 + 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" diff --git a/release_files/freebsd-port-issue-body.sh b/release_files/freebsd-port-issue-body.sh new file mode 100755 index 00000000000..bc459b32492 --- /dev/null +++ b/release_files/freebsd-port-issue-body.sh @@ -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 + 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() { + # 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 + # 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" +} + +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 " >&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 " >&2 + exit 1 + fi + echo "Detected NEW version from GitHub: $NEW_VERSION" >&2 +fi + +if [ "$OLD_VERSION" = "$NEW_VERSION" ]; then + 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() { + 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" ] && \ + [ "$(printf '%s\n' "$ver" "$NEW_VERSION" | sort -V | head -n1)" = "$ver" ] && \ + [ "$ver" != "$OLD_VERSION" ]; then + echo "$ver" + fi + done +} + +generate_changelog_section() { + local releases + releases=$(fetch_releases_between_versions) + + echo "Changelogs:" + if [ -n "$releases" ]; then + 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"