mirror of
https://github.com/MengMengCode/VoCat.git
synced 2026-08-21 15:23:43 +08:00
Increased timeout for the PR size limit check from 2 to 5 minutes. Added issue permissions and improved PR size calculation steps.
156 lines
4.9 KiB
YAML
156 lines
4.9 KiB
YAML
name: Pull request size limit
|
|
|
|
on:
|
|
pull_request_target:
|
|
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:
|
|
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 }}
|
|
BASE_REF: ${{ github.event.pull_request.base.ref }}
|
|
GH_TOKEN: ${{ github.token }}
|
|
|
|
steps:
|
|
- name: Checkout trusted base repository
|
|
uses: actions/checkout@v7
|
|
with:
|
|
fetch-depth: 0
|
|
persist-credentials: false
|
|
|
|
- name: Calculate real pull request size
|
|
shell: bash
|
|
run: |
|
|
set -euo pipefail
|
|
|
|
echo "Checking PR #${PR_NUMBER}"
|
|
echo "Base branch: ${BASE_REF}"
|
|
|
|
# Fetch the latest target branch and the PR head.
|
|
# The PR code is fetched only for diff inspection; it is never executed.
|
|
git fetch --no-tags --force origin \
|
|
"+refs/heads/${BASE_REF}:refs/remotes/origin/base-size-check" \
|
|
"+refs/pull/${PR_NUMBER}/head:refs/remotes/origin/pr-${PR_NUMBER}"
|
|
|
|
BASE_COMMIT="$(git rev-parse refs/remotes/origin/base-size-check)"
|
|
PR_COMMIT="$(git rev-parse refs/remotes/origin/pr-${PR_NUMBER})"
|
|
|
|
echo "Base commit: ${BASE_COMMIT}"
|
|
echo "PR commit: ${PR_COMMIT}"
|
|
|
|
if ! MERGE_BASE="$(git merge-base "${BASE_COMMIT}" "${PR_COMMIT}")"; then
|
|
echo "::error::Unable to determine merge base."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Merge base: ${MERGE_BASE}"
|
|
|
|
NUMSTAT_FILE="$(mktemp)"
|
|
|
|
# Do not allow external diff/textconv helpers.
|
|
git diff \
|
|
--no-ext-diff \
|
|
--no-textconv \
|
|
--numstat \
|
|
"${MERGE_BASE}" \
|
|
"${PR_COMMIT}" > "${NUMSTAT_FILE}"
|
|
|
|
ADDITIONS="$(
|
|
awk '
|
|
$1 ~ /^[0-9]+$/ {
|
|
total += $1
|
|
}
|
|
END {
|
|
print total + 0
|
|
}
|
|
' "${NUMSTAT_FILE}"
|
|
)"
|
|
|
|
DELETIONS="$(
|
|
awk '
|
|
$2 ~ /^[0-9]+$/ {
|
|
total += $2
|
|
}
|
|
END {
|
|
print total + 0
|
|
}
|
|
' "${NUMSTAT_FILE}"
|
|
)"
|
|
|
|
CHANGED_FILES="$(
|
|
awk 'END { print NR + 0 }' "${NUMSTAT_FILE}"
|
|
)"
|
|
|
|
CHANGED_LINES=$((ADDITIONS + DELETIONS))
|
|
|
|
{
|
|
echo "### Pull request size"
|
|
echo
|
|
echo "- Changed files: ${CHANGED_FILES}"
|
|
echo "- Additions: ${ADDITIONS}"
|
|
echo "- Deletions: ${DELETIONS}"
|
|
echo "- Total changed lines: ${CHANGED_LINES}"
|
|
echo "- Limit: ${MAX_CHANGED_LINES}"
|
|
} >> "${GITHUB_STEP_SUMMARY}"
|
|
|
|
echo "Changed files: ${CHANGED_FILES}"
|
|
echo "Additions: ${ADDITIONS}"
|
|
echo "Deletions: ${DELETIONS}"
|
|
echo "Total changed lines: ${CHANGED_LINES}"
|
|
echo "Limit: ${MAX_CHANGED_LINES}"
|
|
|
|
if (( CHANGED_LINES <= MAX_CHANGED_LINES )); then
|
|
echo "Pull request is within the ${MAX_CHANGED_LINES}-line limit."
|
|
exit 0
|
|
fi
|
|
|
|
echo "::error::Pull request changes ${CHANGED_LINES} lines; maximum allowed is ${MAX_CHANGED_LINES}."
|
|
|
|
MESSAGE="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."
|
|
|
|
COMMENT_PAYLOAD="$(
|
|
jq -nc \
|
|
--arg body "${MESSAGE}" \
|
|
'{body: $body}'
|
|
)"
|
|
|
|
# Leave a comment explaining why the PR was rejected.
|
|
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
|
|
|
|
# Close the oversized PR.
|
|
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
|