name: build-and-push-harbor

on:
  push:
    branches:
      - main
      - master
      - dev
      - "feature/**"
  workflow_dispatch:

jobs:
  docker-build-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: http://103.236.53.208:3000/actions/checkout@v4

      - name: Set image tags
        id: vars
        run: |
          echo "short_sha=${GITHUB_SHA::7}" >> "$GITHUB_OUTPUT"
          echo "date_tag=$(date +%Y%m%d%H%M%S)" >> "$GITHUB_OUTPUT"

      # 调试步骤：检查 Secret 是否正确读取 (只会输出字符长度，不会泄露密码)
      - name: Debug Secrets
        run: |
          echo "Registry: ${{ secrets.HARBOR_REGISTRY }}"
          echo "User length: ${#HARBOR_USERNAME}"
          echo "Pass length: ${#HARBOR_PASSWORD}"
        env:
          HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }}
          HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }}

      - name: Login Harbor
        env:
          HARBOR_REGISTRY: ${{ secrets.HARBOR_REGISTRY }}
          HARBOR_USERNAME: ${{ secrets.HARBOR_USERNAME }}
          HARBOR_PASSWORD: ${{ secrets.HARBOR_PASSWORD }}
        run: |
          # 尝试登录，如果失败会打印详细信息
          echo "$HARBOR_PASSWORD" | docker login "$HARBOR_REGISTRY" -u "$HARBOR_USERNAME" --password-stdin

      - name: Build and Push Monorepo Services
        env:
          HARBOR_REGISTRY: ${{ secrets.HARBOR_REGISTRY }}
          HARBOR_PROJECT: ${{ secrets.HARBOR_PROJECT }}
          SHORT_SHA: ${{ steps.vars.outputs.short_sha }}
          DATE_TAG: ${{ steps.vars.outputs.date_tag }}
        shell: bash
        run: |
          set -euo pipefail

          # 1. 定义要遍历的微服务根目录 (根据你的项目结构)
          # 你的结构是 app/<service>/<type>
          # 我们只关心 api, rpc, mq 这三种类型

          echo "🔍 开始扫描 Go-Zero 微服务..."

          # 找到 app 下所有的 api/rpc/mq 目录
          find app -mindepth 2 -maxdepth 2 -type d \( -name "api" -o -name "rpc" -o -name "mq" \) | sort | while read -r service_dir; do
            
            # service_dir 举例: app/community/api
            service_type=$(basename "$service_dir")      # api
            parent_dir=$(dirname "$service_dir")         # app/community
            service_name=$(basename "$parent_dir")       # community
            
            # 2. 智能查找入口文件 (main.go 或 service_name.go)
            # 在当前目录下查找含有 "package main" 的 .go 文件
            entry_file=$(grep -l "package main" "$service_dir"/*.go | head -n 1 || true)
            
            if [[ -z "$entry_file" ]]; then
              echo "⚠️  跳过 $service_dir: 未找到 package main 入口文件"
              continue
            fi
            
            # 3. 智能查找配置文件 (etc/*.yaml)
            config_file=$(ls "$service_dir/etc/"*.yaml 2>/dev/null | head -n 1 || true)
            if [[ -z "$config_file" ]]; then
               echo "⚠️  警告 $service_name-$service_type: 未找到 etc/*.yaml 配置文件，容器启动可能失败"
               config_name="config.yaml" # fallback
            else
               config_name=$(basename "$config_file")
            fi

            # 镜像名称: community-api, user-rpc 等
            image_name="${service_name}-${service_type}"
            image_ref="$HARBOR_REGISTRY/$HARBOR_PROJECT/$image_name"
            
            echo "----------------------------------------------------"
            echo "🚀 构建目标: $image_name"
            echo "📂 入口文件: $entry_file"
            echo "📄 配置文件: $config_name"
            echo "----------------------------------------------------"

            # 4. 动态生成 Dockerfile (针对 Monorepo 优化)
            # 关键点：COPY . . 把整个根目录拷进去，因为 Go-Zero 项目通常依赖 ../../common
            cat <<EOF > Dockerfile.tmp
          FROM golang:alpine AS builder

          # 优化：使用阿里云 Alpine 源
          RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories && \
              apk update --no-cache && apk add --no-cache tzdata

          WORKDIR /build

          # 优化：利用层缓存，先下载依赖
          ENV GOPROXY=https://goproxy.cn,direct
          COPY go.mod go.sum ./
          RUN go mod download

          # 拷贝所有源码 (解决 common 依赖问题)
          COPY . .

          # 编译
          RUN go build -ldflags="-s -w" -o /app/main $entry_file

          # 运行时镜像
          FROM scratch

          COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
          COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
          ENV TZ=Asia/Shanghai

          WORKDIR /app
          COPY --from=builder /app/main /app/main

          # 拷贝 etc 配置
          COPY $service_dir/etc /app/etc

          # 启动命令
          CMD ["./main", "-f", "etc/$config_name"]
          EOF

            # 5. 执行 Docker Build
            docker build -f Dockerfile.tmp -t "$image_ref:$SHORT_SHA" .
            
            # 打其他 Tag
            docker tag "$image_ref:$SHORT_SHA" "$image_ref:$DATE_TAG"
            docker tag "$image_ref:$SHORT_SHA" "$image_ref:latest"

            # 6. 推送
            echo "📤 推送镜像..."
            docker push "$image_ref:$SHORT_SHA"
            docker push "$image_ref:$DATE_TAG"
            docker push "$image_ref:latest"
            
            echo "✅ $image_name 完成"
            rm -f Dockerfile.tmp
          done
