From 6d0876fd19daaca3809886d315fb96bb2ddd2146 Mon Sep 17 00:00:00 2001 From: Ivan Razin Date: Wed, 15 Jul 2026 16:03:13 +0300 Subject: [PATCH] feat(installer): add -version flag to pin 3x-ui release Accepts 3.4.2 or v3.4.2; validates the tag exists on GitHub before download, falls back to latest when omitted. Co-Authored-By: Claude Fable 5 --- CLAUDE.md | 2 +- README.md | 1 + README_EN.md | 1 + x-ui-latest.sh | 23 ++++++++++++++++------- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 8b49750..43f9102 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -27,7 +27,7 @@ effect on servers only after push to `main`. ## What x-ui-latest.sh does 1. Checks OS (Ubuntu 24.04/26.04, Debian 12/13) and rejects QEMU-emulated CPUs -2. Parses CLI arguments (`-install y`, `-subdomain`, `-reality_domain`, `-auto_domain y`, `-uninstall y`) +2. Parses CLI arguments (`-install y`, `-subdomain`, `-reality_domain`, `-auto_domain y`, `-version `, `-uninstall y`) 3. Validates domains (panel ≠ REALITY), then stops/cleans any previous install 4. Installs packages (`install_packages`) — nginx-full, certbot, sqlite3, ufw, mtr, python3 … 5. Obtains Let's Encrypt certs via certbot standalone (`get_ssl_certs`) — panel + reality domains diff --git a/README.md b/README.md index 4f6facb..aa5f2f3 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ bash x-ui-latest.sh -uninstall y | `-subdomain <домен>` | Домен панели и подписок | | `-reality_domain <домен>` | Домен назначения для REALITY | | `-auto_domain y` | Автоопределение домена (без ручного ввода) | +| `-version <версия>` | Установить конкретную версию 3x-ui (например `3.4.2`), по умолчанию — последняя | | `-uninstall y` | Полное удаление | --- diff --git a/README_EN.md b/README_EN.md index d6c591c..2873349 100644 --- a/README_EN.md +++ b/README_EN.md @@ -88,6 +88,7 @@ bash x-ui-latest.sh -uninstall y | `-subdomain ` | Panel and subscription domain | | `-reality_domain ` | REALITY destination domain | | `-auto_domain y` | Auto-detect domain (no manual input) | +| `-version ` | Install specific 3x-ui version (e.g. `3.4.2`), default — latest | | `-uninstall y` | Full uninstall | --- diff --git a/x-ui-latest.sh b/x-ui-latest.sh index 4a09a64..8e8bb56 100644 --- a/x-ui-latest.sh +++ b/x-ui-latest.sh @@ -126,6 +126,7 @@ while [ "$#" -gt 0 ]; do -subdomain) domain="$2"; shift 2 ;; -reality_domain) reality_domain="$2"; shift 2 ;; -ONLY_CF_IP_ALLOW) CFALLOW="$2"; shift 2 ;; + -version) PANEL_VERSION="$2"; shift 2 ;; -uninstall) UNINSTALL="$2"; shift 2 ;; *) shift 1 ;; esac @@ -727,14 +728,22 @@ install_panel() { cd /usr/local/ - tag_version=$(curl -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" \ - | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - if [[ -z "$tag_version" ]]; then - tag_version=$(curl -4 -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" \ + if [[ -n "$PANEL_VERSION" ]]; then + tag_version="v${PANEL_VERSION#v}" + if ! curl -fsLo /dev/null "https://api.github.com/repos/MHSanaei/3x-ui/releases/tags/${tag_version}" \ + && ! curl -4 -fsLo /dev/null "https://api.github.com/repos/MHSanaei/3x-ui/releases/tags/${tag_version}"; then + echo "3x-ui release ${tag_version} not found." && exit 1 + fi + else + tag_version=$(curl -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" \ | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - fi - if [[ -z "$tag_version" ]]; then - echo "Failed to fetch 3x-ui version." && exit 1 + if [[ -z "$tag_version" ]]; then + tag_version=$(curl -4 -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" \ + | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') + fi + if [[ -z "$tag_version" ]]; then + echo "Failed to fetch 3x-ui version." && exit 1 + fi fi echo "Installing 3x-ui ${tag_version} ..."