mirror of
https://github.com/MengMengCode/VoCat.git
synced 2026-08-20 14:53:42 +08:00
193 lines
6.4 KiB
YAML
193 lines
6.4 KiB
YAML
name: Pull request size limit
|
|
|
|
on:
|
|
pull_request_target:
|
|
branches:
|
|
- master
|
|
types:
|
|
- opened
|
|
- synchronize
|
|
- reopened
|
|
- ready_for_review
|
|
|
|
permissions:
|
|
contents: read
|
|
pull-requests: write
|
|
issues: write
|
|
|
|
concurrency:
|
|
group: pr-size-limit-${{ github.event.pull_request.number }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
enforce-size-limit:
|
|
# 保持这个名字不变,这样你 Ruleset 里的 Required Check 不需要修改
|
|
name: Enforce 5,000-line limit
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 5
|
|
|
|
env:
|
|
MAX_CHANGED_LINES: "5000"
|
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
|
|
steps:
|
|
- name: Check conflicts and pull request size via GitHub API
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
echo "Checking PR #${PR_NUMBER}"
|
|
|
|
############################################################
|
|
# Helper: comment on and close rejected PR
|
|
############################################################
|
|
|
|
reject_pr() {
|
|
local message="$1"
|
|
|
|
echo "::error::${message}"
|
|
|
|
COMMENT_PAYLOAD="$(
|
|
jq -nc \
|
|
--arg body "${message}" \
|
|
'{body: $body}'
|
|
)"
|
|
|
|
echo "Posting rejection comment..."
|
|
|
|
curl \
|
|
--fail-with-body \
|
|
--silent \
|
|
--show-error \
|
|
--request POST \
|
|
--header "Accept: application/vnd.github+json" \
|
|
--header "Authorization: Bearer ${GH_TOKEN}" \
|
|
--header "X-GitHub-Api-Version: 2022-11-28" \
|
|
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" \
|
|
--data "${COMMENT_PAYLOAD}" \
|
|
>/dev/null
|
|
|
|
echo "Closing PR #${PR_NUMBER}..."
|
|
|
|
curl \
|
|
--fail-with-body \
|
|
--silent \
|
|
--show-error \
|
|
--request PATCH \
|
|
--header "Accept: application/vnd.github+json" \
|
|
--header "Authorization: Bearer ${GH_TOKEN}" \
|
|
--header "X-GitHub-Api-Version: 2022-11-28" \
|
|
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}" \
|
|
--data '{"state":"closed"}' \
|
|
>/dev/null
|
|
|
|
exit 1
|
|
}
|
|
|
|
############################################################
|
|
# Fetch PR metadata from GitHub REST API
|
|
############################################################
|
|
|
|
echo "Fetching pull request metadata from GitHub API..."
|
|
|
|
PR_JSON=""
|
|
for attempt in {1..10}; do
|
|
PR_JSON="$(
|
|
curl \
|
|
--fail-with-body \
|
|
--silent \
|
|
--show-error \
|
|
--request GET \
|
|
--header "Accept: application/vnd.github+json" \
|
|
--header "Authorization: Bearer ${GH_TOKEN}" \
|
|
--header "X-GitHub-Api-Version: 2022-11-28" \
|
|
"${GITHUB_API_URL}/repos/${GITHUB_REPOSITORY}/pulls/${PR_NUMBER}"
|
|
)"
|
|
|
|
MERGEABLE="$(echo "${PR_JSON}" | jq -r '.mergeable')"
|
|
if [[ "${MERGEABLE}" != "null" ]]; then
|
|
break
|
|
fi
|
|
|
|
echo "Mergeable state is calculating, waiting 2s (attempt ${attempt}/10)..."
|
|
sleep 2
|
|
done
|
|
|
|
MERGEABLE="$(echo "${PR_JSON}" | jq -r '.mergeable')"
|
|
ADDITIONS="$(echo "${PR_JSON}" | jq -r '.additions // 0')"
|
|
DELETIONS="$(echo "${PR_JSON}" | jq -r '.deletions // 0')"
|
|
CHANGED_FILES="$(echo "${PR_JSON}" | jq -r '.changed_files // 0')"
|
|
|
|
CHANGED_LINES=$((ADDITIONS + DELETIONS))
|
|
|
|
############################################################
|
|
# STEP 1: Reject PRs with merge conflicts
|
|
############################################################
|
|
|
|
echo
|
|
echo "Checking for merge conflicts..."
|
|
|
|
if [[ "${MERGEABLE}" == "false" ]]; then
|
|
|
|
{
|
|
echo "### Pull request policy"
|
|
echo
|
|
echo "- Merge conflicts: ❌ Detected"
|
|
echo "- Result: Rejected"
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|
|
|
|
reject_pr "This pull request has merge conflicts with the current master branch and cannot be accepted. Please update your branch with the latest master, resolve all merge conflicts locally, and submit a conflict-free pull request."
|
|
|
|
fi
|
|
|
|
echo "No merge conflicts detected (mergeable: ${MERGEABLE})."
|
|
|
|
############################################################
|
|
# Action summary
|
|
############################################################
|
|
|
|
{
|
|
echo "### Pull request policy"
|
|
echo
|
|
echo "- Merge conflicts: ✅ None"
|
|
echo "- Changed files: ${CHANGED_FILES}"
|
|
echo "- Additions: ${ADDITIONS}"
|
|
echo "- Deletions: ${DELETIONS}"
|
|
echo "- Total changed lines: ${CHANGED_LINES}"
|
|
echo "- Maximum allowed: ${MAX_CHANGED_LINES}"
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|
|
|
|
echo
|
|
echo "Changed files: ${CHANGED_FILES}"
|
|
echo "Additions: ${ADDITIONS}"
|
|
echo "Deletions: ${DELETIONS}"
|
|
echo "Total changed lines: ${CHANGED_LINES}"
|
|
echo "Limit: ${MAX_CHANGED_LINES}"
|
|
|
|
############################################################
|
|
# STEP 2: Reject oversized PRs
|
|
############################################################
|
|
|
|
if (( CHANGED_LINES > MAX_CHANGED_LINES )); then
|
|
|
|
reject_pr "This pull request changes ${CHANGED_LINES} lines (${ADDITIONS} additions + ${DELETIONS} deletions) across ${CHANGED_FILES} files, exceeding the repository limit of ${MAX_CHANGED_LINES} changed lines. It has been closed automatically. Please split the changes into smaller pull requests."
|
|
|
|
fi
|
|
|
|
############################################################
|
|
# PASS
|
|
############################################################
|
|
|
|
echo
|
|
echo "Pull request passed all policy checks."
|
|
echo "No merge conflicts."
|
|
echo "Changed lines: ${CHANGED_LINES}/${MAX_CHANGED_LINES}."
|
|
|
|
{
|
|
echo
|
|
echo "### Result"
|
|
echo
|
|
echo "✅ Pull request passed."
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|