diff --git a/.github/workflows/pr_clang_format.yml b/.github/workflows/pr_clang_format.yml index fb05a47d744..bbd0c6c5b22 100644 --- a/.github/workflows/pr_clang_format.yml +++ b/.github/workflows/pr_clang_format.yml @@ -3,21 +3,17 @@ name: Code Format with Clang-Format on: workflow_dispatch: inputs: + branch: + description: "PR 分支名称\nPR branch name" + required: true + type: string exclude_patterns: description: "排除文件/目录 (以逗号间隔)\n Files/Directories to exclude(comma-separated)" required: false default: '' - branch: - description: "要格式化的分支 | Branch to format" - required: true - default: '' - pr_number: - description: "PR编号 | PR Number" - required: true - default: '' concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + group: ${{ github.workflow }}-${{ inputs.branch || github.ref }} cancel-in-progress: true permissions: @@ -29,12 +25,16 @@ jobs: if: | github.repository_owner != 'RT-Thread' runs-on: ubuntu-latest + env: + HEAD_OWNER: ${{ github.repository_owner }} + SOURCE_REPOSITORY: ${{ github.repository }} + TARGET_BRANCH: ${{ inputs.branch }} steps: - name: Checkout code uses: actions/checkout@v4 with: - ref: ${{ github.event.inputs.branch }} + ref: ${{ inputs.branch }} fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} lfs: false @@ -52,7 +52,7 @@ jobs: echo "📋 Checking supported features..." clang-format --help | grep -i "align\|consecutive" || echo "No align/consecutive options found" - - name: Get PR info (files and author) + - name: Get PR info and changed files id: get-pr-info run: | max_retries=3 @@ -60,31 +60,46 @@ jobs: changed_files="" api_response="" - # 获取PR编号(workflow_dispatch时需要手动输入) - PR_NUMBER="${{ github.event.inputs.pr_number }}" + # fork 查询父仓库中的 PR,独立镜像则查询当前仓库 + repository=$(curl -sS \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "Accept: application/vnd.github+json" \ + "https://api.github.com/repos/${SOURCE_REPOSITORY}") + UPSTREAM_REPOSITORY=$(jq -r '.parent.full_name // .full_name // empty' <<<"$repository") - if [ -z "$PR_NUMBER" ]; then - echo "Error: PR number is required" + if [ -z "$UPSTREAM_REPOSITORY" ]; then + echo "Error: Failed to determine the pull request repository" + echo "API response: $repository" exit 1 fi - echo "Fetching PR info for #$PR_NUMBER..." + echo "Using PR repository: $UPSTREAM_REPOSITORY" + echo "upstream_repository=$UPSTREAM_REPOSITORY" >> "$GITHUB_OUTPUT" - # 获取PR的详细信息(包括作者) - pr_response=$(curl -s \ + # 根据当前仓库所有者和所选分支自动查找上游 PR + pull_requests=$(curl -sS -G \ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ - -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/RT-Thread/rt-thread/pulls/$PR_NUMBER") + -H "Accept: application/vnd.github+json" \ + --data-urlencode "state=open" \ + --data-urlencode "head=${HEAD_OWNER}:${TARGET_BRANCH}" \ + "https://api.github.com/repos/${UPSTREAM_REPOSITORY}/pulls") - # 获取PR作者的GitHub用户名 - PR_AUTHOR=$(jq -r '.user.login' <<<"$pr_response") - echo "PR Author: $PR_AUTHOR" + if ! jq -e 'type == "array"' <<<"$pull_requests" >/dev/null; then + echo "Error: Failed to query the upstream pull request" + echo "API response: $pull_requests" + exit 1 + fi - # 使用GitHub noreply邮箱格式 - PR_AUTHOR_EMAIL="${PR_AUTHOR}+github[bot]@noreply.github.com" + pr_count=$(jq 'length' <<<"$pull_requests") + if [ "$pr_count" -ne 1 ]; then + echo "Error: Expected exactly one open PR for ${HEAD_OWNER}:${TARGET_BRANCH}, found $pr_count" + jq -r '.[] | "PR #\(.number): \(.html_url)"' <<<"$pull_requests" + exit 1 + fi - echo "pr_author=$PR_AUTHOR" >> $GITHUB_OUTPUT - echo "pr_author_email=$PR_AUTHOR_EMAIL" >> $GITHUB_OUTPUT + PR_NUMBER=$(jq -r '.[0].number' <<<"$pull_requests") + echo "Matched upstream PR #$PR_NUMBER" + echo "pr_number=$PR_NUMBER" >> "$GITHUB_OUTPUT" echo "Fetching changed files for PR #$PR_NUMBER..." @@ -93,7 +108,7 @@ jobs: api_response=$(curl -s -w "\n%{http_code}" \ -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ -H "Accept: application/vnd.github.v3+json" \ - "https://api.github.com/repos/RT-Thread/rt-thread/pulls/$PR_NUMBER/files") + "https://api.github.com/repos/${UPSTREAM_REPOSITORY}/pulls/$PR_NUMBER/files") # 分离HTTP状态码和响应内容 http_status=$(echo "$api_response" | tail -1) @@ -268,29 +283,29 @@ jobs: - name: Commit and push changes if: steps.check-changes.outputs.has_changes == 'true' run: | - # 使用PR作者作为commit author,避免CLA检查失败 - # CLA检查只识别PR作者(已签署CLA),而不识别github-actions[bot] - PR_AUTHOR="${{ steps.get-pr-info.outputs.pr_author }}" - PR_AUTHOR_EMAIL="${{ steps.get-pr-info.outputs.pr_author_email }}" - - git config --local user.email "$PR_AUTHOR_EMAIL" - git config --local user.name "$PR_AUTHOR" - - # 使用GIT_AUTHOR环境变量让commit以贡献者名义提交 - export GIT_AUTHOR_NAME="$PR_AUTHOR" - export GIT_AUTHOR_EMAIL="$PR_AUTHOR_EMAIL" + old_head=$(git rev-parse HEAD) + committer_name=$(git show -s --format=%cn "$old_head") + committer_email=$(git show -s --format=%ce "$old_head") + committer_date=$(git show -s --format=%cI "$old_head") git add -A - git commit -m "style: format code with clang-format [skip ci]" - git push origin HEAD:${{ github.event.inputs.branch }} + GIT_COMMITTER_NAME="$committer_name" \ + GIT_COMMITTER_EMAIL="$committer_email" \ + GIT_COMMITTER_DATE="$committer_date" \ + git commit --amend --no-edit --no-gpg-sign + git push \ + --force-with-lease="refs/heads/${TARGET_BRANCH}:${old_head}" \ + origin "HEAD:refs/heads/${TARGET_BRANCH}" - echo "✅ 代码格式化完成并已推送到分支 ${{ github.event.inputs.branch }}" + echo "✅ 格式化结果已追加到分支 ${TARGET_BRANCH} 的最后一个提交" - name: Summary run: | echo "=== 格式化总结 ===" - echo "分支: ${{ github.event.inputs.branch }}" + echo "分支: ${TARGET_BRANCH}" + echo "PR 仓库: ${{ steps.get-pr-info.outputs.upstream_repository }}" + echo "上游 PR: #${{ steps.get-pr-info.outputs.pr_number }}" echo "排除模式: ${{ github.event.inputs.exclude_patterns || '无' }}" echo "处理文件数: ${{ steps.find-files.outputs.files_count }}" echo "有更改: ${{ steps.check-changes.outputs.has_changes }}" - echo "clang-format 版本: $(clang-format --version | head -1)" \ No newline at end of file + echo "clang-format 版本: $(clang-format --version | head -1)" diff --git a/.github/workflows/pr_format_bot.yml b/.github/workflows/pr_format_bot.yml index 3ba8ded41b0..f834ac94aab 100644 --- a/.github/workflows/pr_format_bot.yml +++ b/.github/workflows/pr_format_bot.yml @@ -1,7 +1,7 @@ name: PR Format Notification on: pull_request_target: - types: [opened] + types: [opened, reopened, synchronize] concurrency: @@ -14,7 +14,7 @@ permissions: jobs: notify-format: - if: github.repository_owner == 'RT-Thread' + if: github.repository_owner == 'RT-Thread' || github.repository == 'CYFS3/rt-thread-mirror' runs-on: ubuntu-latest steps: - name: Check if first commit and add comment @@ -40,7 +40,7 @@ jobs: echo "PR commit count: $commit_count" should_comment=false - if [ "$PR_ACTION" = "opened" ]; then + if [ "$PR_ACTION" = "opened" ] || [ "$PR_ACTION" = "reopened" ]; then should_comment=true elif [ "$PR_ACTION" = "synchronize" ] && [ "$commit_count" -eq 1 ]; then should_comment=true @@ -53,7 +53,7 @@ jobs: branch="$PR_HEAD_REF" fork_repo="$PR_HEAD_REPO" workflow_url="https://github.com/${fork_repo}/actions/workflows/pr_clang_format.yml" - direct_link="${workflow_url}?branch=${branch}" + direct_link="${workflow_url}" # 使用数组存储多行消息 message_lines=( @@ -71,14 +71,16 @@ jobs: "[点击进入工作流 → | Click to open workflow →](${direct_link})" "" "2. **点击 \`Run workflow\` | Click \`Run workflow\`**" + "- \`Use workflow from\` 保持默认分支(通常为 \`master\`)" + "Keep the default branch (usually \`master\`) in \`Use workflow from\`" + "- 在 \`branch\` 输入框填写 PR 分支 **\`${branch}\`**" + "Enter PR branch **\`${branch}\`** in the \`branch\` field" "- 设置需排除的文件/目录(目录请以\"/\"结尾)" "Set files/directories to exclude (directories should end with \"/\")" - "- 将目标分支设置为 \ Set the target branch to:**\`${branch}\`**" - "- 设置PR number为 \ Set the PR number to:**\`${PR_NUMBER}\`**" "" "3. **等待工作流完成 | Wait for the workflow to complete**" - "格式化后的代码将自动推送至你的分支。" - "The formatted code will be automatically pushed to your branch." + "格式化后的代码将追加到最后一个提交并推送至你的分支。" + "The formatting changes will be amended into the latest commit and pushed to your branch." "" "完成后,提交将自动更新至 \`${branch}\` 分支,关联的 Pull Request 也会同步更新。" "Once completed, commits will be pushed to the \`${branch}\` branch automatically, and the related Pull Request will be updated." @@ -143,4 +145,4 @@ jobs: echo "Failed to get commits from GitHub API" echo "Response: $commits" exit 1 - fi \ No newline at end of file + fi