From d3bee8478cb5983e4d25c3b8db4bf48002601357 Mon Sep 17 00:00:00 2001 From: Tri Vo Khac Date: Tue, 20 Oct 2026 18:37:50 +0700 Subject: [PATCH] feat: add netbird formula and patched netbird-ui cask --- .github/workflows/bump.yml | 61 ++++++++++++++++++++++++++++++++++++++ Casks/netbird-ui.rb | 45 ++++++++++++++++++++++++++++ Formula/netbird.rb | 28 +++++++++++++++++ README.md | 24 +++++++++++++++ 4 files changed, 158 insertions(+) create mode 100644 .github/workflows/bump.yml create mode 100644 Casks/netbird-ui.rb create mode 100644 Formula/netbird.rb create mode 100644 README.md diff --git a/.github/workflows/bump.yml b/.github/workflows/bump.yml new file mode 100644 index 0000000..bff8f1c --- /dev/null +++ b/.github/workflows/bump.yml @@ -0,0 +1,61 @@ +name: Bump netbird + +on: + schedule: + - cron: "17 */2 * * *" + workflow_dispatch: + +permissions: + contents: write + +jobs: + bump: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - name: Update cask to the latest release + env: + GH_TOKEN: ${{ github.token }} + run: | + set -euo pipefail + cask=Casks/netbird-ui.rb + latest=$(gh api repos/netbirdio/netbird/releases/latest --jq .tag_name) + latest=${latest#v} + current=$(sed -nE 's/^ version "([^"]+)"$/\1/p' "$cask") + if [ "$latest" = "$current" ]; then + echo "Already at $current" + exit 0 + fi + + base="https://github.com/netbirdio/netbird/releases/download/v$latest" + declare -A sha + for asset in netbird-ui_${latest}_darwin_{arm64,amd64}_signed.zip netbird_${latest}_darwin_{arm64,amd64}.tar.gz; do + # Release assets can show up a while after the tag. Try again on the next run. + if ! curl -fsSL -o asset "$base/$asset"; then + echo "$asset is not published yet" + exit 0 + fi + sha[$asset]=$(sha256sum asset | cut -d' ' -f1) + rm -f asset + done + + sed -i -E \ + -e "s/^ version \"[^\"]+\"$/ version \"$latest\"/" \ + -e "s/(arm: +\")[0-9a-f]{64}/\1${sha[netbird-ui_${latest}_darwin_arm64_signed.zip]}/" \ + -e "s/(intel: \")[0-9a-f]{64}/\1${sha[netbird-ui_${latest}_darwin_amd64_signed.zip]}/" \ + "$cask" + + # The formula has literal URLs, each followed by its sha256 line. + formula=Formula/netbird.rb + sed -i -E "s/${current//./\\.}/$latest/g" "$formula" + for arch in arm64 amd64; do + asset="netbird_${latest}_darwin_${arch}.tar.gz" + sed -i -E "/\/${asset//./\\.}\"/{n;s/[0-9a-f]{64}/${sha[$asset]}/}" "$formula" + done + git diff + + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git commit -am "chore: bump netbird to $latest" + git push diff --git a/Casks/netbird-ui.rb b/Casks/netbird-ui.rb new file mode 100644 index 0000000..51dedb0 --- /dev/null +++ b/Casks/netbird-ui.rb @@ -0,0 +1,45 @@ +cask "netbird-ui" do + arch arm: "arm64", intel: "amd64" + + version "0.81.3" + sha256 arm: "690a266cfb15367973707f0616f0d1a9691ce026cd346ad4e4225e680e9a99a1", + intel: "0ac46b7e2d1d6b0ec987212ed8b3bcde23976f2efb5539ac1ebc0d8052ecee06" + + url "https://github.com/netbirdio/netbird/releases/download/v#{version}/netbird-ui_#{version}_darwin_#{arch}_signed.zip" + name "Netbird UI" + desc "Desktop client for the NetBird overlay network" + homepage "https://www.netbird.io/" + + livecheck do + url :url + strategy :github_latest + end + + depends_on formula: "vokhactri/tap/netbird" + depends_on :macos + + app "netbird_ui_darwin", target: "Netbird UI.app" + + # The release zip ships installer.sh as 0644. Upstream chmods it inside the + # signed bundle, which can fail with "Operation not permitted". Running it + # through /bin/sh needs no chmod. + postflight_steps do + run "/bin/sh", args: ["{{appdir}}/Netbird UI.app/installer.sh", version], sudo: true + end + + # bootout returns before launchd has removed system/netbird. On upgrade the + # new installer.sh then fails to load the service and the daemon stays down, + # so wait for the old service to go away first. + uninstall_preflight_steps do + run "/bin/launchctl", args: ["bootout", "system/netbird"], + sudo: true, must_succeed: false, print_stderr: false + run "/bin/sh", + args: ["-c", "i=0; while /bin/launchctl print system/netbird >/dev/null 2>&1 && [ $i -lt 30 ]; " \ + "do sleep 0.5; i=$((i + 1)); done"], + sudo: true, + must_succeed: false + run "/bin/launchctl", args: ["unload", "/Library/LaunchDaemons/netbird.plist"], + sudo: true, must_succeed: false, print_stderr: false + remove "/Library/LaunchDaemons/netbird.plist", sudo: true + end +end diff --git a/Formula/netbird.rb b/Formula/netbird.rb new file mode 100644 index 0000000..f6a52a1 --- /dev/null +++ b/Formula/netbird.rb @@ -0,0 +1,28 @@ +class Netbird < Formula + desc "Connect devices into a WireGuard-based overlay network" + homepage "https://netbird.io/" + license "BSD-3-Clause" + + if Hardware::CPU.arm? + url "https://github.com/netbirdio/netbird/releases/download/v0.81.3/netbird_0.81.3_darwin_arm64.tar.gz" + sha256 "bc37108ee88cbc0a998031231570a2c62f03c0937867a0114b8d137e7840fe71" + else + url "https://github.com/netbirdio/netbird/releases/download/v0.81.3/netbird_0.81.3_darwin_amd64.tar.gz" + sha256 "95ef6a3f3c56d7d7d96e66fdf2523a6ee8c719b8beb959e9f15c6a101e4cac1f" + end + + livecheck do + url "https://github.com/netbirdio/netbird" + strategy :github_latest + end + + depends_on :macos + + def install + bin.install "netbird" + end + + test do + assert_match version.to_s, shell_output("#{bin}/netbird version") + end +end diff --git a/README.md b/README.md new file mode 100644 index 0000000..51965a1 --- /dev/null +++ b/README.md @@ -0,0 +1,24 @@ +# vokhactri/homebrew-tap + +My personal Homebrew tap for macOS. + +| Package | Type | Description | +| --- | --- | --- | +| [`netbird`](https://github.com/netbirdio/netbird) | formula | NetBird CLI and daemon | +| [`netbird-ui`](https://github.com/netbirdio/netbird) | cask | NetBird menu bar app | + +## Install + +```sh +brew tap vokhactri/tap +brew trust vokhactri/tap +brew install vokhactri/tap/ +``` + +Use `brew install --cask` for casks. + +## Updates + +A GitHub Action checks for new upstream releases every two hours and commits the new version +and sha256 values. If a release doesn't have its macOS files yet, the Action tries again on the +next run.