Files
BeacherZ 465a995012 fix(sync): 归一化引擎文件权限位,消除「内容没变却显示已改」的假改动
上游 tarball 里有一部分文件带可执行位,同步时被原样拷进来,在 Linux 上 git 就记下了
30 个「+0 -0 但 modified」的文件(mode 100644 → 100755)。Windows 上完全看不出来,
是靠 GitHub Actions 真跑了一次同步才发现,并产生了一个全是权限变化的空提交。

- tools/sync_upstream.py: copy_tree 显式把文件归一化为 0644、目录 0755
- tools/test_sync_upstream.py: 新增第 9 节(POSIX 平台断言源文件里的 0755 被抹平)
- build.yml: 冒烟测试第一步加「引擎文件权限位检查」,任何非 100644 直接失败
- sync-upstream.yml: 同步后检查工作区里没有可执行文件,防止再提交权限噪音
- 本次提交同时把远端已被改坏的 30 个文件纠正回 100644
2026-10-15 19:09:15 -07:00

189 lines
6.8 KiB
YAML
Raw Permalink 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: sync upstream
# 本项目的签到引擎是「内置上游源码 + 本地补丁」,上游更新不会自己流进来。
# 这个工作流负责把它拉进来:
#
# * 手动触发(Run workflow):同步 → 重放补丁 → 提交 → 重建并发布镜像,一步到位。
# * 每周一自动检查:只比对上游有没有新提交,有就开一个 issue 提醒,不动代码。
#
# 为什么不靠「提交后让 build.yml 的 push 事件去构建」:用 GITHUB_TOKEN 推的提交
# 不会再触发其它工作流(GitHub 防递归),所以这里同步完必须自己把镜像构建掉。
on:
workflow_dispatch:
inputs:
ref:
description: "上游 ref(tag / 分支 / commit),留空则沿用 UPSTREAM.json 里记录的"
required: false
default: ""
publish:
description: "同步后重建并发布镜像到 ghcr.io"
type: boolean
default: true
schedule:
- cron: "0 1 * * 1" # 每周一 09:00(北京时间)
permissions:
contents: write
packages: write
issues: write
jobs:
# ------------------------------------------------------------------ #
# 定时:只检查,不改代码
# ------------------------------------------------------------------ #
check:
name: 检查上游是否有更新
if: github.event_name == 'schedule'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: 比对上游
id: check
run: |
set +e
python3 tools/sync_upstream.py --check | tee check.txt
code=${PIPESTATUS[0]}
echo "exit_code=$code" >> "$GITHUB_OUTPUT"
{
echo "### 上游同步检查"
echo '```'
cat check.txt
echo '```'
} >> "$GITHUB_STEP_SUMMARY"
exit 0
- name: 有更新就开 issue 提醒
if: steps.check.outputs.exit_code == '2'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
TITLE="上游 dailycheckin 有更新,可以同步了"
if gh issue list --state open --search "$TITLE in:title" --json title -q '.[].title' | grep -qF "$TITLE"; then
echo "已有未关闭的提醒 issue,跳过"
exit 0
fi
{
echo "定时检查发现上游仓库有新的提交,站点目录也可能变了。"
echo ""
echo "处理方式(任选其一):"
echo ""
echo "1. 本地跑:\`python tools/sync_upstream.py\`,然后提交推送;"
echo "2. 打开 [Actions → sync upstream](../../actions/workflows/sync-upstream.yml),点 Run workflow。"
echo ""
echo '```'
cat check.txt
echo '```'
} > body.md
gh issue create --title "$TITLE" --body-file body.md
# ------------------------------------------------------------------ #
# 手动:同步 + 提交 + 发布镜像
# ------------------------------------------------------------------ #
sync:
name: 同步上游并发布镜像
if: github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: 同步上游引擎(自动重放 patches/ 里的补丁)
id: sync
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
REF: ${{ inputs.ref }}
run: |
set -e
if [ -n "$REF" ]; then
python3 tools/sync_upstream.py --ref "$REF"
else
python3 tools/sync_upstream.py
fi
# 同步过来的文件必须把权限位归一化成 644,否则 git 会把「只有 mode 变了」
# 的文件也算成改动,每次同步都白提交一次。
extra=$(find dailycheckin -type f -perm -u+x || true)
if [ -n "$extra" ]; then
echo "以下引擎文件带上了可执行位,说明没归一化:"
echo "$extra"
exit 1
fi
# 同步工具会写 UPSTREAM.json,所以用 git 判断到底有没有变化
if git diff --quiet && git diff --cached --quiet; then
echo "changed=false" >> "$GITHUB_OUTPUT"
echo "上游内容与当前一致,无需提交"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
git diff --stat
fi
- name: 提交并推送
if: steps.sync.outputs.changed == 'true'
run: |
set -e
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
VERSION=$(python3 -c "import json;print(json.load(open('UPSTREAM.json',encoding='utf-8'))['version'])")
git add -A
git commit -m "chore: 同步上游签到引擎 ${VERSION}
由 tools/sync_upstream.py 生成:替换 dailycheckin/ 源码并重放 patches/ 里的本地补丁。"
git push
- name: 面板与引擎的离线自测
run: |
set -e
python3 tools/test_sync_upstream.py
python3 -c "import json;s=json.load(open('UPSTREAM.json',encoding='utf-8'));print('同步到',s['repo'],'@',s['ref'],s['commit'][:10],'| 引擎版本',s['version'],'| 站点',len(s['engine_sites']),'个')"
- uses: docker/setup-buildx-action@v3
if: inputs.publish
- name: 登录 GHCR
if: inputs.publish
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: 计算镜像标签
if: inputs.publish
id: meta
uses: docker/metadata-action@v5
with:
images: ghcr.io/${{ github.repository }}
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=sha,format=short
- name: 构建并推送镜像
if: inputs.publish
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
- name: 汇总
env:
CHANGED: ${{ steps.sync.outputs.changed }}
PUBLISH: ${{ inputs.publish }}
run: |
set -e
ENGINE=$(python3 -c "import json;s=json.load(open('UPSTREAM.json',encoding='utf-8'));print(s['repo']+'@'+s['ref']+' '+s['commit'][:10]+' v'+s['version'])")
{
echo "### 上游同步结果"
echo ""
echo "- 是否有代码变化:\`$CHANGED\`"
echo "- 是否发布镜像:\`$PUBLISH\`"
echo "- 引擎信息:\`$ENGINE\`"
} >> "$GITHUB_STEP_SUMMARY"