Files
userbase/.gitea/workflows/ci.yml
T

125 lines
6.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: ci-userbase-service
# 后端标准化 CI:maven 构建 jar -> docker build -> 推 Nexus docker-hosted
# 触发:push 到 main(仅 service 或本文件变更)/ 手动 Run workflow
# 依赖仓库 Actions Secrets:NEXUS_USER / NEXUS_PASSWORD(ci-docker 账号,仅 docker-hosted 推送权)
on:
push:
branches: [main]
paths:
- 'service/**'
- '.gitea/workflows/ci.yml'
workflow_dispatch:
inputs:
tag:
description: 'image tag (default = short sha)'
required: false
default: 'auto'
deploy:
description: 'deploy to 160 after build (auto / skip)'
required: false
default: 'auto'
jobs:
build-and-push:
runs-on: ubuntu-latest
# docker:24 自带 docker CLI,复用宿主 docker daemon。
# 注意:act_runner v0.6.1 默认已把宿主 docker.sock 挂入每个 job 容器,
# 切勿在此再声明 volumes: docker.sock(会与默认挂载重复,报
# "Duplicate mount point" 导致容器创建失败、全部 step cancelled)。
container:
image: docker:24
steps:
# docker:24 基于 alpine,默认无 git;先装 git 再手动 clone 本仓库
- name: Install git (alpine)
run: apk add --no-cache git
# 内网 Gitea 无法访问 github.com 拉取 actions/checkout,改为直接 clone 本仓库
- name: Checkout (manual, internal Gitea)
run: |
git clone --depth 1 --branch main http://192.168.10.160:3000/${GITHUB_REPOSITORY}.git /tmp/src
cp -a /tmp/src/. .
rm -rf /tmp/src
- name: Compute image tag
id: meta
run: |
if [ "${{ inputs.tag }}" = "auto" ] || [ -z "${{ inputs.tag }}" ]; then
echo "tag=$(echo ${GITHUB_SHA} | cut -c1-7)" >> $GITHUB_OUTPUT
else
echo "tag=${{ inputs.tag }}" >> $GITHUB_OUTPUT
fi
- name: Build jar with Maven
run: |
# 注意:job 容器通过 docker.sock 调的是【宿主 docker daemon】,
# 因此 docker run -v <path> 里的路径会被宿主按【宿主路径】解析;
# 而 act 工作区是宿主上的 docker volume,容器内 $PWD 对宿主不可见,
# 直接 -v $PWD:/build 会绑成空目录导致找不到 pom.xml。
# 故改为:起 maven 容器 -> docker cp 源码入容器 -> exec 构建 -> cp 产物回工作区。
# nexus.yunhaixingtong.com 仅在用户本机 hosts 指向 160 的 nexus 容器,
# 160 上该域名不可解析,故在 maven 容器内用 --add-host 映射到宿主(Caddy:80),
# 由 Caddy 反代到 nexus:8081 的 maven-public(匿名可读,已验证 200)。
# 等真实域名就绪、公网可解析后,删除下面 --add-host 这一行即可。
docker run -d --name mavenbuild \
--add-host=nexus.yunhaixingtong.com:host-gateway \
-v /opt/docker/ubs-m2:/root/.m2 \
-w /build maven:3.6.3-jdk-8 sleep 3600
docker cp "${PWD}/." mavenbuild:/build/
# 强制清掉宿主 m2 中已缓存的 yh.platform 全部 SNAPSHOT(mavenbuild 的 /root/.m2
# 即宿主 /opt/docker/ubs-m2,通过 docker.sock 作用于宿主),确保本次重新拉取用户刚
# re-deploy 的最新 yh-auth(含 CasSsoAutoConfiguration),避免解析到旧的 SNAPSHOT 构建。
docker exec mavenbuild rm -rf /root/.m2/com/yunhai/platform
docker exec mavenbuild sh -c 'cd /build/service && mvn -U -B -DskipTests clean package'
mkdir -p "${PWD}/service/target"
docker cp mavenbuild:/build/service/target/userbase.jar "${PWD}/service/target/userbase.jar"
docker rm -f mavenbuild
- name: Login to Nexus docker registry
run: echo "${{ secrets.NEXUS_PASSWORD }}" | docker login nexus:8083 -u ${{ secrets.NEXUS_USER }} --password-stdin
- name: Build image
run: docker build -t nexus:8083/docker-hosted/userbase-service:${{ steps.meta.outputs.tag }} -f service/docker/Dockerfile service
- name: Push image
run: docker push nexus:8083/docker-hosted/userbase-service:${{ steps.meta.outputs.tag }}
- name: Report build
run: echo "pushed nexus:8083/docker-hosted/userbase-service:${{ steps.meta.outputs.tag }}"
# —— 部署阶段(仅在 push 或手动 dispatch deploy=auto 时执行)——
# 运行在 160 的 act_runner 上,复用宿主 docker daemon(docker.sock 由 act_runner 自动挂载),
# 因此 docker pull / run 直接作用于 160 宿主,等价于在 160 上执行部署。
- name: Deploy (pull + rollout with rollback)
if: github.event_name == 'push' || inputs.deploy == 'auto'
run: |
set +e
IMG=nexus:8083/docker-hosted/userbase-service:${{ steps.meta.outputs.tag }}
echo "deploying $IMG"
echo "${{ secrets.NEXUS_PASSWORD }}" | docker login nexus:8083 -u ${{ secrets.NEXUS_USER }} --password-stdin
docker pull "$IMG"
# 回滚锚:保留当前 userbase-service:latest(已知良好镜像),再额外打一个时间点标签
RB=userbase-service:rb-$(date +%s)
docker tag userbase-service:latest "$RB" 2>/dev/null || true
docker stop userbase-service 2>/dev/null; docker rm -f userbase-service 2>/dev/null
docker run -d --name userbase-service --restart unless-stopped --network infra-infra-net -p 8060:8060 \
-e NACOS_ADDR=nacos:8848 \
-e NACOS_NAMESPACE=6196f0de-a28d-4894-8f10-e2982b57c6bc \
"$IMG"
# 健康检查:Spring 起来后 /userbase/ 返回 404(根路径无映射控制器),000 表示未起来
OK=0
for i in $(seq 1 30); do
sleep 5
CODE=$(curl -s -o /dev/null -w '%{http_code}' http://localhost:8060/userbase/ 2>/dev/null || true)
if [ "$CODE" != "000" ]; then OK=1; break; fi
done
if [ "$OK" = "0" ]; then
echo "!! UNHEALTHY -> rollback to userbase-service:latest"
docker stop userbase-service 2>/dev/null; docker rm -f userbase-service 2>/dev/null
docker run -d --name userbase-service --restart unless-stopped --network infra-infra-net -p 8060:8060 userbase-service:latest
echo "rolled back"; exit 7
fi
echo "DEPLOY OK: $IMG"
docker tag "$IMG" userbase-service:latest
docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Image}}' | grep userbase || true