name: CI on: push: branches: - main pull_request: branches: - main jobs: build-and-test: runs-on: CDCD container: dockerreg.eazygame.cn/node:22-bookworm env: SKIP_ENV_VALIDATION: "1" NEXT_TELEMETRY_DISABLED: "1" steps: - name: Checkout uses: actions/checkout@v3 # 1. 增加 Cache 策略,显著加快 npm ci 速度 - name: Cache npm dependencies uses: actions/cache@v3 id: npm-cache with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Configure npm proxy run: | # 自动获取容器的默认网关 IP(即宿主机 IP) # ip route show default | awk '{print $3}' # 或者如果没有 ip 命令,尝试解析 host.docker.internal (如果 runner 支持) # 这里假设容器内有 iproute2 工具 GATEWAY_IP=$(ip route show | grep default | awk '{print $3}') echo "Detected Docker Gateway: $GATEWAY_IP" if [ -z "$GATEWAY_IP" ]; then echo "Warning: Could not detect gateway IP, falling back to 172.17.0.1" GATEWAY_IP="172.17.0.1" fi PROXY_URL="http://$GATEWAY_IP:7890" echo "Using Proxy: $PROXY_URL" # 设置 npm 代理 npm config set proxy "$PROXY_URL" npm config set https-proxy "$PROXY_URL" # 设置环境变量供后续步骤使用 (例如 cypress, next build 等) echo "http_proxy=$PROXY_URL" >> $GITHUB_ENV echo "https_proxy=$PROXY_URL" >> $GITHUB_ENV echo "HTTP_PROXY=$PROXY_URL" >> $GITHUB_ENV echo "HTTPS_PROXY=$PROXY_URL" >> $GITHUB_ENV - name: Show proxy status run: | if [ -n "$HTTP_PROXY" ] || [ -n "$http_proxy" ] || [ -n "$HTTPS_PROXY" ] || [ -n "$https_proxy" ]; then echo "proxy=on"; else echo "proxy=off"; fi - name: Install dependencies run: npm ci - name: Dump npm logs if: failure() run: | ls -la /root/.npm/_logs || true for f in /root/.npm/_logs/*-debug-*.log; do echo "===== $f =====" cat "$f" || true done - name: Lint run: npm run lint - name: Typecheck run: npm run typecheck # 2. 增加 Next.js 构建缓存 - name: Cache Next.js build uses: actions/cache@v3 with: path: | ~/.npm ${{ github.workspace }}/.next/cache # Generate a new cache whenever packages or source files change. key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/*.js', '**/*.jsx', '**/*.ts', '**/*.tsx') }} restore-keys: | ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- - name: Build run: npm run build # - name: 🔍 Debug - List Build Files # run: | # echo "=======================" # echo "1. Root directory files:" # ls -la # # echo "=======================" # echo "2. Checking .next directory:" # if [ -d ".next" ]; then # ls -la .next # else # echo "❌ Error: .next folder does not exist!" # fi # echo "=======================" # echo "3. Deep check of .next (excluding node_modules):" # # 查找 .next 目录下 4 层深度的文件,但排除 node_modules 避免日志太长 # find .next -maxdepth 4 -not -path '*/node_modules*' - name: Prepare standalone build run: | mkdir -p .next/standalone/public mkdir -p .next/standalone/.next/static cp -r public/* .next/standalone/public/ cp -r .next/static/* .next/standalone/.next/static/ cp Dockerfile .next/standalone/Dockerfile # - name: 🔍 Debug - List Build Files # run: | # echo "=======================" # ls -la .next/standalone - name: Upload production build artifact uses: actions/upload-artifact@v3 with: name: next-build path: .next/standalone include-hidden-files: true deploy: needs: build-and-test runs-on: CDCD container: image: dockerreg.eazygame.cn/node-with-docker:22 steps: - name: 🌐 Setup Network (Dynamic) run: | # 1. 动态获取 Docker 网关 IP # 尝试多种方式获取网关 IP GATEWAY_IP="" # 尝试使用 ip route (如果可用) if command -v ip >/dev/null 2>&1; then GATEWAY_IP=$(ip route show | grep default | awk '{print $3}') fi # 如果 ip 命令不可用,尝试 hostname -I 推断 if [ -z "$GATEWAY_IP" ]; then CURRENT_IP=$(hostname -I 2>/dev/null | awk '{print $1}') if [ -n "$CURRENT_IP" ]; then GATEWAY_IP=$(echo "$CURRENT_IP" | sed 's/\.[0-9]*$/.1/') fi fi # 兜底 if [ -z "$GATEWAY_IP" ]; then echo "Warning: Could not detect gateway IP, using fallback 172.17.0.1" GATEWAY_IP="172.17.0.1" fi echo "Detected Docker Gateway: $GATEWAY_IP" # 2. 配置 Host 解析 (解决 gittea.eazygame.cn 无法访问的问题) # 注意:需要容器内有 root 权限 if [ "$(id -u)" -eq 0 ]; then echo "$GATEWAY_IP gittea.eazygame.cn" >> /etc/hosts cat /etc/hosts else echo "Warning: Not root, cannot modify /etc/hosts" fi # 3. 设置 NO_PROXY (非常重要!防止请求走代理导致 Timeout) # 包含 localhost, 127.0.0.1, 网关IP, 以及 Gitea 域名 NO_PROXY_VAL="localhost,127.0.0.1,$GATEWAY_IP,gittea.eazygame.cn,.eazygame.cn,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12" echo "NO_PROXY=$NO_PROXY_VAL" >> $GITHUB_ENV echo "no_proxy=$NO_PROXY_VAL" >> $GITHUB_ENV - name: Download artifacts uses: actions/download-artifact@v3 with: name: next-build - name: Deploy to Docker run: | # 1. 使用 --no-cache 防止使用旧的构建层,确保部署的是最新代码 # 2. 使用 --pull 确保基础镜像是最新的 docker build --no-cache --pull -t nextjs-app . # 3. 优雅停止:先尝试 stop,如果失败则无需处理 (|| true) docker stop nextjs-app || true docker rm nextjs-app || true # 4. 运行容器: # --init: 解决 Node.js PID 1 僵尸进程问题 # --restart unless-stopped: 自动重启策略 docker run -d \ --init \ -p 8015:3000 \ --restart unless-stopped \ --name nextjs-app \ --network 1panel-network \ -e NODE_ENV=production \ -e DATABASE_URL=${{ secrets.DATABASE_URL }} \ -e NEXTAUTH_SECRET=${{ secrets.NEXTAUTH_SECRET }} \ -e NEXTAUTH_URL=${{ secrets.NEXTAUTH_URL }} \ -e NEXT_TELEMETRY_DISABLED=1 \ nextjs-app