Some checks failed
RKNnoVPN Linux and Android CI / policy-and-go (push) Successful in 14s
RKNnoVPN Linux and Android CI / android-debug (push) Successful in 2m5s
Full build and Forgejo release / Privacy Lint (push) Successful in 3s
Full build and Forgejo release / Local-first Runtime Guardrail (push) Successful in 2s
Full build and Forgejo release / Go Tests (push) Successful in 13s
Full build and Forgejo release / Resolve sing-box release (push) Successful in 1s
Full build and Forgejo release / Resolve Xray-core release (push) Successful in 1s
Full build and Forgejo release / Android Guardrails & Tests (push) Failing after 16s
Full build and Forgejo release / Build APK (push) Has been skipped
Full build and Forgejo release / Build Runtime CLI (arm64) (push) Successful in 11s
Full build and Forgejo release / Build Runtime CLI (armv7) (push) Successful in 11s
Full build and Forgejo release / Build sing-box (arm64) (push) Failing after 2s
Full build and Forgejo release / Build sing-box (armv7) (push) Failing after 2s
Full build and Forgejo release / Build Xray-core (arm64) (push) Failing after 3s
Full build and Forgejo release / Build Xray-core (armv7) (push) Failing after 2s
Full build and Forgejo release / Build Magisk Module (push) Has been skipped
Full build and Forgejo release / Create Release (push) Has been skipped
133 lines
6.5 KiB
Shell
133 lines
6.5 KiB
Shell
#!/usr/bin/env bash
|
|
# Repository-independent Forgejo/local policy check.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
fail() {
|
|
echo "release manifest: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
version_code() {
|
|
tools/version.sh code "$1" || fail "invalid versionCode input: $1"
|
|
}
|
|
|
|
extract_go_version() {
|
|
local file="$1"
|
|
sed -n 's/^[[:space:]]*\(var[[:space:]]\+\)\{0,1\}Version[[:space:]]*=[[:space:]]*"\([^"]*\)".*/\2/p' "$file" | head -n 1
|
|
}
|
|
|
|
release_version="$(tools/version.sh current)"
|
|
release_code="$(version_code "$release_version")"
|
|
runtime_version="$(extract_go_version runtime/cmd/rknnovpn-runtime/main.go)"
|
|
module_version="$(sed -n 's/^version=//p' module/module.prop | head -n 1)"
|
|
module_code="$(sed -n 's/^versionCode=//p' module/module.prop | head -n 1)"
|
|
update_version="$(sed -n 's/[[:space:]]*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' update.json | head -n 1)"
|
|
update_code="$(sed -n 's/[[:space:]]*"versionCode"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p' update.json | head -n 1)"
|
|
|
|
[ -n "$release_version" ] || fail "VERSION is empty"
|
|
[ -n "$release_code" ] || fail "VERSION does not produce a versionCode"
|
|
[ "$runtime_version" = "dev" ] || fail "runtime source default Version must stay dev; release builds stamp it with ldflags"
|
|
grep -q 'versionName = rknnoVpnVersionName' app/app/build.gradle.kts || fail "APK versionName must come from the shared VERSION source"
|
|
grep -q 'versionCode = rknnoVpnVersionCode' app/app/build.gradle.kts || fail "APK versionCode must come from the shared VERSION formula"
|
|
|
|
[ -n "$module_version" ] || fail "module version not found"
|
|
[ -n "$module_code" ] || fail "module versionCode not found"
|
|
if [ "$module_version" = "dev" ]; then
|
|
[ "$module_code" = "0" ] || fail "module template versionCode must be 0 when version is dev"
|
|
else
|
|
[ "$module_code" = "$(version_code "$module_version")" ] || fail "module versionCode $module_code does not match $module_version"
|
|
fi
|
|
[ -n "$update_version" ] || fail "update.json version not found"
|
|
[ -n "$update_code" ] || fail "update.json versionCode not found"
|
|
[ "$update_code" = "$(version_code "$update_version")" ] || fail "update.json versionCode $update_code does not match $update_version"
|
|
|
|
for required in \
|
|
module/META-INF/com/google/android/update-binary \
|
|
module/META-INF/com/google/android/updater-script \
|
|
module/scripts/lib/rknnovpn_env.sh \
|
|
module/scripts/lib/rknnovpn_install.sh \
|
|
module/scripts/lib/rknnovpn_installer_flow.sh \
|
|
module/scripts/lib/rknnovpn_netstack.sh \
|
|
module/scripts/lib/rknnovpn_iptables_rules.sh \
|
|
module/scripts/rescue_reset.sh \
|
|
module/scripts/routing.sh \
|
|
module/scripts/iptables.sh \
|
|
module/scripts/dns.sh \
|
|
module/OWNERSHIP.md \
|
|
module/customize.sh \
|
|
module/service.sh \
|
|
module/post-fs-data.sh \
|
|
module/uninstall.sh; do
|
|
[ -f "$required" ] || fail "required module file missing: $required"
|
|
done
|
|
|
|
if [ "$(tr -d '\r\n' < module/META-INF/com/google/android/updater-script)" != "#MAGISK" ]; then
|
|
fail "Magisk updater-script must contain only #MAGISK"
|
|
fi
|
|
|
|
if ! grep -q 'install_module' module/META-INF/com/google/android/update-binary; then
|
|
fail "Magisk update-binary must invoke install_module"
|
|
fi
|
|
|
|
if ! grep -q 'SRC_BIN="${MODPATH}/binaries/${ARCH_DIR}"' module/scripts/lib/rknnovpn_installer_flow.sh; then
|
|
fail "installer must resolve only canonical module binary directories"
|
|
fi
|
|
|
|
if grep -Eq 'restore_missing_binaries|Restoring missing or non-executable binary|binary restore|binaries/.*rknnovpn-runtime' module/service.sh; then
|
|
fail "service.sh must not run boot-time binary restore loops"
|
|
fi
|
|
|
|
android_abi_dir_pattern='binaries/(arm64-v8a|armeabi-v7a)'
|
|
removed_arch_var='ARCH_''ABI_DIR'
|
|
if grep -REn "${removed_arch_var}|${android_abi_dir_pattern}" .forgejo/workflows Makefile module/scripts >/tmp/release-manifest-noncanonical-dirs.$$ 2>/dev/null; then
|
|
cat /tmp/release-manifest-noncanonical-dirs.$$ >&2
|
|
rm -f /tmp/release-manifest-noncanonical-dirs.$$
|
|
fail "release packaging must use only canonical binary directories"
|
|
fi
|
|
rm -f /tmp/release-manifest-noncanonical-dirs.$$
|
|
|
|
expected_zip="https://git.zapret.moe/zapretdiscordyoutube/RKNnoVPN/releases/download/${update_version}/rknnovpn-${update_version}-module.zip"
|
|
expected_changelog="https://git.zapret.moe/zapretdiscordyoutube/RKNnoVPN/releases/tag/${update_version}"
|
|
update_zip="$(sed -n 's/[[:space:]]*"zipUrl"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' update.json | head -n 1)"
|
|
update_changelog="$(sed -n 's/[[:space:]]*"changelog"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' update.json | head -n 1)"
|
|
[ "$update_zip" = "$expected_zip" ] || fail "update.json zipUrl is not $expected_zip"
|
|
[ "$update_changelog" = "$expected_changelog" ] || fail "update.json changelog is not $expected_changelog"
|
|
|
|
if grep -REn 's/v//;s/\\?\.//g|s/v//;s/\.//g' .forgejo/workflows Makefile >/tmp/release-manifest-removed-code.$$ 2>/dev/null; then
|
|
cat /tmp/release-manifest-removed-code.$$ >&2
|
|
rm -f /tmp/release-manifest-removed-code.$$
|
|
fail "removed dot-stripping versionCode formula is forbidden"
|
|
fi
|
|
rm -f /tmp/release-manifest-removed-code.$$
|
|
|
|
if grep -REn 'major \* 1000[[:space:]]*\+ minor \* 100[[:space:]]*\+ patch|s/v//;s/\\?\.//g|s/v//;s/\.//g' .forgejo/workflows Makefile app/app/build.gradle.kts tools/version.sh >/tmp/release-manifest-removed-code.$$ 2>/dev/null; then
|
|
cat /tmp/release-manifest-removed-code.$$ >&2
|
|
rm -f /tmp/release-manifest-removed-code.$$
|
|
fail "non-canonical versionCode formula is forbidden"
|
|
fi
|
|
rm -f /tmp/release-manifest-removed-code.$$
|
|
|
|
if [ "$(version_code v2.3.0)" != "2030000" ] || [ "$(version_code v1.8.0)" != "1080000" ] || [ "$(version_code v1.7.13)" != "1071300" ] || [ "$(version_code v2.10.0)" != "2100000" ]; then
|
|
fail "canonical version_code formula must use fixed semver slots"
|
|
fi
|
|
if [ "$(version_code v1.10.0)" = "$(version_code v2.0.0)" ]; then
|
|
fail "canonical version_code formula collides for v1.10.0 and v2.0.0"
|
|
fi
|
|
if ! grep -q 'VERSION' Makefile || ! grep -q 'rootProject.file("../VERSION")' app/app/build.gradle.kts; then
|
|
fail "release version must stay centralized in the root VERSION file"
|
|
fi
|
|
if grep -REn 'SCRIPT_VERSION="v[0-9]|Version = "v[0-9]' runtime/cmd module/scripts >/tmp/release-manifest-hardcoded-version.$$ 2>/dev/null; then
|
|
cat /tmp/release-manifest-hardcoded-version.$$ >&2
|
|
rm -f /tmp/release-manifest-hardcoded-version.$$
|
|
fail "runtime source must not hardcode release versions"
|
|
fi
|
|
rm -f /tmp/release-manifest-hardcoded-version.$$
|
|
|
|
if [ "$(version_code "$release_version")" != "$release_code" ]; then
|
|
fail "canonical version_code formula must use fixed semver slots"
|
|
fi
|
|
|
|
echo "release manifest: ${release_version} (${release_code}) ok"
|