Refine PR workflow to syntax checks only

This commit is contained in:
yxsj245
2026-04-05 13:37:36 +08:00
parent 08aa5bba5b
commit 1e66d036fc
4 changed files with 43 additions and 244 deletions

View File

@@ -1,11 +1,12 @@
name: PR 自动审查与分流
name: PR 代码语法检查
on:
pull_request_target:
types: [opened, reopened, synchronize, ready_for_review]
permissions:
contents: write
contents: read
issues: write
pull-requests: write
concurrency:
@@ -14,17 +15,16 @@ concurrency:
jobs:
pr-flow:
name: PR 自动化流程
name: PR 语法检查
runs-on: ubuntu-latest
steps:
- name: 初始评论 - 正在进行自动化审
- name: 初始评论 - 正在进行语法检
uses: actions/github-script@v7
with:
script: |
const { owner, repo, number } = context.issue;
// 获取 PR 变更的文件列表
const files = await github.paginate(github.rest.pulls.listFiles, {
owner, repo, pull_number: number, per_page: 100
});
@@ -34,7 +34,7 @@ jobs:
await github.rest.issues.createComment({
owner, repo, issue_number: number,
body: `⚠ 本 PR 已进入自动化审查流程,正在进行代码审查,请稍后\n\n**本次变更文件 (${fileCount} 个):**\n${fileList}\n\n正在进行变更类型识别与 TypeScript 语法检查...`
body: `⚠ 本 PR 已进入自动化语法检查流程,请稍后\n\n**本次变更文件 (${fileCount} 个):**\n${fileList}\n\n正在进行 TypeScript 语法检查...`
});
- name: 检出 PR 提交代码
@@ -66,11 +66,9 @@ jobs:
const { owner, repo, number } = context.issue;
await github.rest.issues.createComment({
owner, repo, issue_number: number,
body: '📝 本次提交仅为纯文档/文本变更。请等待作者最终审核。'
body: '📝 本次提交仅为纯文档/文本变更,已跳过代码语法检查。'
});
- name: 设置 Node 版本
if: ${{ steps.flags.outputs.docs_only != 'true' }}
uses: actions/setup-node@v4
@@ -115,7 +113,7 @@ jobs:
if [ $rc -ne 0 ]; then echo "failed=true" >> $GITHUB_OUTPUT; else echo "failed=false" >> $GITHUB_OUTPUT; fi
exit 0
- name: 类型检查失败时回复 PR
- name: 语法检查失败时回复 PR
if: ${{ (steps.tsc_server.outputs.failed == 'true' || steps.tsc_client.outputs.failed == 'true') && steps.flags.outputs.docs_only != 'true' }}
uses: actions/github-script@v7
with:
@@ -125,85 +123,29 @@ jobs:
let errorDetails = '';
// 读取 server 端错误信息
if ('${{ steps.tsc_server.outputs.failed }}' === 'true') {
try {
const serverErrors = fs.readFileSync('tsc_server_output.txt', 'utf8');
if (serverErrors.trim()) {
errorDetails += '**Server 端类型错误:**\n```\n' + serverErrors.trim() + '\n```\n\n';
errorDetails += '**Server 端语法错误:**\n```\n' + serverErrors.trim() + '\n```\n\n';
}
} catch (e) {
errorDetails += '**Server 端类型检查失败**(无法读取详细错误信息)\n\n';
errorDetails += '**Server 端语法检查失败**(无法读取详细错误信息)\n\n';
}
}
// 读取 client 端错误信息
if ('${{ steps.tsc_client.outputs.failed }}' === 'true') {
try {
const clientErrors = fs.readFileSync('tsc_client_output.txt', 'utf8');
if (clientErrors.trim()) {
errorDetails += '**Client 端类型错误:**\n```\n' + clientErrors.trim() + '\n```\n\n';
errorDetails += '**Client 端语法错误:**\n```\n' + clientErrors.trim() + '\n```\n\n';
}
} catch (e) {
errorDetails += '**Client 端类型检查失败**(无法读取详细错误信息)\n\n';
errorDetails += '**Client 端语法检查失败**(无法读取详细错误信息)\n\n';
}
}
await github.rest.issues.createComment({
owner, repo, issue_number: number,
body: `❌ 自动化类型检查未通过。命令:\`npx tsc --noEmit\`\n\n${errorDetails}请根据上述错误信息修复类型错误后再次提交,系统会重新审查~`
body: `❌ 自动化语法检查未通过。命令:\`npx tsc --noEmit\`\n\n${errorDetails}请根据上述错误信息修复后再次提交,系统会重新检查。`
});
- name: 确保 base 仓库存在 feature 分支
if: ${{ success() && steps.flags.outputs.docs_only != 'true' && steps.tsc_server.outputs.failed != 'true' && steps.tsc_client.outputs.failed != 'true' }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ACTIONS_PAT }}
script: |
const { owner, repo } = context.issue;
async function ensureFeature() {
try {
await github.rest.git.getRef({ owner, repo, ref: 'heads/feature' });
} catch (err) {
if (err.status === 404) {
const baseRef = await github.rest.git.getRef({ owner, repo, ref: 'heads/main' });
await github.rest.git.createRef({ owner, repo, ref: 'refs/heads/feature', sha: baseRef.data.object.sha });
} else {
throw err;
}
}
}
await ensureFeature();
- name: 如目标为 main则将 PR 目标分支切换为 feature
if: ${{ success() && steps.flags.outputs.docs_only != 'true' && steps.tsc_server.outputs.failed != 'true' && steps.tsc_client.outputs.failed != 'true' && github.event.pull_request.base.ref == 'main' }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ACTIONS_PAT }}
script: |
const { owner, repo, number } = context.issue;
await github.rest.pulls.update({ owner, repo, pull_number: number, base: 'feature' });
- name: 合并 PR目标为 feature 时直接合并)
if: ${{ success() && steps.flags.outputs.docs_only != 'true' && steps.tsc_server.outputs.failed != 'true' && steps.tsc_client.outputs.failed != 'true' }}
uses: actions/github-script@v7
with:
github-token: ${{ secrets.ACTIONS_PAT }}
script: |
const { owner, repo, number } = context.issue;
try {
const pr = await github.rest.pulls.get({ owner, repo, pull_number: number });
if (pr.data.state !== 'open') {
return await github.rest.issues.createComment({ owner, repo, issue_number: number, body: '⚠️ PR 当前非 open 状态,自动合并已跳过。' });
}
await github.rest.pulls.merge({ owner, repo, pull_number: number, merge_method: 'merge' });
await github.rest.issues.createComment({
owner, repo, issue_number: number,
body: '✅ 您的 PR 已通过自动化检查,现已合并至 feature测试分支。\n维护者将进行最终检查若无问题会合并到 main 分支并在下个版本发布时包含。感谢贡献!❤'
});
} catch (e) {
const msg = (e && e.message) ? e.message : String(e);
await github.rest.issues.createComment({ owner, repo, issue_number: number, body: `⚠️ 自动合并失败,请维护者查看:\n\n\`\`\`\n${msg}\n\`\`\`` });
core.setFailed('Auto merge failed');
}

