feat: organize scripts and add portal validation assets
This commit is contained in:
40
scripts/README.md
Normal file
40
scripts/README.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# scripts 目录说明
|
||||
|
||||
日期:2026-05-27
|
||||
|
||||
`scripts/` 当前按职责拆成三层,避免部署、验收和回归入口继续平铺混杂。
|
||||
|
||||
## 目录划分
|
||||
|
||||
- `scripts/deploy/`
|
||||
- 部署、构建、远端环境拉起
|
||||
- 例如:
|
||||
- `build_local_image.sh`
|
||||
- `deploy_tksea_portal.sh`
|
||||
- `setup_remote43_patched_stack.sh`
|
||||
- `scripts/acceptance/`
|
||||
- 真实宿主验收、upstream 直探、artifact 安全化
|
||||
- 例如:
|
||||
- `real_host_acceptance.sh`
|
||||
- `import_remote43_provider.sh`
|
||||
- `check_deepseek_completion_split.sh`
|
||||
- `scripts/test/`
|
||||
- 脚本自身的回归与资产检查
|
||||
- 例如:
|
||||
- `test_real_host_scripts.sh`
|
||||
- `test_tksea_portal_assets.sh`
|
||||
|
||||
## 放置规则
|
||||
|
||||
- 新增脚本前先判断它属于 `deploy`、`acceptance` 还是 `test`
|
||||
- 需要被目标机直接消费的静态文件不要放这里,应放到 `deploy/`
|
||||
- 真实验收产物不要放这里,应落到 `artifacts/`
|
||||
|
||||
## 常用入口
|
||||
|
||||
```bash
|
||||
bash ./scripts/test/test_real_host_scripts.sh
|
||||
bash ./scripts/test/test_tksea_portal_assets.sh
|
||||
scripts/deploy/build_local_image.sh
|
||||
bash ./scripts/acceptance/real_host_acceptance.sh
|
||||
```
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Helpers for redacting real-host acceptance artifacts."""
|
||||
import hashlib
|
||||
import json
|
||||
import pathlib
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# 环境变量驱动,便于被不同验收 harness 复用。
|
||||
|
||||
require_var() {
|
||||
local name="$1"
|
||||
if [[ -z "${!name:-}" ]]; then
|
||||
2
scripts/host_access_prep_lib.sh → scripts/acceptance/host_access_prep_lib.sh
Normal file → Executable file
2
scripts/host_access_prep_lib.sh → scripts/acceptance/host_access_prep_lib.sh
Normal file → Executable file
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# SQL 和缓存 key 组装 helper,供 remote acceptance 脚本复用。
|
||||
|
||||
sql_escape_literal() {
|
||||
local value="$1"
|
||||
local squote="'"
|
||||
@@ -6,10 +6,10 @@ model_name="${2:?model_name required}"
|
||||
env_var="${3:?env var required}"
|
||||
key_file="${4:-}"
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT_DIR/scripts/host_access_prep_lib.sh"
|
||||
ARTIFACT_REDACTION_SCRIPT="$ROOT_DIR/scripts/artifact_redaction.py"
|
||||
source "$ROOT_DIR/scripts/acceptance/host_access_prep_lib.sh"
|
||||
ARTIFACT_REDACTION_SCRIPT="$ROOT_DIR/scripts/acceptance/artifact_redaction.py"
|
||||
|
||||
KEY="${KEY:-/home/long/下载/zjsea.pem}"
|
||||
REMOTE="${REMOTE:-ubuntu@43.155.133.187}"
|
||||
@@ -33,12 +33,12 @@ mkdir -p "$ART"
|
||||
|
||||
artifact_redact_key_json() {
|
||||
local value="$1"
|
||||
python3 "$ROOT_DIR/scripts/artifact_redaction.py" redact-key "$value"
|
||||
python3 "$ROOT_DIR/scripts/acceptance/artifact_redaction.py" redact-key "$value"
|
||||
}
|
||||
|
||||
artifact_redact_id() {
|
||||
local value="$1"
|
||||
python3 "$ROOT_DIR/scripts/artifact_redaction.py" redact-id "$value"
|
||||
python3 "$ROOT_DIR/scripts/acceptance/artifact_redaction.py" redact-id "$value"
|
||||
}
|
||||
|
||||
write_json_file() {
|
||||
@@ -49,20 +49,20 @@ write_json_file() {
|
||||
|
||||
sanitize_headers_file() {
|
||||
local path="$1"
|
||||
python3 "$ROOT_DIR/scripts/artifact_redaction.py" sanitize-headers "$path" "$path"
|
||||
python3 "$ROOT_DIR/scripts/acceptance/artifact_redaction.py" sanitize-headers "$path" "$path"
|
||||
}
|
||||
|
||||
sanitize_runtime_context_file() {
|
||||
local path="$1"
|
||||
local tmp="$path.tmp"
|
||||
python3 "$ROOT_DIR/scripts/artifact_redaction.py" sanitize-runtime-context "$path" "$tmp"
|
||||
python3 "$ROOT_DIR/scripts/acceptance/artifact_redaction.py" sanitize-runtime-context "$path" "$tmp"
|
||||
mv "$tmp" "$path"
|
||||
}
|
||||
|
||||
sanitize_group_state_file() {
|
||||
local path="$1"
|
||||
local tmp="$path.tmp"
|
||||
python3 "$ROOT_DIR/scripts/artifact_redaction.py" sanitize-group-state "$path" "$tmp"
|
||||
python3 "$ROOT_DIR/scripts/acceptance/artifact_redaction.py" sanitize-group-state "$path" "$tmp"
|
||||
mv "$tmp" "$path"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Normalize historical real-host artifacts into repo-safe form."""
|
||||
import json
|
||||
import pathlib
|
||||
import shutil
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
|
||||
ARTIFACT_DIR="${ARTIFACT_DIR:-$ROOT_DIR/artifacts/real-host-acceptance/$TIMESTAMP}"
|
||||
DRY_RUN="${DRY_RUN:-0}"
|
||||
@@ -47,7 +47,7 @@ save_json() {
|
||||
|
||||
artifact_redact_key_json() {
|
||||
local value="$1"
|
||||
python3 "$ROOT_DIR/scripts/artifact_redaction.py" redact-key "$value"
|
||||
python3 "$ROOT_DIR/scripts/acceptance/artifact_redaction.py" redact-key "$value"
|
||||
}
|
||||
|
||||
write_checklist_guide() {
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
IMAGE_TAG="${IMAGE_TAG:-sub2api-cn-relay-manager:local}"
|
||||
BINARY_PATH="${BINARY_PATH:-$ROOT_DIR/bin/sub2api-cn-relay-manager}"
|
||||
|
||||
161
scripts/deploy/deploy_tksea_portal.sh
Executable file
161
scripts/deploy/deploy_tksea_portal.sh
Executable file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
KEY="${KEY:-/home/long/下载/zjsea.pem}"
|
||||
REMOTE="${REMOTE:-ubuntu@43.155.133.187}"
|
||||
REMOTE_PORTAL_DIR="${REMOTE_PORTAL_DIR:-/var/www/sub2api-portal}"
|
||||
REMOTE_NGINX_SITE="${REMOTE_NGINX_SITE:-/etc/nginx/sites-available/tksea}"
|
||||
REMOTE_HOST_PORT="${REMOTE_HOST_PORT:-18169}"
|
||||
LOCAL_PORTAL_INDEX="${LOCAL_PORTAL_INDEX:-$ROOT_DIR/deploy/tksea-portal/index.html}"
|
||||
REMOTE_STAGE_DIR="${REMOTE_STAGE_DIR:-/tmp/sub2api-portal-deploy}"
|
||||
DRY_RUN="${DRY_RUN:-0}"
|
||||
|
||||
die() {
|
||||
echo "$*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
require_cmd() {
|
||||
command -v "$1" >/dev/null 2>&1 || die "missing command: $1"
|
||||
}
|
||||
|
||||
run_cmd() {
|
||||
if [[ "$DRY_RUN" == "1" ]]; then
|
||||
printf 'DRY_RUN:'
|
||||
printf ' %q' "$@"
|
||||
printf '\n'
|
||||
return 0
|
||||
fi
|
||||
"$@"
|
||||
}
|
||||
|
||||
ssh_remote() {
|
||||
run_cmd ssh -i "$KEY" -o StrictHostKeyChecking=no "$REMOTE" "$@"
|
||||
}
|
||||
|
||||
scp_remote() {
|
||||
run_cmd scp -i "$KEY" -o StrictHostKeyChecking=no "$@"
|
||||
}
|
||||
|
||||
main() {
|
||||
require_cmd python3
|
||||
require_cmd ssh
|
||||
require_cmd scp
|
||||
|
||||
[[ -f "$LOCAL_PORTAL_INDEX" ]] || die "missing portal index: $LOCAL_PORTAL_INDEX"
|
||||
if [[ "$DRY_RUN" != "1" ]]; then
|
||||
[[ -f "$KEY" ]] || die "missing ssh key: $KEY"
|
||||
fi
|
||||
|
||||
local tmpdir patch_file index_copy
|
||||
tmpdir="$(mktemp -d)"
|
||||
trap "rm -rf $(printf '%q' "$tmpdir")" EXIT
|
||||
patch_file="$tmpdir/patch_tksea_portal_nginx.py"
|
||||
index_copy="$tmpdir/index.html"
|
||||
|
||||
cp "$LOCAL_PORTAL_INDEX" "$index_copy"
|
||||
|
||||
cat > "$patch_file" <<EOF
|
||||
from pathlib import Path
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
|
||||
path = Path(${REMOTE_NGINX_SITE@Q})
|
||||
text = path.read_text()
|
||||
block = textwrap.dedent("""\
|
||||
location = /portal {
|
||||
return 302 /portal/;
|
||||
}
|
||||
|
||||
location = /kimi-portal {
|
||||
return 302 /portal/;
|
||||
}
|
||||
|
||||
# BEGIN sub2api-portal
|
||||
location /portal/ {
|
||||
alias ${REMOTE_PORTAL_DIR}/;
|
||||
index index.html;
|
||||
try_files \$uri \$uri/ /portal/index.html;
|
||||
}
|
||||
|
||||
location /portal-proxy/ {
|
||||
proxy_pass http://127.0.0.1:${REMOTE_HOST_PORT}/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location /kimi-portal/ {
|
||||
return 302 /portal/;
|
||||
}
|
||||
|
||||
location /kimi-portal-proxy/ {
|
||||
proxy_pass http://127.0.0.1:${REMOTE_HOST_PORT}/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location /kimi/ {
|
||||
proxy_pass http://127.0.0.1:${REMOTE_HOST_PORT}/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
|
||||
location /kimi-v1/ {
|
||||
proxy_pass http://127.0.0.1:${REMOTE_HOST_PORT}/v1/;
|
||||
proxy_set_header Host \$host;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto \$scheme;
|
||||
proxy_http_version 1.1;
|
||||
}
|
||||
# END sub2api-portal
|
||||
|
||||
""")
|
||||
|
||||
patterns = [
|
||||
re.compile(r"\\n\\s*location = /portal \\{.*?# END sub2api-portal\\n\\n", re.S),
|
||||
re.compile(r"\\n\\s*location = /kimi-portal \\{.*?# END kimi-portal\\n\\n", re.S),
|
||||
]
|
||||
|
||||
for pattern in patterns:
|
||||
if pattern.search(text):
|
||||
text = pattern.sub("\\n" + block + "\\n", text, count=1)
|
||||
path.write_text(text)
|
||||
raise SystemExit(0)
|
||||
|
||||
needle = "\\n location / {\\n proxy_pass http://127.0.0.1:"
|
||||
index = text.rfind(needle)
|
||||
if index == -1:
|
||||
raise SystemExit("failed to locate sub.tksea.top root location block")
|
||||
|
||||
text = text[:index] + "\\n" + block + text[index:]
|
||||
path.write_text(text)
|
||||
EOF
|
||||
|
||||
ssh_remote "mkdir -p $(printf '%q' "$REMOTE_STAGE_DIR")"
|
||||
scp_remote "$index_copy" "$REMOTE:$REMOTE_STAGE_DIR/index.html"
|
||||
scp_remote "$patch_file" "$REMOTE:$REMOTE_STAGE_DIR/patch_tksea_portal_nginx.py"
|
||||
ssh_remote "sudo install -d -m 755 $(printf '%q' "$REMOTE_PORTAL_DIR") && sudo cp $(printf '%q' "$REMOTE_STAGE_DIR/index.html") $(printf '%q' "$REMOTE_PORTAL_DIR/index.html") && sudo python3 $(printf '%q' "$REMOTE_STAGE_DIR/patch_tksea_portal_nginx.py") && sudo nginx -t && sudo systemctl reload nginx"
|
||||
|
||||
cat <<EOF
|
||||
tksea portal deployed
|
||||
remote: ${REMOTE}
|
||||
portal url: https://sub.tksea.top/portal/
|
||||
legacy url: https://sub.tksea.top/kimi-portal/
|
||||
portal dir: ${REMOTE_PORTAL_DIR}
|
||||
nginx site: ${REMOTE_NGINX_SITE}
|
||||
EOF
|
||||
}
|
||||
|
||||
main "$@"
|
||||
2
scripts/remote43_patched_stack_lib.sh → scripts/deploy/remote43_patched_stack_lib.sh
Normal file → Executable file
2
scripts/remote43_patched_stack_lib.sh → scripts/deploy/remote43_patched_stack_lib.sh
Normal file → Executable file
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# remote43 patched stack 渲染 helper,供部署脚本和测试脚本共享。
|
||||
|
||||
remote43_require_file() {
|
||||
local path="$1"
|
||||
local label="$2"
|
||||
@@ -1,9 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT_DIR/scripts/remote43_patched_stack_lib.sh"
|
||||
source "$ROOT_DIR/scripts/deploy/remote43_patched_stack_lib.sh"
|
||||
|
||||
KEY="${KEY:-/home/long/下载/zjsea.pem}"
|
||||
REMOTE="${REMOTE:-ubuntu@43.155.133.187}"
|
||||
@@ -198,7 +198,7 @@ shared pack path: ${LOCAL_SHARED_PACK_DIR}
|
||||
next:
|
||||
1. 在另一终端运行: ${LOCAL_TUNNEL_SCRIPT}
|
||||
2. 当前终端执行: set -a; source ${LOCAL_OPERATOR_ENV_FILE}; set +a
|
||||
3. 再运行: bash ${ROOT_DIR}/scripts/import_remote43_provider.sh kimi-a7m kimi-k2.6 A7M_KIMI_API_KEY /path/to/keyfile
|
||||
3. 再运行: bash ${ROOT_DIR}/scripts/acceptance/import_remote43_provider.sh kimi-a7m kimi-k2.6 A7M_KIMI_API_KEY /path/to/keyfile
|
||||
EOF
|
||||
}
|
||||
|
||||
16
scripts/test_real_host_scripts.sh → scripts/test/test_real_host_scripts.sh
Normal file → Executable file
16
scripts/test_real_host_scripts.sh → scripts/test/test_real_host_scripts.sh
Normal file → Executable file
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
@@ -26,7 +26,7 @@ assert_not_contains() {
|
||||
|
||||
run_test_build_subscription_access_prep_sql() {
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT_DIR/scripts/host_access_prep_lib.sh"
|
||||
source "$ROOT_DIR/scripts/acceptance/host_access_prep_lib.sh"
|
||||
|
||||
local sql
|
||||
sql="$(build_subscription_access_prep_sql 42 'sk-test-123' 7 10 30 1 'hermes remote subscription validation')"
|
||||
@@ -141,7 +141,7 @@ EOF
|
||||
SUBSCRIPTION_USERS="42" \
|
||||
SKIP_ROLLBACK="1" \
|
||||
AFTER_IMPORT_HOOK_COMMAND='printf "%s\n" "$BATCH_ID:$BATCH_DETAIL_FILE:$ACCESS_MODE" > "$ARTIFACT_DIR/hook.txt"' \
|
||||
"$ROOT_DIR/scripts/real_host_acceptance.sh" >"$stdout_file"
|
||||
"$ROOT_DIR/scripts/acceptance/real_host_acceptance.sh" >"$stdout_file"
|
||||
|
||||
[[ -f "$hook_file" ]] || fail "after-import hook did not create $hook_file"
|
||||
[[ -f "$guide_file" ]] || fail "artifact guide was not created"
|
||||
@@ -244,7 +244,7 @@ EOF
|
||||
UPSTREAM_BASE="https://upstream.example.com/v1" \
|
||||
UPSTREAM_API_KEY="upstream-key" \
|
||||
MODEL="deepseek-v4-flash" \
|
||||
bash "$ROOT_DIR/scripts/check_deepseek_completion_split.sh" >"$stdout_file"
|
||||
bash "$ROOT_DIR/scripts/acceptance/check_deepseek_completion_split.sh" >"$stdout_file"
|
||||
|
||||
[[ -f "$summary_file" ]] || fail "missing summary file: $summary_file"
|
||||
local summary stdout_contents host_headers upstream_headers
|
||||
@@ -501,7 +501,7 @@ EOF
|
||||
SUBSCRIPTION_DAYS=30 \
|
||||
MIN_BALANCE=10 \
|
||||
SKIP_ROLLBACK=1 \
|
||||
bash "$ROOT_DIR/scripts/import_remote43_provider.sh" deepseek gpt-4 UPSTREAM_KEY >/dev/null
|
||||
bash "$ROOT_DIR/scripts/acceptance/import_remote43_provider.sh" deepseek gpt-4 UPSTREAM_KEY >/dev/null
|
||||
|
||||
[[ -f "$summary_file" ]] || fail "prep summary was not captured"
|
||||
local prep_summary
|
||||
@@ -618,7 +618,7 @@ EOF
|
||||
{"access_closures":[{"DetailsJSON":"{\"requested_probe_api_key\":\"sk-raw-probe-20260523b\",\"subscription_users\":[\"crm-user\"]}"}]}
|
||||
EOF
|
||||
|
||||
python3 "$ROOT_DIR/scripts/migrate_historical_artifacts.py" "$src_root" >/dev/null
|
||||
python3 "$ROOT_DIR/scripts/acceptance/migrate_historical_artifacts.py" "$src_root" >/dev/null
|
||||
|
||||
local migrated_runtime migrated_key_source migrated_invalidation migrated_group_state headers_text summary_json semantic_json details_json
|
||||
migrated_runtime="$(cat "$target_dir/01-runtime-context.json")"
|
||||
@@ -654,7 +654,7 @@ EOF
|
||||
|
||||
run_test_remote43_patched_stack_renderers() {
|
||||
# shellcheck disable=SC1091
|
||||
source "$ROOT_DIR/scripts/remote43_patched_stack_lib.sh"
|
||||
source "$ROOT_DIR/scripts/deploy/remote43_patched_stack_lib.sh"
|
||||
|
||||
local host_env crm_env bootstrap
|
||||
host_env="$(render_remote43_host_env "stack-pg" "stack-redis" "db-pass" "sub2api" "admin@sub2api.local" "admin-pass" "jwt-secret" "totp-secret")"
|
||||
@@ -733,7 +733,7 @@ run_test_setup_remote43_patched_stack_dry_run() {
|
||||
LOCAL_TUNNEL_SCRIPT="$tunnel_script" \
|
||||
REMOTE_ROOT="/home/ubuntu/test-stack" \
|
||||
DRY_RUN=1 \
|
||||
bash "$ROOT_DIR/scripts/setup_remote43_patched_stack.sh" >"$stdout_file"
|
||||
bash "$ROOT_DIR/scripts/deploy/setup_remote43_patched_stack.sh" >"$stdout_file"
|
||||
|
||||
[[ -f "$operator_env" ]] || fail "operator env file was not created"
|
||||
[[ -f "$tunnel_script" ]] || fail "tunnel script was not created"
|
||||
54
scripts/test/test_tksea_portal_assets.sh
Executable file
54
scripts/test/test_tksea_portal_assets.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||
HTML_FILE="$ROOT_DIR/deploy/tksea-portal/index.html"
|
||||
NGINX_FILE="$ROOT_DIR/deploy/tksea-portal/nginx.sub.tksea.top.conf.example"
|
||||
DEPLOY_SCRIPT="$ROOT_DIR/scripts/deploy/deploy_tksea_portal.sh"
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
assert_contains_file() {
|
||||
local file="$1"
|
||||
local needle="$2"
|
||||
if ! grep -Fq "$needle" "$file"; then
|
||||
fail "expected [$needle] in $file"
|
||||
fi
|
||||
}
|
||||
|
||||
[[ -f "$HTML_FILE" ]] || fail "missing $HTML_FILE"
|
||||
[[ -f "$NGINX_FILE" ]] || fail "missing $NGINX_FILE"
|
||||
[[ -f "$DEPLOY_SCRIPT" ]] || fail "missing $DEPLOY_SCRIPT"
|
||||
|
||||
assert_contains_file "$HTML_FILE" "Sub2API 多模型接入中心"
|
||||
assert_contains_file "$HTML_FILE" "https://sub.tksea.top/portal/"
|
||||
assert_contains_file "$HTML_FILE" "/portal-proxy/api/v1"
|
||||
assert_contains_file "$HTML_FILE" "localStorage.setItem"
|
||||
assert_contains_file "$HTML_FILE" "/auth/me"
|
||||
assert_contains_file "$HTML_FILE" "/groups/available"
|
||||
assert_contains_file "$HTML_FILE" "/subscriptions"
|
||||
assert_contains_file "$HTML_FILE" "/keys?page=1&page_size=20"
|
||||
assert_contains_file "$HTML_FILE" "copy-existing-key-btn"
|
||||
assert_contains_file "$HTML_FILE" "已有 Key"
|
||||
assert_contains_file "$HTML_FILE" "showToast"
|
||||
assert_contains_file "$HTML_FILE" "可立即使用"
|
||||
assert_contains_file "$HTML_FILE" "需开通"
|
||||
assert_contains_file "$HTML_FILE" "暂不推荐"
|
||||
assert_contains_file "$HTML_FILE" "gpt-5.4"
|
||||
assert_contains_file "$HTML_FILE" "MiniMax-M2.7-highspeed"
|
||||
assert_contains_file "$HTML_FILE" "deepseek-chat"
|
||||
|
||||
assert_contains_file "$NGINX_FILE" "location = /portal"
|
||||
assert_contains_file "$NGINX_FILE" "location = /kimi-portal"
|
||||
assert_contains_file "$NGINX_FILE" "location /portal/"
|
||||
assert_contains_file "$NGINX_FILE" "location /portal-proxy/"
|
||||
assert_contains_file "$NGINX_FILE" "location /kimi-portal-proxy/"
|
||||
|
||||
assert_contains_file "$DEPLOY_SCRIPT" "portal url: https://sub.tksea.top/portal/"
|
||||
assert_contains_file "$DEPLOY_SCRIPT" "REMOTE_PORTAL_DIR"
|
||||
assert_contains_file "$DEPLOY_SCRIPT" "patch_tksea_portal_nginx.py"
|
||||
|
||||
echo "PASS: tksea portal assets look consistent"
|
||||
Reference in New Issue
Block a user