run_update_and_commit.sh 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #!/usr/bin/env bash
  2. set -euo pipefail
  3. APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
  4. CONFIG_PATH="${1:-${APP_DIR}/config.json}"
  5. DOMAIN_FILE="${APP_DIR}/runtime/current_domain.txt"
  6. before=""
  7. if [[ -f "$DOMAIN_FILE" ]]; then
  8. before="$(tr -d '\r\n' < "$DOMAIN_FILE")"
  9. fi
  10. /usr/bin/python3 "${APP_DIR}/scripts/domain_updater.py" --config "$CONFIG_PATH"
  11. after=""
  12. if [[ -f "$DOMAIN_FILE" ]]; then
  13. after="$(tr -d '\r\n' < "$DOMAIN_FILE")"
  14. fi
  15. if [[ -z "$after" ]]; then
  16. echo "[vmess-domain-rotator] empty selected domain, skip git commit"
  17. exit 0
  18. fi
  19. if [[ "$before" == "$after" ]]; then
  20. echo "[vmess-domain-rotator] domain unchanged (${after}), skip git commit"
  21. exit 0
  22. fi
  23. if ! command -v git >/dev/null 2>&1; then
  24. echo "[vmess-domain-rotator] git not found, skip git commit"
  25. exit 0
  26. fi
  27. if ! git -C "$APP_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
  28. echo "[vmess-domain-rotator] not a git repo, skip git commit"
  29. exit 0
  30. fi
  31. commit_name="${GIT_COMMIT_NAME:-vmess-domain-rotator}"
  32. commit_email="${GIT_COMMIT_EMAIL:-vmess-domain-rotator@localhost}"
  33. runtime_branch="${GIT_RUNTIME_BRANCH:-runtime-state}"
  34. ts="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
  35. push_remote="${GIT_PUSH_REMOTE:-origin}"
  36. if ! git -C "$APP_DIR" remote get-url "$push_remote" >/dev/null 2>&1; then
  37. push_remote=""
  38. while IFS= read -r r; do
  39. push_remote="$r"
  40. break
  41. done < <(git -C "$APP_DIR" remote)
  42. fi
  43. work_dir=""
  44. cleanup_worktree="0"
  45. current_branch="$(git -C "$APP_DIR" symbolic-ref --quiet --short HEAD 2>/dev/null || true)"
  46. if [[ "$current_branch" == "$runtime_branch" ]]; then
  47. work_dir="$APP_DIR"
  48. else
  49. work_dir="$(mktemp -d "${TMPDIR:-/tmp}/vmess-runtime-state.XXXXXX")"
  50. cleanup_worktree="1"
  51. if git -C "$APP_DIR" show-ref --verify --quiet "refs/heads/${runtime_branch}"; then
  52. git -C "$APP_DIR" worktree add --force "$work_dir" "$runtime_branch"
  53. else
  54. if [[ -n "$push_remote" ]] && git -C "$APP_DIR" ls-remote --exit-code --heads "$push_remote" "$runtime_branch" >/dev/null 2>&1; then
  55. git -C "$APP_DIR" fetch "$push_remote" "$runtime_branch:$runtime_branch"
  56. git -C "$APP_DIR" worktree add --force "$work_dir" "$runtime_branch"
  57. else
  58. git -C "$APP_DIR" worktree add --force --detach "$work_dir"
  59. git -C "$work_dir" checkout --orphan "$runtime_branch"
  60. git -C "$work_dir" rm -rf . >/dev/null 2>&1 || true
  61. echo "[vmess-domain-rotator] initialized branch ${runtime_branch}"
  62. fi
  63. fi
  64. fi
  65. if [[ "$cleanup_worktree" == "1" ]]; then
  66. cleanup() {
  67. git -C "$APP_DIR" worktree remove --force "$work_dir" >/dev/null 2>&1 || rm -rf "$work_dir"
  68. }
  69. trap cleanup EXIT
  70. fi
  71. mkdir -p "$work_dir/runtime"
  72. for file in current_domain.txt current_domain.json state.json substore_vars.json; do
  73. src="$APP_DIR/runtime/$file"
  74. dst="$work_dir/runtime/$file"
  75. if [[ -f "$src" ]]; then
  76. cp "$src" "$dst"
  77. else
  78. rm -f "$dst"
  79. fi
  80. done
  81. git -C "$work_dir" add -A runtime/current_domain.txt runtime/current_domain.json runtime/state.json runtime/substore_vars.json || true
  82. if git -C "$work_dir" diff --cached --quiet; then
  83. echo "[vmess-domain-rotator] no staged changes for ${runtime_branch}, skip git commit"
  84. exit 0
  85. fi
  86. git -C "$work_dir" \
  87. -c user.name="$commit_name" \
  88. -c user.email="$commit_email" \
  89. commit -m "chore: rotate preferred domain to ${after} (${ts})"
  90. if [[ -z "$push_remote" ]]; then
  91. echo "[vmess-domain-rotator] no remote found, skip git push"
  92. else
  93. if git -C "$work_dir" rev-parse --abbrev-ref --symbolic-full-name "@{u}" >/dev/null 2>&1; then
  94. if git -C "$work_dir" push "$push_remote" "$runtime_branch:$runtime_branch"; then
  95. echo "[vmess-domain-rotator] pushed to ${push_remote}/${runtime_branch}"
  96. else
  97. echo "[vmess-domain-rotator] git push failed"
  98. fi
  99. else
  100. if git -C "$work_dir" push -u "$push_remote" "$runtime_branch:$runtime_branch"; then
  101. echo "[vmess-domain-rotator] pushed to ${push_remote}/${runtime_branch} (set upstream)"
  102. else
  103. echo "[vmess-domain-rotator] git push failed"
  104. fi
  105. fi
  106. fi
  107. echo "[vmess-domain-rotator] committed domain change on ${runtime_branch}: ${before} -> ${after}"