Skip to content

[ECO-2809] Restrict number of lines changed in a PR #30

[ECO-2809] Restrict number of lines changed in a PR

[ECO-2809] Restrict number of lines changed in a PR #30

---
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
# foo
concurrency:
group: >-
${{ github.workflow }}-${{
github.event.pull_request.number ||
github.event.pull_request_review.pull_request.number
}}
cancel-in-progress: true
env:
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
MAX_LINES: 300
OVERRIDE_APPROVING_REVIEWS: 1
jobs:
check-n-lines-changed:
runs-on: 'ubuntu-latest'
steps:
- uses: 'actions/checkout@v4'
with:
fetch-depth: 0
- id: 'get-pr-number'
name: 'Get PR number'
# yamllint disable rule:indentation
run: |
PR_NUMBER=$(
if [ "${{ github.event_name }}" = "pull_request_review" ]; then
echo "${{ github.event.pull_request_review.pull_request.number }}"
else
echo "${{ github.event.pull_request.number }}"
fi
)
echo "number=$PR_NUMBER" >> $GITHUB_OUTPUT
# yamllint disable rule:indentation
- id: 'get-insertions'
name: 'Get number of lines added'
# yamllint disable rule:indentation
run: |
git fetch origin ${{ github.base_ref }}
INSERTIONS=$(
git diff --stat origin/${{ github.base_ref }} | \
tail -n1 | grep -oP '\d+(?= insertion)' || echo "0"
)
echo "Number of lines added: $INSERTIONS"
echo "insertions=$INSERTIONS" >> $GITHUB_OUTPUT
# yamllint enable rule:indentation
- id: 'get-deletions'
name: 'Get number of lines removed'
# yamllint disable rule:indentation
run: |
DELETIONS=$(
git diff --stat origin/${{ github.base_ref }} | \
tail -n1 | grep -oP '\d+(?= deletion)' || echo "0"
)
echo "Number of lines removed: $DELETIONS"
echo "deletions=$DELETIONS" >> $GITHUB_OUTPUT
# yamllint enable rule:indentation
- id: 'get-approvals'
name: 'Get number of active approving reviews'
# Sum up the number of approvals across all reviewers, only counting a
# review as approving if it is the last review by that reviewer.
# yamllint disable rule:indentation
run: |
APPROVALS=$(
gh pr view ${{ steps.get-pr-number.outputs.number }} \
--json reviews | \
jq '
.reviews
| group_by(.user.login)
| map(last)
| map(select(.state == "APPROVED"))
| length
'
)
echo "Number of approvals: $APPROVALS"
echo "approvals=$APPROVALS" >> $GITHUB_OUTPUT
# yamllint enable rule:indentation
- name: 'Check size versus approvals'
# yamllint disable rule:indentation
run: |
TOTAL=$((
${{ steps.get-insertions.outputs.insertions }} + \
${{ steps.get-deletions.outputs.deletions }}
))
echo "Total lines changed: $TOTAL"
NEEDS_APPROVAL=0
if [ "$TOTAL" -gt "${{ env.MAX_LINES }}" ]; then
NEEDS_APPROVAL=1
fi
HAS_APPROVALS=0
if [ "${{ steps.get-approvals.outputs.approvals }}" -ge \
"${{ env.OVERRIDE_APPROVING_REVIEWS }}" ]; then
HAS_APPROVALS=1
fi
if [ "$NEEDS_APPROVAL" = "1" ] && [ "$HAS_APPROVALS" = "0" ]; then
echo "❌ Large PR ($TOTAL lines) needs" \
"${{ env.OVERRIDE_APPROVING_REVIEWS }} approvals"
exit 1
elif [ "$NEEDS_APPROVAL" = "1" ]; then
echo "✅ Large PR ($TOTAL lines) has enough approvals"
else
echo "✅ Small PR ($TOTAL lines)"
fi
# yamllint enable rule:indentation
name: 'Check number of lines changed'
'on':
pull_request:
branches-ignore:
- 'production'
- 'fallback'
pull_request_review: null
...