Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

151 linhas
3.4 KiB

  1. #!/usr/bin/env bash
  2. if [ -z "${BASH_VERSION:-}" ]; then
  3. exec bash "$0" "$@"
  4. fi
  5. set -Eeuo pipefail
  6. APP_NAME="${APP_NAME:-pc_nuxt}"
  7. BRANCH="${BRANCH:-}"
  8. NUXT_PUBLIC_API_BASE="${NUXT_PUBLIC_API_BASE:-https://api.aionline.cc}"
  9. NUXT_API_SERVER_BASE="${NUXT_API_SERVER_BASE:-$NUXT_PUBLIC_API_BASE}"
  10. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  11. export NUXT_PUBLIC_API_BASE
  12. export NUXT_API_SERVER_BASE
  13. cd "$SCRIPT_DIR"
  14. log() {
  15. printf '\n[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$*"
  16. }
  17. require_command() {
  18. if ! command -v "$1" >/dev/null 2>&1; then
  19. log "Missing command: $1"
  20. exit 1
  21. fi
  22. }
  23. validate_api_base() {
  24. node - "$NUXT_PUBLIC_API_BASE" <<'NODE'
  25. const value = process.argv[2]
  26. let url
  27. try {
  28. url = new URL(value)
  29. } catch {
  30. console.error(`[pc_nuxt] Invalid NUXT_PUBLIC_API_BASE: ${value || '(empty)'}`)
  31. process.exit(1)
  32. }
  33. const hostname = url.hostname.toLowerCase()
  34. const isPrivate = hostname === 'localhost'
  35. || hostname === '0.0.0.0'
  36. || /^127\./.test(hostname)
  37. || hostname === '[::1]'
  38. || hostname.endsWith('.local')
  39. || /^10\./.test(hostname)
  40. || /^192\.168\./.test(hostname)
  41. || /^169\.254\./.test(hostname)
  42. || /^172\.(1[6-9]|2\d|3[01])\./.test(hostname)
  43. if (!['http:', 'https:'].includes(url.protocol) || isPrivate) {
  44. console.error(`[pc_nuxt] Production API must be a public http(s) URL: ${value}`)
  45. process.exit(1)
  46. }
  47. NODE
  48. }
  49. validate_server_api_base() {
  50. node - "$NUXT_API_SERVER_BASE" <<'NODE'
  51. const value = process.argv[2]
  52. let url
  53. try {
  54. url = new URL(value)
  55. } catch {
  56. console.error(`[pc_nuxt] Invalid NUXT_API_SERVER_BASE: ${value || '(empty)'}`)
  57. process.exit(1)
  58. }
  59. if (!['http:', 'https:'].includes(url.protocol)) {
  60. console.error(`[pc_nuxt] NUXT_API_SERVER_BASE must be http(s): ${value}`)
  61. process.exit(1)
  62. }
  63. NODE
  64. }
  65. validate_tls_security() {
  66. if [ "${NODE_TLS_REJECT_UNAUTHORIZED:-}" = "0" ]; then
  67. log "Refusing deployment: NODE_TLS_REJECT_UNAUTHORIZED=0 disables TLS certificate verification."
  68. exit 1
  69. fi
  70. }
  71. resolve_branch() {
  72. if [ -z "$BRANCH" ]; then
  73. BRANCH="$(git rev-parse --abbrev-ref HEAD)"
  74. fi
  75. if [ "$BRANCH" = "HEAD" ]; then
  76. log "Cannot detect git branch. Please run with BRANCH=main ./restart.sh"
  77. exit 1
  78. fi
  79. }
  80. sync_latest_code() {
  81. log "Force sync code from origin/$BRANCH"
  82. git fetch origin "$BRANCH"
  83. if [ -n "$(git status --porcelain)" ]; then
  84. log "Discard local working tree changes before deploy"
  85. git status --short
  86. fi
  87. git reset --hard "origin/$BRANCH"
  88. git clean -fd
  89. }
  90. install_dependencies() {
  91. log "Install dependencies"
  92. pnpm install --frozen-lockfile
  93. }
  94. build_app() {
  95. log "Build Nuxt app"
  96. pnpm run build
  97. if [ ! -f ".output/server/index.mjs" ]; then
  98. log "Build output missing: .output/server/index.mjs"
  99. exit 1
  100. fi
  101. }
  102. restart_app() {
  103. log "Reload app with pm2 ecosystem config"
  104. mkdir -p logs
  105. APP_NAME="$APP_NAME" pm2 startOrReload ecosystem.config.cjs --env production --update-env
  106. pm2 save >/dev/null 2>&1 || true
  107. }
  108. main() {
  109. require_command git
  110. require_command node
  111. require_command pnpm
  112. require_command pm2
  113. validate_tls_security
  114. validate_api_base
  115. validate_server_api_base
  116. resolve_branch
  117. log "Deploy start: $APP_NAME"
  118. log "Node: $(node -v 2>/dev/null || echo 'unknown')"
  119. log "pnpm: $(pnpm -v)"
  120. log "pm2: $(pm2 -v)"
  121. log "API: $NUXT_PUBLIC_API_BASE"
  122. log "Server API: $NUXT_API_SERVER_BASE"
  123. sync_latest_code
  124. install_dependencies
  125. build_app
  126. restart_app
  127. log "Deploy done: $APP_NAME"
  128. }
  129. main "$@"