Files
karuo-ai/01_卡资(金)/金仓_存储备份/群晖NAS管理/参考资料/GitHub与Gitea同步_脚本与钩子规则.md
2026-07-19 00:21:46 +08:00

5.5 KiB
Raw Blame History

GitHub 与 Gitea 同步:脚本与钩子规则

目的:说清定时脚本与 Web 钩子的关系、是否冲突、最佳用法与固定规则。
维护:金仓


一、脚本 vs 钩子

方式 触发 方向 说明
定时脚本cron 每 30 分钟 GitHub → Gitea NAS 上执行 sync_github_to_gitea.sh,拉取 GitHub 全仓/指定仓并推送到存客宝 Gitea。
GitHub Web 钩子 GitHub 有 push 时 GitHub → Gitea GitHub 向 NAS 上的接收端发 POST接收端执行同步脚本实时
Gitea Web 钩子 Gitea 有 push 时 Gitea → 外部 Gitea 向指定 URL 发 POST通知用若要做 Gitea→GitHub 反向同步,需接收端再推送到 GitHub。

二、是否冲突?结论:不冲突,用锁兜底

  • 脚本与 GitHub 钩子做的是同一件事GitHub → Gitea只是触发不同定时 vs 事件)。可能同时发生(例如刚 push 完又赶上 cron不会逻辑冲突,但并发跑同一仓库可能造成重复拉取/推送。
  • 处理方式:同步脚本已加全局锁(同一时间只允许一个同步进程)。钩子或 cron 触发时,若脚本已在跑,后到的会等待锁或超时跳过,不会两个进程同时写同一仓库
  • Gitea 钩子若只做「GitHub → Gitea」单向不需要在 Gitea 配置钩子。若要做「Gitea → GitHub」反向Gitea 钩子只负责「通知接收端」,由接收端去 push 到 GitHub与脚本GitHub→Gitea方向相反不冲突

三、最佳方案(推荐)

  1. 主向GitHub → Gitea实时 + 兜底)

    • 实时:在 GitHub 仓库或组织里配置 Web 钩子Payload URL 指向 NAS 上的 webhook 接收端(需 NAS 有可从外网访问的地址,如 frp触发时只同步该仓库或按约定同步全仓
    • 兜底:保留 cron 每 30 分钟 全量同步,防止钩子漏触发或网络问题。
    • 规则:脚本带锁,钩子与 cron 都只调同一脚本,不会并发冲突。
  2. Gitea 钩子(按需)

    • 若只需「GitHub 为源、Gitea 为镜像」,不必在 Gitea 配置钩子
    • 若需「在 Gitea 的修改也推到 GitHub」
      • 在 Gitea 用户设置 → Web 钩子 添加「添加 Web 钩子」;
      • URL 填接收端地址,触发事件选「推送」等;
      • 接收端收到后,根据 payload 找到对应仓库并执行 git push 到 GitHub需在接收端配置 GitHub 权限)。
  3. 约定规则(固定)

    • 源真相:默认以 GitHub 为准Gitea 为镜像反向Gitea→GitHub仅对明确需要的仓库开启。
    • 只用一个同步脚本所有同步cron 或钩子触发)都调用 sync_github_to_gitea.sh(可带 --repo xxx),脚本内用同一把锁。
    • 不在 Gitea 侧做「镜像仓库」与脚本重复:若用 Gitea 的「从 URL 迁移/镜像」功能,就不要再对同一仓库用本脚本,二选一,避免双写。

四、Gitea 上钩子设置(界面说明)

  • 打开 open.quwanzhi.com:3000 → 右上角头像 → 设置 → 左侧 Web 钩子
  • 「添加 Web 钩子」:选类型(如 Gitea 或 HTTPURL 填你的接收端地址(例如 http://你的NAS或frp地址:端口/webhook)。
  • 触发事件:至少勾选「推送」;若需合并请求等再勾选对应项。
  • 说明:此处钩子为由 Gitea 发出的通知用于「Gitea → 外部」(如 Gitea→GitHub 反向同步);GitHub → Gitea 的实时同步是在 GitHub 侧 配置钩子指向 NAS 接收端,而不是在 Gitea 配置。

五、脚本锁规则(实现层面)

  • 同步脚本使用全局锁目录 $WORK_DIR.lock(如 /tmp/github_gitea_sync.lock),通过 mkdir 原子性获取锁。
  • 获取不到锁时,每 5 秒重试,超过 SYNC_LOCK_WAIT 秒(默认 300则退出不执行本次同步。
  • 脚本正常或异常退出时用 trap EXIT 释放锁。
  • 结论cron 与 webhook 可同时配置,两者都触发同一脚本,由锁保证同一时刻只跑一个同步,无冲突。

六、Web 钩子接收端(实时触发同步)

  • 位置scripts/webhook_receiver.pyPython 3仅标准库
  • 在 NAS 上运行
    cd /volume1/docker/gitea && nohup python3 webhook_receiver.py >> webhook.log 2>&1 &
    默认监听 9999 端口,环境变量 WEBHOOK_PORT 可改。
  • 行为:对任意路径的 POST(如 http://NAS或frp地址:9999/sync)执行同步;若 body 为 JSON 且含 repository.nameGitHub/Gitea 格式),则只同步该仓库,否则全量同步。GET //sync/health 返回 200 用于探活。
  • GitHub 配置:仓库或组织 → Settings → Webhooks → Add webhook → Payload URL 填 http://你的NAS公网或frp地址:9999/syncContent type 选 application/json,事件选 “Just the push event” 即可。
  • Gitea 配置(仅当需要 Gitea→GitHub 反向时):用户设置 → Web 钩子 → 添加 Web 钩子 → URL 填上述地址,触发选「推送」。

七、相关文件

文件 说明
scripts/sync_github_to_gitea.sh 带锁的同步脚本GitHub → Gitea
scripts/webhook_receiver.py NAS 上 Web 钩子接收端(被 GitHub/Gitea 调用)
references/GitHub全仓同步到CKB_NAS_Gitea_方案与双向说明.md 全量同步与部署说明

版本v1.0