Skip to content

Fork Sync

Fork Sync #42

Workflow file for this run

name: Fork Sync
on:
schedule:
- cron: "0 */3 * * *" # 每 3 小时执行一次
workflow_dispatch:
permissions:
contents: write
actions: write
jobs:
sync_with_upstream:
name: Sync with Upstream
runs-on: ubuntu-latest
if: ${{ github.event.repository.fork }}
steps:
- name: Checkout target repo
uses: actions/checkout@v4
with:
token: ${{ secrets.SYNC_PAT != '' && secrets.SYNC_PAT || secrets.GITHUB_TOKEN }}
fetch-depth: 0
ref: main
- name: Configure Git & remotes
env:
SYNC_PAT: ${{ secrets.SYNC_PAT }}
run: |
set -e
git config user.name "GitHub Actions Bot"
git config user.email "github-actions[bot]@users.noreply.github.com"
# 确保在 main 分支
git checkout main || git checkout -b main
# upstream remote:存在则改 URL,不存在则新增
if git remote get-url upstream >/dev/null 2>&1; then
git remote set-url upstream https://github.com/imzyb/MiSub.git
else
git remote add upstream https://github.com/imzyb/MiSub.git
fi
# 若配置了带 workflows 权限的 PAT,则强制 origin 使用该令牌推送
if [ -n "${SYNC_PAT:-}" ]; then
git remote set-url origin "https://x-access-token:${SYNC_PAT}@github.com/${{ github.repository }}.git"
echo "✅ 检测到 SYNC_PAT,将使用 PAT 推送(支持工作流文件同步)"
else
echo "⚠️ 未配置 SYNC_PAT,将使用默认 GITHUB_TOKEN。注意:由于 GitHub 限制,此模式下无法自动同步 .github/workflows 的变更。"
fi
git fetch --prune upstream
git fetch --all
- name: Merge from upstream and resolve conflicts (prefer upstream)
id: merge_attempt
run: |
# 记录合并前基线,后续用于必要时回滚 workflow 文件
BASE_REF=$(git rev-parse HEAD)
echo "BASE_REF=$BASE_REF" >> "$GITHUB_ENV"
# 尝试合并 upstream/main
if git merge upstream/main --no-ff --no-edit; then
echo "🎉 合并成功,无冲突"
else
echo "🚩 合并出现冲突,正在处理..."
# 如果存在冲突文件,统一用上游版本(theirs=upstream)
CONFLICT_FILES=$(git diff --name-only --diff-filter=U 2>/dev/null || true)
if [ -n "$CONFLICT_FILES" ]; then
echo "检测到冲突文件:将优先使用上游版本覆盖"
for file in $CONFLICT_FILES; do
echo " 使用上游版本: $file"
git checkout --theirs "$file"
git add "$file"
done
fi
# 注意:如果 merge 失败且没有 U 类型冲突(例如只有 D 类型),则继续
if [ -f .git/MERGE_HEAD ]; then
git commit -m "Auto-sync with upstream (Conflict Resolved) $(TZ=Asia/Shanghai date +'%Y-%m-%d %H:%M:%S')"
else
echo "无法自动解决的异常合并状态,中断同步以防止历史损坏"
git merge --abort || true
exit 1
fi
fi
- name: Commit and Push (if changed)
env:
SYNC_PAT: ${{ secrets.SYNC_PAT }}
run: |
set -e
# 未配置 PAT 时,GITHUB_TOKEN 默认无法更新 workflow 文件,推送前回滚该目录
if [ -z "${SYNC_PAT:-}" ]; then
if [ -n "${BASE_REF:-}" ] && git ls-tree -d --name-only "$BASE_REF" .github/workflows >/dev/null 2>&1; then
git restore --source "$BASE_REF" --staged --worktree .github/workflows || true
echo "⚠️ 未配置 SYNC_PAT:已回滚 .github/workflows 变更以避免推送权限错误。"
fi
fi
# 检查是否有正在进行的合并(冲突解决后需提交)
if [ -f .git/MERGE_HEAD ]; then
git commit -m "Auto-sync with upstream (Final Polish) $(TZ=Asia/Shanghai date +'%Y-%m-%d %H:%M:%S')" || true
fi
# 检查本地是否领先于远程(即是否有新提交需要推送)
# 使用 git status 或 rev-parse 检查
if [ -n "$(git status --porcelain=v1)" ] || [ "$(git rev-parse HEAD)" != "$(git rev-parse origin/main)" ]; then
echo "🚀 正在推送变更到仓库..."
git push origin main
else
echo "✨ 本地已是最新版本,无需推送。"
fi