name: JS Script Validation on: pull_request_target: types: [opened, synchronize, reopened, edited] branches: - main paths: - 'repo/js/**/*.js' - 'repo/js/**/*.json' workflow_dispatch: inputs: path: description: '要验证的路径 (repo/js下的文件或目录)' required: true default: 'repo/js' type: string auto_fix: description: '是否自动修复问题' required: false default: true type: boolean jobs: validate-js: runs-on: ubuntu-latest permissions: contents: write pull-requests: write steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.10' - name: Install dependencies run: | pip install packaging semver pip install chardet - name: Setup Git run: | git config --global user.name "GitHub Actions Bot" git config --global user.email "actions@github.com" git config --global core.quotepath false # 设置upstream远程仓库指向当前仓库 CURRENT_REPO="${{ github.repository }}" git remote remove upstream 2>/dev/null || true git remote add upstream https://github.com/${CURRENT_REPO}.git # 获取upstream分支 git fetch upstream main echo "远程仓库配置:" git remote -v - name: Get changed files id: changed_files if: ${{ github.event_name == 'pull_request_target' }} run: | # 获取修改的JS和JSON文件 echo "当前分支: $(git branch --show-current)" echo "HEAD指向: $(git rev-parse HEAD)" echo "获取修改的文件..." # 方法1:使用git diff检测变化 CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD | grep -E '^repo/js/.*\.(js|json)$' || true) echo "方法1找到的文件:" echo "$CHANGED_FILES" # 方法2:如果方法1没找到,使用GitHub API if [ -z "$CHANGED_FILES" ]; then echo "方法1未找到文件,尝试使用GitHub API" CHANGED_FILES=$(curl -s -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \ "https://api.github.com/repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files" | \ jq -r '.[] | select(.filename | test("^repo/js/.*\\.(js|json)$")) | .filename' || true) echo "方法2找到的文件:" echo "$CHANGED_FILES" fi # 回退方案:如果还是没找到,验证整个JS目录 if [ -z "$CHANGED_FILES" ]; then echo "未找到修改的文件,验证整个JS目录" CHANGED_FILES="repo/js" fi echo "最终文件列表:" echo "$CHANGED_FILES" echo "changed_files=$(echo "$CHANGED_FILES" | base64 -w 0)" >> $GITHUB_OUTPUT - name: Run JS validation env: GITHUB_ACTOR: ${{ github.actor }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} HEAD_REF: ${{ github.event.pull_request.head.ref }} PR_NUMBER: ${{ github.event.pull_request.number }} CHANGED_FILES_B64: ${{ steps.changed_files.outputs.changed_files }} run: | set -e # 设置验证路径 if [ "${{ github.event_name }}" = "pull_request_target" ]; then CHANGED_FILES=$(echo "$CHANGED_FILES_B64" | base64 --decode) echo "PR触发模式,验证修改的文件:" echo "$CHANGED_FILES" # 直接处理文件列表,不创建临时文件 if [ "$CHANGED_FILES" = "repo/js" ]; then # 如果回退到整个目录,直接验证目录 python build/validate_js.py "repo/js" --fix else # 处理每个修改的文件 echo "$CHANGED_FILES" | while read -r file_path; do if [ -n "$file_path" ] && [ -f "$file_path" ]; then echo "处理文件: $file_path" python build/validate_js.py "$file_path" --fix # 如果是JS文件,检查对应目录的manifest.json if [[ "$file_path" == *.js ]]; then file_dir=$(dirname "$file_path") manifest_path="$file_dir/manifest.json" if [ -f "$manifest_path" ]; then echo "检查对应目录的manifest.json: $manifest_path" python build/validate_js.py "$manifest_path" --fix fi fi fi done fi else VALIDATE_PATH="${{ github.event.inputs.path }}" echo "手动触发模式,验证路径: ${VALIDATE_PATH}" python build/validate_js.py "${VALIDATE_PATH}" --fix fi # 检查是否有文件被修改 if [ -n "$(git status --porcelain)" ]; then echo "发现修改,检查修改的文件:" git status --porcelain # 只添加manifest.json文件的修改 MANIFEST_FILES=$(git status --porcelain | grep "manifest.json" | awk '{print $2}') if [ -n "$MANIFEST_FILES" ]; then echo "提交manifest.json版本号修改:" echo "$MANIFEST_FILES" # 检查是否只有版本号被修改 for manifest_file in $MANIFEST_FILES; do echo "检查文件修改内容: $manifest_file" git diff "$manifest_file" | head -20 # 只添加这个特定的manifest.json文件 git add "$manifest_file" done git commit -m "自动更新manifest.json版本号 [ci skip]" # 推送到PR分支 if [ "${{ github.event_name }}" = "pull_request_target" ] && [ -n "$HEAD_REF" ]; then echo "PR触发,推送到PR分支: ${HEAD_REF}" # 先拉取最新代码,然后推送 git fetch origin ${HEAD_REF} git push origin HEAD:${HEAD_REF} --force-with-lease elif [ -n "$PR_NUMBER" ] && [ -n "$HEAD_REF" ]; then echo "提交更改到PR: #$PR_NUMBER" # 确定当前分支 CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD) echo "当前分支: ${CURRENT_BRANCH}" if [ "$CURRENT_BRANCH" = "HEAD" ]; then # 如果在detached HEAD状态,使用正确的方式推送 echo "在detached HEAD状态,使用HEAD_REF推送: ${HEAD_REF}" git push origin HEAD:${HEAD_REF} else # 常规推送 echo "推送到分支: ${CURRENT_BRANCH}" git push origin ${CURRENT_BRANCH} fi else echo "未关联PR或无法确定分支,直接提交到main分支" git push origin HEAD fi else echo "没有manifest.json文件被修改,无需提交" fi else echo "没有文件被修改,无需提交" fi - name: Add PR comment if: ${{ github.event_name == 'pull_request_target' }} continue-on-error: true uses: actions/github-script@v6 with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const { execSync } = require('child_process'); let commitMessage = ''; try { const lastCommit = execSync('git log -1 --pretty=%B').toString().trim(); if (lastCommit.includes('自动修复')) { commitMessage = '✅ JS脚本校验完成并自动修复了一些问题。修改已提交到PR中。'; } else { commitMessage = '✅ JS脚本校验完成,没有发现需要修复的问题'; } } catch (error) { commitMessage = '✅ JS脚本校验完成,没有发现需要修复的问题'; } await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: commitMessage });