Files

146 lines
5.0 KiB
Bash
Raw Permalink Normal View History

2024-02-28 19:21:08 +01:00
#!/bin/bash
2025-06-05 20:37:51 +02:00
# Script to build NetBird mobile bindings using gomobile
# Usage: ./script.sh [version]
2026-08-17 11:45:55 +00:00
#
# Version resolution (first match wins):
# 1. explicit argument -> the argument ('v' prefix stripped)
# 2. local build (any HEAD) -> dev-<sha>
# 3. CI, HEAD on a release tag -> that tag, e.g. 0.77.0
# 4. CI, commits on top of a tag -> 0.77.0+<sha>
# 5. CI, no reachable tag -> ci-<sha>
#
# The base tag is the last stable release tag (vX.Y.Z, no pre-release) found
# walking back HEAD's ancestry in the netbird submodule — the last tag on this
# branch, not the newest tag in the repository. <sha> is the submodule commit.
set -euo pipefail
2024-02-28 19:21:08 +01:00
2025-06-05 20:37:51 +02:00
app_path=$(pwd)
2024-02-28 19:21:08 +01:00
2026-08-17 11:45:55 +00:00
# Stable release tags only ("v" + digits, no pre-release suffix): a pre-release
# base such as "0.75.0-rc.2" would land in SemVer pre-release position, which
# the management server compares differently from a plain release.
readonly RELEASE_TAG_MATCH='v[0-9]*'
readonly RELEASE_TAG_EXCLUDE='*-*'
# The NDK gomobile links against. CI reads this line to install the same one.
readonly NDK_VERSION=23.1.7779620
# Normalize semantic versions to drop a leading 'v' (e.g., v1.2.3 -> 1.2.3).
# Only strips if the string starts with 'v' followed by a digit, so it won't affect
# dev/ci strings or other non-semver values.
normalize_version() {
local ver="$1"
if [[ "$ver" =~ ^v[0-9] ]]; then
ver="${ver#v}"
fi
echo "$ver"
}
2026-08-17 11:45:55 +00:00
describe_release_tag() {
git describe --tags "$@" --match "$RELEASE_TAG_MATCH" --exclude "$RELEASE_TAG_EXCLUDE" 2>/dev/null || true
}
get_version() {
if [ -n "${1:-}" ]; then
normalize_version "$1"
return
fi
2026-08-17 11:45:55 +00:00
local short_hash
short_hash=$(git rev-parse --short HEAD)
2025-07-10 10:02:14 +02:00
2026-08-17 11:45:55 +00:00
if [ "${GITHUB_ACTIONS:-}" != "true" ]; then
echo "dev-$short_hash"
return
fi
local tag
tag=$(describe_release_tag --exact-match)
if [ -n "$tag" ]; then
normalize_version "$tag"
2025-07-10 10:02:14 +02:00
return
fi
2025-07-10 10:02:14 +02:00
2026-08-17 11:45:55 +00:00
# Walks HEAD's ancestry, so this is the last release tag on this branch,
# not the most recently created tag in the repository.
tag=$(describe_release_tag --abbrev=0)
if [ -n "$tag" ]; then
echo "$(normalize_version "$tag")+$short_hash"
return
2025-07-10 10:02:14 +02:00
fi
2026-08-17 11:45:55 +00:00
echo "WARNING: no release tag reachable from HEAD; using ci-$short_hash" >&2
if [ "$(git rev-parse --is-shallow-repository)" = "true" ]; then
echo "WARNING: the submodule is a shallow clone; the tag lookup needs full history" >&2
fi
echo "ci-$short_hash"
}
# gomobile bind shells out to gobind, and gobind is the tool that actually
# generates the Java bindings and the JNI glue. Its own suggestion for a missing
# gobind is `gomobile init`, which installs it from @latest — that would let the
# generator float even though the driver is pinned, changing the generated API
# without a commit here. So both tools are held to the revision go.mod names:
# the module version embedded in each binary (go version -m) is compared to
# that pin, and a missing or diverging tool is reinstalled at the pin.
#
# GOBIN is prepended to PATH so the binary this function verified or installed
# is the one `gomobile bind` (and its PATH lookup of gobind) actually runs,
# even when another copy sits earlier on the caller's PATH.
#
# Must run inside the submodule: the pinned version comes from its go.mod.
ensure_gomobile_tools() {
local want
want=$(go list -m -f '{{.Version}}' golang.org/x/mobile)
local gobin
gobin=$(go env GOBIN)
[ -n "$gobin" ] || gobin="$(go env GOPATH)/bin"
export PATH="$gobin:$PATH"
local tool path have
for tool in gomobile gobind; do
have=""
if path=$(command -v "$tool"); then
# `|| true`: go version fails on binaries without build info, and set -e
# would abort instead of letting the reinstall below repair the tool.
have=$(go version -m "$path" 2>/dev/null \
| awk '$1 == "mod" && $2 == "golang.org/x/mobile" {print $3}') || true
fi
if [ "$have" != "$want" ]; then
echo "Installing $tool at the go.mod pin $want (found: ${have:-none})"
go install "golang.org/x/mobile/cmd/$tool@$want"
fi
done
}
ensure_ndk() {
: "${ANDROID_HOME:?ANDROID_HOME must point at the Android SDK}"
export ANDROID_NDK_HOME="$ANDROID_HOME/ndk/$NDK_VERSION"
if [ ! -d "$ANDROID_NDK_HOME" ]; then
echo "NDK $NDK_VERSION not found under $ANDROID_HOME/ndk; install it with:" >&2
echo " sdkmanager --install \"ndk;$NDK_VERSION\"" >&2
exit 1
fi
}
2025-06-05 20:37:51 +02:00
cd netbird
# Get version using the function
version=$(get_version "${1:-}")
echo "Using version: $version"
ensure_ndk
2026-08-17 11:45:55 +00:00
ensure_gomobile_tools
2024-02-28 19:21:08 +01:00
# -androidapi must match minSdkVersion in build.gradle.kts. Without it gomobile
# defaults to API 16, which only NDK r23 and older still accept.
2025-06-05 20:37:51 +02:00
CGO_ENABLED=0 gomobile bind \
-androidapi 26 \
-o "$app_path/gomobile/netbird.aar" \
2025-06-05 20:37:51 +02:00
-javapkg=io.netbird.gomobile \
2025-11-26 19:04:38 +01:00
-ldflags="-linkmode=external -extldflags=-Wl,-z,max-page-size=16384 -checklinkname=0 -X golang.zx2c4.com/wireguard/ipc.socketDirectory=/data/data/io.netbird.client/cache/wireguard -X github.com/netbirdio/netbird/version.version=$version" \
"$(pwd)/client/android"
2025-06-05 20:37:51 +02:00
cd - > /dev/null