mirror of
https://github.com/Mo3he/Axis_Cam_Tailscale.git
synced 2026-09-24 00:34:17 +00:00
172 lines
4.7 KiB
Bash
Executable File
172 lines
4.7 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# Decide which version this repo should build, from .acap.json.
|
|
# Writes build/release/version/upstream to GITHUB_OUTPUT under CI, and always
|
|
# prints the decision so it can be run locally to preview.
|
|
#
|
|
# Policies:
|
|
# mirror the ACAP version follows the upstream version exactly.
|
|
# patch upstream is tracked through a pin; our own last digit is bumped.
|
|
|
|
set -euo pipefail
|
|
|
|
cd "$(dirname "$0")/.."
|
|
|
|
CONFIG=.acap.json
|
|
[ -f "$CONFIG" ] || {
|
|
echo "missing $CONFIG" >&2
|
|
exit 1
|
|
}
|
|
|
|
cfg() { jq -r "$1" "$CONFIG"; }
|
|
|
|
POLICY=$(cfg '.versionPolicy')
|
|
UPSTREAM_TYPE=$(cfg '.upstream.type')
|
|
EVENT_NAME=${EVENT_NAME:-manual}
|
|
INPUT_VERSION=${INPUT_VERSION:-}
|
|
INPUT_FORCE=${INPUT_FORCE:-false}
|
|
|
|
current_version() {
|
|
local manifest conf
|
|
manifest=$(find . -path '*/app/manifest.json' -not -path './node_modules/*' | sort | head -1)
|
|
if [ -n "$manifest" ]; then
|
|
jq -r '.acapPackageConf.setup.version' "$manifest"
|
|
return
|
|
fi
|
|
conf=$(find . -path '*/app/package.conf' | sort | head -1)
|
|
[ -n "$conf" ] && sed -n 's/^VERSION=//p' "$conf" | head -1
|
|
}
|
|
|
|
# Current value of the first pin, used by "patch" to detect upstream movement.
|
|
pin_value() {
|
|
local file arg gomod module
|
|
file=$(cfg '.pins[0].file // empty')
|
|
arg=$(cfg '.pins[0].arg // empty')
|
|
if [ -n "$file" ] && [ -n "$arg" ] && [ -f "$file" ]; then
|
|
sed -n "s/^ARG ${arg}=//p" "$file" | head -1
|
|
return
|
|
fi
|
|
gomod=$(cfg '.upstream.goMod // empty')
|
|
module=$(cfg '.upstream.module // empty')
|
|
if [ -n "$gomod" ] && [ -f "$gomod" ]; then
|
|
# The module may appear as "require mod ver" or as "mod ver" inside a
|
|
# require block, so take the field after the module name wherever it is.
|
|
awk -v m="$module" '{ for (i = 1; i < NF; i++) if ($i == m) { print $(i + 1); exit } }' "$gomod"
|
|
fi
|
|
}
|
|
|
|
# FFmpeg and openvpn3 publish no releases, and their tag lists contain names
|
|
# that are not versions, hence the explicit pattern per repo.
|
|
upstream_version() {
|
|
case "$UPSTREAM_TYPE" in
|
|
github-release)
|
|
local tag
|
|
tag=$(gh api "repos/$(cfg '.upstream.repo')/releases/latest" --jq '.tag_name')
|
|
[ "$(cfg '.upstream.stripV // false')" = true ] && tag=${tag#v}
|
|
printf '%s\n' "$tag"
|
|
;;
|
|
github-tag)
|
|
gh api "repos/$(cfg '.upstream.repo')/tags?per_page=100" --paginate --jq '.[].name' |
|
|
grep -E "$(cfg '.upstream.tagPattern')" |
|
|
sed "s|^$(cfg '.upstream.strip // empty')||" |
|
|
sort -V | tail -1
|
|
;;
|
|
go-module)
|
|
curl -fsSL "https://proxy.golang.org/$(cfg '.upstream.module')/@latest" | jq -r '.Version'
|
|
;;
|
|
script)
|
|
bash "$(cfg '.upstream.script')"
|
|
;;
|
|
*)
|
|
echo ''
|
|
;;
|
|
esac
|
|
}
|
|
|
|
bump_patch() {
|
|
local major minor patch
|
|
IFS='.' read -r major minor patch <<<"$1"
|
|
printf '%s.%s.%s\n' "${major:-0}" "${minor:-0}" "$((${patch:-0} + 1))"
|
|
}
|
|
|
|
# True when $1 is a strictly higher version than $2.
|
|
version_gt() {
|
|
[ "$1" != "$2" ] && [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -1)" = "$1" ]
|
|
}
|
|
|
|
CURRENT=$(current_version)
|
|
UPSTREAM=$(upstream_version || true)
|
|
|
|
BUILD=false
|
|
RELEASE=false
|
|
TARGET="$CURRENT"
|
|
|
|
if [ -n "$INPUT_VERSION" ]; then
|
|
TARGET=${INPUT_VERSION#v}
|
|
BUILD=true
|
|
RELEASE=true
|
|
elif [ "$POLICY" = mirror ]; then
|
|
if [ -n "$UPSTREAM" ] && [ "$UPSTREAM" != "$CURRENT" ]; then
|
|
if version_gt "$UPSTREAM" "$CURRENT"; then
|
|
# Upstream is ahead: adopt its version.
|
|
TARGET="$UPSTREAM"
|
|
BUILD=true
|
|
RELEASE=true
|
|
elif [ "$UPSTREAM" != "$(pin_value)" ]; then
|
|
# Our line already ran past upstream, so keep moving forward on it
|
|
# rather than emitting a lower version that clashes with old tags.
|
|
TARGET=$(bump_patch "$CURRENT")
|
|
BUILD=true
|
|
RELEASE=true
|
|
fi
|
|
fi
|
|
elif [ "$POLICY" = patch ]; then
|
|
if [ -n "$UPSTREAM" ] && [ "$UPSTREAM" != "$(pin_value)" ]; then
|
|
TARGET=$(bump_patch "$CURRENT")
|
|
BUILD=true
|
|
RELEASE=true
|
|
fi
|
|
fi
|
|
|
|
# Pull requests build for validation but never release.
|
|
if [ "$EVENT_NAME" = pull_request ]; then
|
|
BUILD=true
|
|
RELEASE=false
|
|
fi
|
|
|
|
if [ "$INPUT_FORCE" = true ]; then
|
|
BUILD=true
|
|
RELEASE=true
|
|
fi
|
|
|
|
# Never aim at a version that is already published. Stepping forward here means
|
|
# a long build is not wasted only to be rejected by the release job. An explicit
|
|
# version input is respected as given.
|
|
if [ "$RELEASE" = true ] && [ -z "$INPUT_VERSION" ] && command -v gh >/dev/null 2>&1; then
|
|
attempts=0
|
|
while [ "$attempts" -lt 20 ] &&
|
|
gh release view "v$TARGET" --json isDraft --jq '.isDraft' 2>/dev/null | grep -qx false; do
|
|
echo "v$TARGET is already published; stepping forward"
|
|
TARGET=$(bump_patch "$TARGET")
|
|
attempts=$((attempts + 1))
|
|
done
|
|
fi
|
|
|
|
cat <<EOF
|
|
policy : $POLICY
|
|
current : $CURRENT
|
|
upstream : ${UPSTREAM:-n/a}
|
|
target : $TARGET
|
|
build : $BUILD
|
|
release : $RELEASE
|
|
EOF
|
|
|
|
if [ -n "${GITHUB_OUTPUT:-}" ]; then
|
|
{
|
|
echo "build=$BUILD"
|
|
echo "release=$RELEASE"
|
|
echo "version=$TARGET"
|
|
echo "upstream=$UPSTREAM"
|
|
} >>"$GITHUB_OUTPUT"
|
|
fi
|