RKNnoVPN/scripts/ci/check_release_manifest.sh
loop-uh 2ccfe8ce0a
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
Перенести выпуск RKNnoVPN на Forgejo
2026-08-07 03:08:36 +03:00

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"