Files
website/.gitea/workflows/mirror-to-gitee.yml
T
技小云 aecd2ad658
mirror-to-gitee / mirror (push) Successful in 3s
fix: 可见性校正补 name 字段(Gitee 端点要求)
2026-11-04 11:18:44 +08:00

121 lines
6.0 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: 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
echo "❌ 取不到仓库名(GITHUB_REPOSITORY=${GITHUB_REPOSITORY:-<空>}),中止"
exit 1
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,\"private\":false,\"description\":\"雪羊科技开源项目门户:iotLCM / 秀杰 DTU / XiuAdmin 等开源项目索引\"}" \
-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}@git.5iot.com/iotlcm-public/${REPO_NAME}.git" "$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 限流时容易发生)
#
# 每条赋值都带 `|| true`:命令替换里任何一段返回非零(新建仓没有 tag 时
# `grep -v` 会返回 1)在 set -e 下会直接中断脚本,
# 导致「推送其实成功了,但 job 报红」这种假失败。
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 2>/dev/null | awk '{print $1}' || true)
LOCAL_TAGS=$(git for-each-ref --format='%(refname:short)' refs/tags 2>/dev/null | sort | tr '\n' ' ' || true)
REMOTE_TAGS=$(git ls-remote --tags "https://${DST_USER}:${DST_TOKEN}@${DST}" 2>/dev/null \
| awk '{print $2}' | sed 's#refs/tags/##' | { grep -v '\^{}$' || true; } | sort | tr '\n' ' ' || true)
echo "本地 main: ${LOCAL_MAIN:-<无>}"
echo "远端 main: ${REMOTE_MAIN:-<无>}"
echo "本地 tag: ${LOCAL_TAGS:-<无>}"
echo "远端 tag: ${REMOTE_TAGS:-<无>}"
if [ -n "$LOCAL_MAIN" ] && [ -n "$REMOTE_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 均已对齐"
# 门户是公开项目门户,目标仓必须是公开的,否则不会出现在企业仓列表页里。
# 仓库可见性的更新端点是 PATCH /api/v5/repos/{owner}/{repo};
# /enterprises/{owner}/repos/{repo} 不是有效端点(会 404)。
# 该端点要求带 name,否则返回 400 {"messages":["name is missing"]}。
# 企业仓可见性有三档(公开 / 企业内 / 私有),公开需要 private 与 internal 都为 false。
echo "----- 校正目标仓可见性为公开"
curl -sS -X PATCH \
"https://gitee.com/api/v5/repos/${DST_OWNER}/${REPO_NAME}?access_token=${DST_TOKEN}" \
-H 'Content-Type: application/json' \
-d "{\"name\":\"${REPO_NAME}\",\"private\":false,\"internal\":false,\"description\":\"雪羊科技开源项目门户:iotLCM / 秀杰 DTU / XiuAdmin 等开源项目索引\"}" \
-o /tmp/repo-patch.json -w '改可见性 HTTP %{http_code}\n' || true
head -c 300 /tmp/repo-patch.json 2>/dev/null; echo
exit 0
fi
wait_s=$((attempt * 30))
echo "推送失败,${wait_s}s 后重试"
sleep "$wait_s"
done
echo "❌ 连续 5 次推送失败,请检查 Gitee 状态或令牌"
exit 1