mirror of
https://github.com/CodelyTV/pr-size-labeler.git
synced 2025-02-13 16:50:22 -05:00
Support ignore deletions with "ignore_line_deletions" param (#71)
* Support ignore deletions with "ignore_file_deletions" param Test files_to_ignore code path Tweak the variable type Correct bad logic in the file ignore block Debug More debugging More debugging Fingers crossed Another try Last try Lets see if this one does it Testing again More tests More testing Last test Wait, I might be onto something Put some changes back Fixes Whoops Walk back yml test * Rename config variable to be ignore_line_deletions * Add and update tests * Update action.yml to provided more consistent desc. Co-authored-by: Javier Ferrer González <javier.mailserio@gmail.com> * Delete redundant helper function * Fix parse error in action.yml --------- Co-authored-by: Javier Ferrer González <javier.mailserio@gmail.com>
This commit is contained in:
parent
1cc5389c9b
commit
f2aafc4d87
12 changed files with 134 additions and 41 deletions
33
README.md
33
README.md
|
@ -55,22 +55,23 @@ jobs:
|
|||
|
||||
## 🎛️ Arguments
|
||||
|
||||
| Name | Required | Default Value | Description |
|
||||
|-------------------|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------|
|
||||
| `GITHUB_TOKEN` | Yes | Automatically supplied| GitHub token needed to interact with the repository. |
|
||||
| `xs_label` | No | 'size/xs' | Label for very small-sized PRs. |
|
||||
| `xs_max_size` | No | '10' | Maximum number of changes allowed for XS-sized PRs. |
|
||||
| `s_label` | No | 'size/s' | Label for small-sized PRs. |
|
||||
| `s_max_size` | No | '100' | Maximum number of changes allowed for S-sized PRs. |
|
||||
| `m_label` | No | 'size/m' | Label for medium-sized PRs. |
|
||||
| `m_max_size` | No | '500' | Maximum number of changes allowed for M-sized PRs. |
|
||||
| `l_label` | No | 'size/l' | Label for large-sized PRs. |
|
||||
| `l_max_size` | No | '1000' | Maximum number of changes allowed for L-sized PRs. |
|
||||
| `xl_label` | No | 'size/xl' | Label for extra-large-sized PRs. |
|
||||
| `fail_if_xl` | No | 'false' | Whether to fail the GitHub workflow if the PR size is 'XL' (blocks the merge). |
|
||||
| `message_if_xl` | No | Custom message | Message to display when a PR exceeds the 'XL' size limit. |
|
||||
| `github_api_url` | No | 'https://api.github.com' | URL for the GitHub API, can be changed for GitHub Enterprise Servers. |
|
||||
| `files_to_ignore` | No | '' | Files to ignore during PR size calculation. Supports newline or whitespace delimited list. |
|
||||
| Name | Required | Default Value | Description |
|
||||
|-------------------------|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------|
|
||||
| `GITHUB_TOKEN` | Yes | Automatically supplied| GitHub token needed to interact with the repository. |
|
||||
| `xs_label` | No | 'size/xs' | Label for very small-sized PRs. |
|
||||
| `xs_max_size` | No | '10' | Maximum number of changes allowed for XS-sized PRs. |
|
||||
| `s_label` | No | 'size/s' | Label for small-sized PRs. |
|
||||
| `s_max_size` | No | '100' | Maximum number of changes allowed for S-sized PRs. |
|
||||
| `m_label` | No | 'size/m' | Label for medium-sized PRs. |
|
||||
| `m_max_size` | No | '500' | Maximum number of changes allowed for M-sized PRs. |
|
||||
| `l_label` | No | 'size/l' | Label for large-sized PRs. |
|
||||
| `l_max_size` | No | '1000' | Maximum number of changes allowed for L-sized PRs. |
|
||||
| `xl_label` | No | 'size/xl' | Label for extra-large-sized PRs. |
|
||||
| `fail_if_xl` | No | 'false' | Whether to fail the GitHub workflow if the PR size is 'XL' (blocks the merge). |
|
||||
| `message_if_xl` | No | Custom message | Message to display when a PR exceeds the 'XL' size limit. |
|
||||
| `github_api_url` | No | 'https://api.github.com' | URL for the GitHub API, can be changed for GitHub Enterprise Servers. |
|
||||
| `files_to_ignore` | No | '' | Files to ignore during PR size calculation. Supports newline or whitespace delimited list. |
|
||||
| `ignore_line_deletions` | No | 'false' | Whether to ignore lines which are deleted when calculating the PR size. If set to 'true', deleted lines will be ignored. |
|
||||
|
||||
### Example for `files_to_ignore`:
|
||||
```yml
|
||||
|
|
|
@ -59,6 +59,10 @@ inputs:
|
|||
description: 'Whitespace separated list of files to ignore when calculating the PR size (sum of changes)'
|
||||
required: false
|
||||
default: ''
|
||||
ignore_line_deletions:
|
||||
description: 'Whether to ignore lines which are deleted when calculating the PR size. If set to "true", deleted lines will be ignored.'
|
||||
required: false
|
||||
default: 'false'
|
||||
runs:
|
||||
using: 'docker'
|
||||
image: 'Dockerfile'
|
||||
|
@ -77,6 +81,7 @@ runs:
|
|||
- --fail_if_xl=${{ inputs.fail_if_xl }}
|
||||
- --message_if_xl="${{ inputs.message_if_xl }}"
|
||||
- --files_to_ignore=${{ inputs.files_to_ignore }}
|
||||
- --ignore_line_deletions=${{ inputs.ignore_line_deletions }}
|
||||
branding:
|
||||
icon: 'tag'
|
||||
color: 'green'
|
||||
|
|
|
@ -5,36 +5,44 @@ GITHUB_API_HEADER="Accept: application/vnd.github.v3+json"
|
|||
github::calculate_total_modifications() {
|
||||
local -r pr_number="${1}"
|
||||
local -r files_to_ignore="${2}"
|
||||
local -r ignore_line_deletions="${3}"
|
||||
|
||||
local additions=0
|
||||
local deletions=0
|
||||
|
||||
if [ -z "$files_to_ignore" ]; then
|
||||
local -r body=$(curl -sSL -H "Authorization: token $GITHUB_TOKEN" -H "$GITHUB_API_HEADER" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/pulls/$pr_number")
|
||||
|
||||
local -r additions=$(echo "$body" | jq '.additions')
|
||||
local -r deletions=$(echo "$body" | jq '.deletions')
|
||||
additions=$(echo "$body" | jq '.additions')
|
||||
|
||||
echo $((additions + deletions))
|
||||
if [ "$ignore_line_deletions" != "true" ]; then
|
||||
((deletions += $(echo "$body" | jq '.deletions')))
|
||||
fi
|
||||
else
|
||||
local -r body=$(curl -sSL -H "Authorization: token $GITHUB_TOKEN" -H "$GITHUB_API_HEADER" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/pulls/$pr_number/files?per_page=100")
|
||||
|
||||
local changes=0
|
||||
|
||||
for file in $(echo "$body" | jq -r '.[] | @base64'); do
|
||||
local ignore_file=0
|
||||
for file_to_ignore in $files_to_ignore; do
|
||||
if [ -z "$file_to_ignore" ]; then
|
||||
continue
|
||||
fi
|
||||
if [[ "$(jq::base64 '.filename')" == $file_to_ignore ]]; then
|
||||
ignore_file=1
|
||||
filename=$(jq::base64 '.filename')
|
||||
ignore=false
|
||||
|
||||
for pattern in $files_to_ignore; do
|
||||
if [[ $filename == $pattern ]]; then
|
||||
ignore=true
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ $ignore_file -eq 0 ]; then
|
||||
((changes += $(jq::base64 '.changes')))
|
||||
|
||||
if [ "$ignore" = false ]; then
|
||||
((additions += $(jq::base64 '.additions')))
|
||||
|
||||
if [ "$ignore_line_deletions" != "true" ]; then
|
||||
((deletions += $(jq::base64 '.deletions')))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
echo $changes
|
||||
fi
|
||||
|
||||
echo $((additions + deletions))
|
||||
}
|
||||
|
||||
github::add_label_to_pr() {
|
||||
|
|
|
@ -1,5 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
github_actions::get_pr_number() {
|
||||
jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH"
|
||||
local -r pull_request_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
|
||||
|
||||
if [[ "$pull_request_number" != "null" ]]; then
|
||||
echo "$pull_request_number"
|
||||
else
|
||||
echo "Not a pull request event"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -9,9 +9,10 @@ labeler::label() {
|
|||
local -r fail_if_xl="${10}"
|
||||
local -r message_if_xl="${11}"
|
||||
local -r files_to_ignore="${12}"
|
||||
local -r ignore_line_deletions="${13}"
|
||||
|
||||
local -r pr_number=$(github_actions::get_pr_number)
|
||||
local -r total_modifications=$(github::calculate_total_modifications "$pr_number" "$files_to_ignore")
|
||||
local -r total_modifications=$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")
|
||||
|
||||
log::message "Total modifications (additions + deletions): $total_modifications"
|
||||
log::message "Ignoring files (if present): $files_to_ignore"
|
||||
|
|
|
@ -9,7 +9,7 @@ source "$PR_SIZE_LABELER_HOME/src/misc.sh"
|
|||
##? Adds a size label to a GitHub Pull Request
|
||||
##?
|
||||
##? Usage:
|
||||
##? main.sh --github_token=<token> --xs_label=<label> --xs_max_size=<size> --s_label=<label> --s_max_size=<size> --m_label=<label> --m_max_size=<size> --l_label=<label> --l_max_size=<size> --xl_label=<label> --fail_if_xl=<false> --message_if_xl=<message> --github_api_url=<url> --files_to_ignore=<files>
|
||||
##? main.sh --github_token=<token> --xs_label=<label> --xs_max_size=<size> --s_label=<label> --s_max_size=<size> --m_label=<label> --m_max_size=<size> --l_label=<label> --l_max_size=<size> --xl_label=<label> --fail_if_xl=<false> --message_if_xl=<message> --github_api_url=<url> --files_to_ignore=<files> --ignore_line_deletions=<false>
|
||||
main() {
|
||||
eval "$(/root/bin/docpars -h "$(grep "^##?" "$PR_SIZE_LABELER_HOME/src/main.sh" | cut -c 5-)" : "$@")"
|
||||
|
||||
|
@ -31,7 +31,8 @@ main() {
|
|||
"$xl_label" \
|
||||
"$fail_if_xl" \
|
||||
"$message_if_xl" \
|
||||
"$files_to_ignore"
|
||||
"$files_to_ignore" \
|
||||
"$ignore_line_deletions"
|
||||
|
||||
exit $?
|
||||
}
|
||||
|
|
38
tests/fixtures/pull_request_api
vendored
Normal file
38
tests/fixtures/pull_request_api
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
{
|
||||
"url": "https://api.github.com/repos/test/pulls/123",
|
||||
"number": 123,
|
||||
"state": "open",
|
||||
"locked": false,
|
||||
"title": "YOLO PR",
|
||||
"user": {},
|
||||
"body": "",
|
||||
"created_at": "2024-04-12T17:08:32Z",
|
||||
"updated_at": "2024-04-12T20:03:46Z",
|
||||
"closed_at": null,
|
||||
"merged_at": null,
|
||||
"merge_commit_sha": "9ec1fc67bbc7bd9151270",
|
||||
"assignee": null,
|
||||
"assignees": [],
|
||||
"requested_reviewers": [],
|
||||
"requested_teams": [],
|
||||
"labels": [],
|
||||
"milestone": null,
|
||||
"draft": false,
|
||||
"head": {},
|
||||
"base": {},
|
||||
"author_association": "CONTRIBUTOR",
|
||||
"auto_merge": null,
|
||||
"active_lock_reason": null,
|
||||
"merged": false,
|
||||
"mergeable": true,
|
||||
"rebaseable": false,
|
||||
"mergeable_state": "blocked",
|
||||
"merged_by": null,
|
||||
"comments": 4,
|
||||
"review_comments": 0,
|
||||
"maintainer_can_modify": false,
|
||||
"commits": 9,
|
||||
"additions": 173,
|
||||
"deletions": 1,
|
||||
"changed_files": 4
|
||||
}
|
|
@ -5,10 +5,39 @@ function set_up() {
|
|||
source ./src/github.sh
|
||||
}
|
||||
|
||||
function test_should_ignore_files_with_glob() {
|
||||
local -r pr_number=123
|
||||
local -r files_to_ignore=("*.lock" ".editorconfig")
|
||||
mock curl cat ./tests/fixtures/test_should_ignore_files_with_regex_response
|
||||
pr_number=123
|
||||
files_to_ignore=''
|
||||
ignore_line_deletions='false'
|
||||
|
||||
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}")"
|
||||
function test_should_count_changes() {
|
||||
mock curl cat ./tests/fixtures/pull_request_api
|
||||
|
||||
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
|
||||
}
|
||||
|
||||
function test_should_count_changes_ignore_deletions() {
|
||||
ignore_line_deletions='true'
|
||||
|
||||
mock curl cat ./tests/fixtures/pull_request_api
|
||||
|
||||
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
|
||||
}
|
||||
|
||||
# NOTE: when `files_to_ignore` is set, we have to invoke the PR files API and iterate each file
|
||||
# one at at time. This is why the mock call is diffent in the subsequent test cases
|
||||
function test_should_ignore_files_with_glob() {
|
||||
files_to_ignore=("*.lock" ".editorconfig")
|
||||
|
||||
mock curl cat ./tests/fixtures/pull_request_files_api
|
||||
|
||||
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
|
||||
}
|
||||
|
||||
function test_should_ignore_files_with_glob_ignore_deletions() {
|
||||
files_to_ignore=("*.lock" ".editorconfig")
|
||||
ignore_line_deletions='true'
|
||||
|
||||
mock curl cat ./tests/fixtures/pull_request_files_api
|
||||
|
||||
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
174
|
|
@ -0,0 +1 @@
|
|||
173
|
|
@ -0,0 +1 @@
|
|||
224
|
Loading…
Add table
Reference in a new issue