266 lines
10 KiB
YAML
266 lines
10 KiB
YAML
name: JSON Data Validation
|
||
|
||
on:
|
||
pull_request_target:
|
||
types: [opened, synchronize, reopened, edited]
|
||
branches:
|
||
- main
|
||
paths:
|
||
- 'repo/pathing/**/*.json'
|
||
workflow_dispatch:
|
||
inputs:
|
||
path:
|
||
description: '要验证的路径'
|
||
required: true
|
||
default: 'repo/pathing'
|
||
type: string
|
||
auto_fix:
|
||
description: '是否自动修复问题'
|
||
required: false
|
||
default: true
|
||
type: boolean
|
||
pr_number:
|
||
description: '关联的 PR 号'
|
||
required: false
|
||
type: string
|
||
|
||
jobs:
|
||
validate-json:
|
||
runs-on: ubuntu-latest
|
||
permissions:
|
||
contents: write
|
||
pull-requests: write
|
||
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v4
|
||
with:
|
||
fetch-depth: 0
|
||
ref: ${{ github.event.pull_request.head.sha || github.sha }}
|
||
token: ${{ secrets.GITHUB_TOKEN }}
|
||
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
||
|
||
- name: Set up Python
|
||
uses: actions/setup-python@v5
|
||
with:
|
||
python-version: '3.10'
|
||
|
||
- name: Install dependencies
|
||
run: |
|
||
pip install packaging semver
|
||
|
||
- name: Debug file structure
|
||
run: |
|
||
echo "Current directory: $(pwd)"
|
||
echo "List files in root:"
|
||
ls -la
|
||
echo "List files in build directory (if exists):"
|
||
if [ -d "build" ]; then
|
||
ls -la build/
|
||
else
|
||
echo "build directory does not exist"
|
||
mkdir -p build
|
||
fi
|
||
|
||
- name: Setup Git and repositories
|
||
run: |
|
||
git config --global user.name "GitHub Actions Bot"
|
||
git config --global user.email "actions@github.com"
|
||
|
||
# 确保远程仓库设置正确
|
||
echo "当前远程仓库配置:"
|
||
git remote -v
|
||
|
||
# 设置上游仓库(upstream)和origin
|
||
UPSTREAM_REPO="https://github.com/${{ github.repository }}.git"
|
||
ORIGIN_REPO="https://github.com/${{ github.event.pull_request.head.repo.full_name || github.repository }}.git"
|
||
|
||
echo "设置upstream指向主仓库: $UPSTREAM_REPO"
|
||
git remote remove upstream 2>/dev/null || true
|
||
git remote add upstream $UPSTREAM_REPO
|
||
|
||
echo "确保origin指向正确的仓库: $ORIGIN_REPO"
|
||
git remote set-url origin $ORIGIN_REPO 2>/dev/null || git remote add origin $ORIGIN_REPO
|
||
|
||
# 获取最新的主仓库和分支
|
||
echo "获取远程分支信息"
|
||
git fetch upstream
|
||
git fetch origin
|
||
|
||
# 显示远程仓库配置
|
||
echo "更新后的远程仓库配置:"
|
||
git remote -v
|
||
|
||
# 检查是否处于PR环境
|
||
if [ -n "${{ github.event.pull_request.head.ref }}" ]; then
|
||
echo "检测到PR,切换到PR分支: ${{ github.event.pull_request.head.ref }}"
|
||
git checkout "${{ github.event.pull_request.head.ref }}"
|
||
elif [ -n "${{ github.ref_name }}" ]; then
|
||
echo "切换到分支: ${{ github.ref_name }}"
|
||
git checkout "${{ github.ref_name }}"
|
||
else
|
||
echo "创建临时分支"
|
||
git checkout -b temp-validation-branch
|
||
fi
|
||
|
||
- name: Prepare validation script
|
||
run: |
|
||
git show upstream/main:build/validate.py > build/validate.py 2>/dev/null
|
||
|
||
# 检查文件是否成功获取并且非空
|
||
if [ ! -s "build/validate.py" ]; then
|
||
echo "无法从上游仓库获取validate.py文件,终止流程"
|
||
exit 1
|
||
else
|
||
echo "成功获取validate.py"
|
||
fi
|
||
|
||
|
||
- name: Get PR information
|
||
if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.pr_number != '' }}
|
||
id: pr_info
|
||
uses: actions/github-script@v6
|
||
with:
|
||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
try {
|
||
const pr = await github.rest.pulls.get({
|
||
owner: context.repo.owner,
|
||
repo: context.repo.repo,
|
||
pull_number: parseInt(${{ github.event.inputs.pr_number }})
|
||
});
|
||
|
||
core.setOutput('head_sha', pr.data.head.sha);
|
||
core.setOutput('head_ref', pr.data.head.ref);
|
||
core.setOutput('head_repo', pr.data.head.repo.full_name);
|
||
core.setOutput('found', 'true');
|
||
|
||
console.log(`找到 PR #${{ github.event.inputs.pr_number }}`);
|
||
console.log(`Head SHA: ${pr.data.head.sha}`);
|
||
console.log(`Head Ref: ${pr.data.head.ref}`);
|
||
console.log(`Head Repo: ${pr.data.head.repo.full_name}`);
|
||
|
||
// 如果找到PR,切换到PR分支
|
||
const exec = require('child_process').execSync;
|
||
if (pr.data.head.ref) {
|
||
console.log(`切换到PR分支: ${pr.data.head.ref}`);
|
||
exec(`git checkout ${pr.data.head.ref}`);
|
||
}
|
||
} catch (error) {
|
||
console.log(`获取 PR #${{ github.event.inputs.pr_number }} 信息失败: ${error.message}`);
|
||
core.setOutput('found', 'false');
|
||
}
|
||
|
||
- name: Get changed files
|
||
id: changed_files
|
||
if: github.event_name == 'pull_request_target'
|
||
run: |
|
||
# 使用upstream/main作为比较基准
|
||
CHANGED_FILES=$(git diff --name-only upstream/main HEAD | grep -E '^repo/pathing/.*\.json$' || true)
|
||
echo "Changed JSON files in repo/pathing compared to upstream/main:"
|
||
echo "$CHANGED_FILES"
|
||
echo "changed_files=$CHANGED_FILES" >> $GITHUB_OUTPUT
|
||
|
||
if [ -z "$CHANGED_FILES" ]; then
|
||
echo "No JSON files changed in repo/pathing directory"
|
||
fi
|
||
|
||
- name: Run validation and correction
|
||
env:
|
||
GITHUB_ACTOR: ${{ github.actor }}
|
||
PR_NUMBER: ${{ github.event.pull_request.number || github.event.inputs.pr_number }}
|
||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||
HEAD_REF: ${{ github.event.pull_request.head.ref || steps.pr_info.outputs.head_ref || '' }}
|
||
PR_REPO: ${{ github.event.pull_request.head.repo.full_name || steps.pr_info.outputs.head_repo || github.repository }}
|
||
VALIDATE_PATH: ${{ github.event.inputs.path || 'repo/pathing' }}
|
||
AUTO_FIX: ${{ github.event.inputs.auto_fix || 'true' }}
|
||
CHANGED_FILES: ${{ steps.changed_files.outputs.changed_files }}
|
||
run: |
|
||
# 根据触发方式决定验证路径和是否自动修复
|
||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||
echo "手动触发模式,验证路径: ${VALIDATE_PATH}"
|
||
python build/validate.py ${VALIDATE_PATH} $([[ "${AUTO_FIX}" == "true" ]] && echo "--fix")
|
||
else
|
||
echo "PR 触发模式,仅验证修改的 JSON 文件"
|
||
if [ -z "$CHANGED_FILES" ]; then
|
||
echo "没有找到修改的 JSON 文件,跳过验证"
|
||
exit 0
|
||
fi
|
||
|
||
# 单独验证每个修改的文件
|
||
for file in $CHANGED_FILES; do
|
||
echo "验证文件: $file"
|
||
python build/validate.py "$file" --fix
|
||
done
|
||
fi
|
||
|
||
# 检查是否有文件被修改
|
||
if [ -n "$(git status --porcelain)" ]; then
|
||
echo "发现修改,提交更改"
|
||
git add .
|
||
git commit -m "自动修复 JSON 格式和版本号 [ci skip]"
|
||
|
||
# 确定当前分支
|
||
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
||
echo "当前分支: ${CURRENT_BRANCH}"
|
||
|
||
if [ "$CURRENT_BRANCH" = "HEAD" ]; then
|
||
# 如果在detached HEAD状态,使用正确的方式推送
|
||
if [ -n "${HEAD_REF}" ]; then
|
||
echo "在detached HEAD状态,使用HEAD_REF推送: ${HEAD_REF}"
|
||
git push origin HEAD:${HEAD_REF}
|
||
else
|
||
echo "无法确定目标分支,跳过推送"
|
||
fi
|
||
else
|
||
# 常规推送
|
||
echo "推送到分支: ${CURRENT_BRANCH}"
|
||
git push origin ${CURRENT_BRANCH}
|
||
fi
|
||
else
|
||
echo "没有文件被修改,无需提交"
|
||
fi
|
||
|
||
- name: Add PR comment
|
||
if: ${{ github.event_name == 'pull_request_target' || (github.event_name == 'workflow_dispatch' && github.event.inputs.pr_number != '' && steps.pr_info.outputs.found == 'true') }}
|
||
continue-on-error: true
|
||
uses: actions/github-script@v6
|
||
with:
|
||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const fs = require('fs');
|
||
const pr_number = ${{ github.event.pull_request.number || github.event.inputs.pr_number }};
|
||
|
||
if (fs.existsSync('validation_notes.md')) {
|
||
const message = fs.readFileSync('validation_notes.md', 'utf8');
|
||
await github.rest.issues.createComment({
|
||
issue_number: pr_number,
|
||
owner: context.repo.owner,
|
||
repo: context.repo.repo,
|
||
body: message
|
||
});
|
||
} else {
|
||
console.log("没有发现 validation_notes.md 文件");
|
||
|
||
// 检查是否有文件被修改并提交
|
||
const { execSync } = require('child_process');
|
||
let commitMessage = '';
|
||
|
||
try {
|
||
const lastCommit = execSync('git log -1 --pretty=%B').toString().trim();
|
||
if (lastCommit.includes('自动修复')) {
|
||
commitMessage = '✅ 校验完成并自动修复了一些问题。修改已提交到PR中。';
|
||
} else {
|
||
commitMessage = '✅ 校验完成,没有发现需要修复的问题';
|
||
}
|
||
} catch (error) {
|
||
commitMessage = '✅ 校验完成,没有发现需要修复的问题';
|
||
}
|
||
|
||
await github.rest.issues.createComment({
|
||
issue_number: pr_number,
|
||
owner: context.repo.owner,
|
||
repo: context.repo.repo,
|
||
body: commitMessage
|
||
});
|
||
} |