View File

@@ -1,163 +0,0 @@
name: 同步main分支到指定分支
on:
push:
branches:
- main
# 环境变量配置 - 可以在这里修改目标分支和源分支
env:
SOURCE_BRANCH: main # 源分支名称
TARGET_BRANCHES: feature # 目标分支名称列表(用逗号分隔,可添加多个分支)
MERGE_STRATEGY: merge # 合并策略: merge(标准合并) 或 rebase(变基合并)
jobs:
sync-branches:
runs-on: ubuntu-latest
steps:
- name: 检出代码
uses: actions/checkout@v4
with:
fetch-depth: 0 # 获取完整的git历史
token: ${{ secrets.ACTIONS_PAT }}
- name: 配置Git用户信息
run: |
git config --global user.name "GitHub Actions Bot"
git config --global user.email "actions@github.com"
- name: 同步到多个分支
run: |
echo "🚀 开始同步流程"
echo "📌 源分支: $SOURCE_BRANCH"
echo "📌 目标分支列表: $TARGET_BRANCHES"
echo "📌 合并策略: $MERGE_STRATEGY"
echo ""
# 将逗号分隔的分支列表转换为数组
IFS=',' read -ra BRANCHES <<< "$TARGET_BRANCHES"
# 记录同步结果
SUCCESS_BRANCHES=()
FAILED_BRANCHES=()
CREATED_BRANCHES=()
# 遍历每个目标分支
for TARGET_BRANCH in "${BRANCHES[@]}"; do
# 去除空格
TARGET_BRANCH=$(echo "$TARGET_BRANCH" | xargs)
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🔄 开始同步到分支: $TARGET_BRANCH"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# 检查目标分支是否存在
if git ls-remote --heads origin $TARGET_BRANCH | grep -q $TARGET_BRANCH; then
echo "✓ $TARGET_BRANCH 分支存在"
# 切换到源分支
git checkout $SOURCE_BRANCH
# 获取并切换到目标分支
git fetch origin $TARGET_BRANCH
git checkout -B $TARGET_BRANCH origin/$TARGET_BRANCH
# 根据策略进行合并或变基
echo "正在将 $SOURCE_BRANCH 分支同步到 $TARGET_BRANCH 分支..."
SYNC_SUCCESS=false
if [ "$MERGE_STRATEGY" = "rebase" ]; then
echo "使用 rebase 策略..."
if git rebase origin/$SOURCE_BRANCH; then
echo "✅ Rebase 成功,推送到远程仓库"
git push origin $TARGET_BRANCH --force-with-lease
SYNC_SUCCESS=true
else
echo "❌ Rebase 冲突detected"
echo "冲突文件列表:"
git status --porcelain | grep "^UU\|^AA\|^DD" || echo "无法确定冲突文件"
git rebase --abort
FAILED_BRANCHES+=("$TARGET_BRANCH")
fi
else
echo "使用 merge 策略..."
if git merge origin/$SOURCE_BRANCH --no-edit; then
echo "✅ 合并成功,推送到远程仓库"
git push origin $TARGET_BRANCH
SYNC_SUCCESS=true
else
echo "❌ 合并冲突detected"
echo "冲突文件列表:"
git status --porcelain | grep "^UU\|^AA\|^DD" || echo "无法确定冲突文件"
git merge --abort
FAILED_BRANCHES+=("$TARGET_BRANCH")
fi
fi
if [ "$SYNC_SUCCESS" = true ]; then
SUCCESS_BRANCHES+=("$TARGET_BRANCH")
fi
else
echo "⚠️ $TARGET_BRANCH 分支不存在,从 $SOURCE_BRANCH 分支创建"
git checkout -B $TARGET_BRANCH $SOURCE_BRANCH
git push origin $TARGET_BRANCH --set-upstream
echo "✅ 成功创建 $TARGET_BRANCH 分支"
CREATED_BRANCHES+=("$TARGET_BRANCH")
SUCCESS_BRANCHES+=("$TARGET_BRANCH")
fi
done
# 输出最终汇总
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📊 同步结果汇总"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ 成功同步的分支 (${#SUCCESS_BRANCHES[@]}): ${SUCCESS_BRANCHES[*]}"
[ ${#CREATED_BRANCHES[@]} -gt 0 ] && echo "🆕 新创建的分支 (${#CREATED_BRANCHES[@]}): ${CREATED_BRANCHES[*]}"
[ ${#FAILED_BRANCHES[@]} -gt 0 ] && echo "❌ 失败的分支 (${#FAILED_BRANCHES[@]}): ${FAILED_BRANCHES[*]}"
# 如果有失败的分支退出码为1
if [ ${#FAILED_BRANCHES[@]} -gt 0 ]; then
echo ""
echo "⚠️ 部分分支同步失败,请手动处理冲突"
exit 1
fi
env:
GITHUB_TOKEN: ${{ secrets.ACTIONS_PAT }}
- name: 输出同步结果
if: success()
run: |
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "✅ 所有分支同步成功!"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "📌 源分支: $SOURCE_BRANCH"
echo "📌 目标分支列表: $TARGET_BRANCHES"
echo "📝 同步的提交: ${{ github.sha }}"
echo "👤 推送者: ${{ github.actor }}"
echo "🔄 同步方式: $MERGE_STRATEGY"
echo "⏰ 同步时间: $(date '+%Y-%m-%d %H:%M:%S')"
- name: 冲突处理提示
if: failure()
run: |
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "⚠️ 部分分支同步失败 - 检测到合并冲突"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
echo "🔧 手动解决冲突的步骤:"
echo "1. 本地克隆仓库: git clone <repo-url>"
echo "2. 切换到失败的目标分支: git checkout <target-branch>"
echo "3. 合并源分支: git merge $SOURCE_BRANCH"
echo "4. 手动解决冲突文件"
echo "5. 添加解决后的文件: git add ."
echo "6. 提交解决结果: git commit"
echo "7. 推送到远程: git push origin <target-branch>"
echo ""
echo "💡 提示:"
echo " - 可以修改工作流中的 MERGE_STRATEGY 环境变量来改变合并策略"
echo " - 可以从 TARGET_BRANCHES 中移除经常冲突的分支,单独处理"

View File

@@ -158,16 +158,6 @@ GSManager3/
2. 不得提交具有后门,入侵操作系统等严重违规违法故意破坏使用者计算机的行为!
3. 请确保您提交的代码清晰标注注释,变量请使用驼峰命名法。
4. 代码逻辑不能采用非常简单粗暴的行为,应当评估代码在正式环境中对系统性能影响程度,始终要把性能消耗降到最低。
### 贡献流程
1. 确保代码符合准则没有语法错误。然后发起PR请求提交到本仓库的`main`分支。并详细说明代码功能和实现或修复的地方。
2. 自动化审查脚本将会对您提交的代码进行基准检查,通过后将会自动合并到`feature`分支后需要等待作者进行最终功能和代码审核
3. 审核通过后将会合并到`main`主分支并在您的PR告知您已通过最终审核。根据内容量和影响程度会评估最终发包时间一般不超过7天。
### 特殊情况处理
若您代码提交后发现存在问题,届时您也没看到通过最终审核您需要确保提交的远程分支为`feature`以确保仓库的同步
> 一般情况在自动化审核通过后此PR会自动修改为`feature`分支
---
## 📞 支持与反馈

View File

@@ -0,0 +1,30 @@
# PR 自动语法检查说明
## 说明
`pr-auto-check.yml` 现在只负责对 PR 进行代码语法检查,不再执行以下操作:
- 自动切换 PR 的目标分支
- 自动合并 PR
- 自动创建或调整 `feature` 分支
## 检查范围
当前流程会在 PR 打开、重新打开、推送新提交或标记为可审阅时触发,并执行以下内容:
1. 读取 PR 变更文件列表,并在评论中提示当前状态
2. 检出 PR 对应提交
3. 判断是否仅包含文档变更
4.`server``client` 分别执行 `npx tsc --noEmit`
5. 如果检查失败,在 PR 中回复中文错误信息
## 结果说明
- 如果 PR 仅修改文档或文本文件,会跳过代码语法检查,并在 PR 中给出提示
- 如果 `server``client` 的 TypeScript 检查失败,工作流会返回对应的错误输出
- 如果检查通过,工作流不会再自动合并代码,也不会修改 PR 的目标分支
## 维护建议
- 如果后续希望增加其他静态检查,可以在这里继续补充流程说明
- 如果需要恢复自动合并,请单独设计新的工作流,不建议和语法检查混在一起