fd42b5976e
README - 标题去掉「(开源版)」:对使用者就是 iotLCM - 新增「文档」表:使用手册(Web 端 / 小程序端)、部署手册、OpenAPI 合同、 共享 Token 接口,全部指向仓内 docs/ 路径;并给出部署后的文档站地址 - 补功能概览、服务构成(带镜像 tag)、从源码构建、版本与镜像、许可 去措辞 - Gitee 建仓描述同步去掉「(开源版)」 单端口入口(新增,对外默认 5051) - deploy/config/gateway/nginx.conf:/ → 管理端、/docs/ → 文档站、 /openapi/ 与 /route/open/ → openapi - compose 增加 gateway 服务(profile with-gateway),端口由 GATEWAY_PORT 控制 实测:/ 200、/docs/ 200(含静态资源)、/api/agent/dept/list 200、 /api/system/auth/login 返回后端真实 JSON - nginx profile 的 80 端口改为可配 NGINX_HTTP_PORT(文档早有提及但 compose 写死) - 部署手册概览页修正过期内容(schema 单文件、服务清单补全)、optional 增单端口入口段
102 lines
4.2 KiB
YAML
102 lines
4.2 KiB
YAML
name: mirror-to-gitee
|
||
|
||
# 把本仓镜像到 Gitee 企业仓 <GITEE_OWNER>/<同名仓库>。
|
||
# 触发:main 分支推送、v* tag 推送、手动;另有每日兜底重试。
|
||
on:
|
||
push:
|
||
branches:
|
||
- main
|
||
tags:
|
||
- 'v*'
|
||
schedule:
|
||
# Gitea Actions 的 cron 用 UTC:18:30 UTC = 次日 02:30 北京时间
|
||
- cron: '30 18 * * *'
|
||
workflow_dispatch:
|
||
|
||
concurrency:
|
||
group: mirror-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
jobs:
|
||
mirror:
|
||
runs-on: host
|
||
steps:
|
||
- name: 同步到 Gitee
|
||
env:
|
||
SRC_TOKEN: ${{ secrets.SRC_GIT_TOKEN }}
|
||
DST_TOKEN: ${{ secrets.GITEE_TOKEN }}
|
||
DST_OWNER: ${{ secrets.GITEE_OWNER }}
|
||
DST_USER: ${{ secrets.GITEE_USER }}
|
||
run: |
|
||
set -u
|
||
|
||
# 仓库名取当前仓;取不到时回退到单仓名
|
||
REPO_NAME="${GITHUB_REPOSITORY#*/}"
|
||
if [ -z "${REPO_NAME:-}" ] || [ "$REPO_NAME" = "${GITHUB_REPOSITORY:-}" ]; then
|
||
REPO_NAME="iotlcm"
|
||
fi
|
||
|
||
SRC="git.5iot.com/iotlcm-public/${REPO_NAME}.git"
|
||
DST="gitee.com/${DST_OWNER}/${REPO_NAME}.git"
|
||
echo "源:$SRC"
|
||
echo "目标:$DST"
|
||
|
||
# Gitee 不支持 push 建仓,目标仓不存在时先按企业 API 创建(已存在会报 400,忽略)
|
||
if ! git ls-remote "https://${DST_USER}:${DST_TOKEN}@${DST}" >/dev/null 2>&1; then
|
||
echo "目标仓不存在,尝试创建 ${DST_OWNER}/${REPO_NAME}"
|
||
curl -sS -X POST \
|
||
"https://gitee.com/api/v5/enterprises/${DST_OWNER}/repos?access_token=${DST_TOKEN}" \
|
||
-H 'Content-Type: application/json' \
|
||
-d "{\"name\":\"${REPO_NAME}\",\"auto_init\":false,\"description\":\"iotLCM 物联网卡全生命周期管理平台\"}" \
|
||
-o /tmp/repo-create.json -w '建仓 HTTP %{http_code}\n' || true
|
||
head -c 300 /tmp/repo-create.json 2>/dev/null; echo
|
||
else
|
||
echo "目标仓已存在"
|
||
fi
|
||
|
||
WORK=$(mktemp -d)
|
||
trap 'rm -rf "$WORK"' EXIT
|
||
|
||
git clone --mirror "https://jenkins:${SRC_TOKEN}@${SRC%/}" "$WORK/repo.git"
|
||
cd "$WORK/repo.git"
|
||
echo "本地 ref:$(git for-each-ref --format='%(refname:short)' | tr '\n' ' ')"
|
||
|
||
# Gitee 在推送密集时会返回 429 Pending queue overflowed / 408 Authorization server timeout,
|
||
# 属服务端限流,退避重试即可。
|
||
attempt=0
|
||
while [ "$attempt" -lt 5 ]; do
|
||
attempt=$((attempt + 1))
|
||
echo "----- 推送尝试 $attempt/5"
|
||
if git push --mirror "https://${DST_USER}:${DST_TOKEN}@${DST}" 2>&1; then
|
||
echo "✅ 已同步到 Gitee"
|
||
|
||
# 推送后校验:远端 main 与 tag 集合必须与本地一致
|
||
# (避免“绿了但其实没推上去” —— Gitee 限流时容易发生)
|
||
LOCAL_MAIN=$(git rev-parse refs/heads/main 2>/dev/null || true)
|
||
REMOTE_MAIN=$(git ls-remote "https://${DST_USER}:${DST_TOKEN}@${DST}" refs/heads/main | awk '{print $1}')
|
||
LOCAL_TAGS=$(git for-each-ref --format='%(refname:short)' refs/tags | sort | tr '\n' ' ')
|
||
REMOTE_TAGS=$(git ls-remote --tags "https://${DST_USER}:${DST_TOKEN}@${DST}" \
|
||
| awk '{print $2}' | sed 's#refs/tags/##' | grep -v '\^{}$' | sort | tr '\n' ' ')
|
||
echo "本地 main: ${LOCAL_MAIN:-<无>}"
|
||
echo "远端 main: ${REMOTE_MAIN:-<无>}"
|
||
echo "本地 tag: ${LOCAL_TAGS:-<无>}"
|
||
echo "远端 tag: ${REMOTE_TAGS:-<无>}"
|
||
if [ -n "$LOCAL_MAIN" ] && [ "$LOCAL_MAIN" != "$REMOTE_MAIN" ]; then
|
||
echo "❌ 校验失败:远端 main 与本地不一致"
|
||
exit 1
|
||
fi
|
||
if [ "${LOCAL_TAGS% }" != "${REMOTE_TAGS% }" ]; then
|
||
echo "❌ 校验失败:远端 tag 与本地不一致"
|
||
exit 1
|
||
fi
|
||
echo "✅ 校验通过:Gitee 端 main 与 tag 均已对齐"
|
||
exit 0
|
||
fi
|
||
wait_s=$((attempt * 30))
|
||
echo "推送失败,${wait_s}s 后重试"
|
||
sleep "$wait_s"
|
||
done
|
||
|
||
echo "❌ 连续 5 次推送失败,请检查 Gitee 状态或令牌"
|
||
exit 1
|