Skip to content

Commit f2aafc4

Browse files
johnlkJavierCane
andauthored
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 <[email protected]> * Delete redundant helper function * Fix parse error in action.yml --------- Co-authored-by: Javier Ferrer González <[email protected]>
1 parent 1cc5389 commit f2aafc4

12 files changed

+133
-40
lines changed

README.md

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,23 @@ jobs:
5555
5656
## 🎛️ Arguments
5757
58-
| Name | Required | Default Value | Description |
59-
|-------------------|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------|
60-
| `GITHUB_TOKEN` | Yes | Automatically supplied| GitHub token needed to interact with the repository. |
61-
| `xs_label` | No | 'size/xs' | Label for very small-sized PRs. |
62-
| `xs_max_size` | No | '10' | Maximum number of changes allowed for XS-sized PRs. |
63-
| `s_label` | No | 'size/s' | Label for small-sized PRs. |
64-
| `s_max_size` | No | '100' | Maximum number of changes allowed for S-sized PRs. |
65-
| `m_label` | No | 'size/m' | Label for medium-sized PRs. |
66-
| `m_max_size` | No | '500' | Maximum number of changes allowed for M-sized PRs. |
67-
| `l_label` | No | 'size/l' | Label for large-sized PRs. |
68-
| `l_max_size` | No | '1000' | Maximum number of changes allowed for L-sized PRs. |
69-
| `xl_label` | No | 'size/xl' | Label for extra-large-sized PRs. |
70-
| `fail_if_xl` | No | 'false' | Whether to fail the GitHub workflow if the PR size is 'XL' (blocks the merge). |
71-
| `message_if_xl` | No | Custom message | Message to display when a PR exceeds the 'XL' size limit. |
72-
| `github_api_url` | No | 'https://api.github.com' | URL for the GitHub API, can be changed for GitHub Enterprise Servers. |
73-
| `files_to_ignore` | No | '' | Files to ignore during PR size calculation. Supports newline or whitespace delimited list. |
58+
| Name | Required | Default Value | Description |
59+
|-------------------------|----------|----------------------|-------------------------------------------------------------------------------------------------------------------------|
60+
| `GITHUB_TOKEN` | Yes | Automatically supplied| GitHub token needed to interact with the repository. |
61+
| `xs_label` | No | 'size/xs' | Label for very small-sized PRs. |
62+
| `xs_max_size` | No | '10' | Maximum number of changes allowed for XS-sized PRs. |
63+
| `s_label` | No | 'size/s' | Label for small-sized PRs. |
64+
| `s_max_size` | No | '100' | Maximum number of changes allowed for S-sized PRs. |
65+
| `m_label` | No | 'size/m' | Label for medium-sized PRs. |
66+
| `m_max_size` | No | '500' | Maximum number of changes allowed for M-sized PRs. |
67+
| `l_label` | No | 'size/l' | Label for large-sized PRs. |
68+
| `l_max_size` | No | '1000' | Maximum number of changes allowed for L-sized PRs. |
69+
| `xl_label` | No | 'size/xl' | Label for extra-large-sized PRs. |
70+
| `fail_if_xl` | No | 'false' | Whether to fail the GitHub workflow if the PR size is 'XL' (blocks the merge). |
71+
| `message_if_xl` | No | Custom message | Message to display when a PR exceeds the 'XL' size limit. |
72+
| `github_api_url` | No | 'https://api.github.com' | URL for the GitHub API, can be changed for GitHub Enterprise Servers. |
73+
| `files_to_ignore` | No | '' | Files to ignore during PR size calculation. Supports newline or whitespace delimited list. |
74+
| `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. |
7475

7576
### Example for `files_to_ignore`:
7677
```yml

action.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ inputs:
5959
description: 'Whitespace separated list of files to ignore when calculating the PR size (sum of changes)'
6060
required: false
6161
default: ''
62+
ignore_line_deletions:
63+
description: 'Whether to ignore lines which are deleted when calculating the PR size. If set to "true", deleted lines will be ignored.'
64+
required: false
65+
default: 'false'
6266
runs:
6367
using: 'docker'
6468
image: 'Dockerfile'
@@ -77,6 +81,7 @@ runs:
7781
- --fail_if_xl=${{ inputs.fail_if_xl }}
7882
- --message_if_xl="${{ inputs.message_if_xl }}"
7983
- --files_to_ignore=${{ inputs.files_to_ignore }}
84+
- --ignore_line_deletions=${{ inputs.ignore_line_deletions }}
8085
branding:
8186
icon: 'tag'
8287
color: 'green'

src/github.sh

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,36 +5,44 @@ GITHUB_API_HEADER="Accept: application/vnd.github.v3+json"
55
github::calculate_total_modifications() {
66
local -r pr_number="${1}"
77
local -r files_to_ignore="${2}"
8+
local -r ignore_line_deletions="${3}"
9+
10+
local additions=0
11+
local deletions=0
812

913
if [ -z "$files_to_ignore" ]; then
1014
local -r body=$(curl -sSL -H "Authorization: token $GITHUB_TOKEN" -H "$GITHUB_API_HEADER" "$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/pulls/$pr_number")
1115

12-
local -r additions=$(echo "$body" | jq '.additions')
13-
local -r deletions=$(echo "$body" | jq '.deletions')
16+
additions=$(echo "$body" | jq '.additions')
1417

15-
echo $((additions + deletions))
18+
if [ "$ignore_line_deletions" != "true" ]; then
19+
((deletions += $(echo "$body" | jq '.deletions')))
20+
fi
1621
else
1722
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")
1823

19-
local changes=0
20-
2124
for file in $(echo "$body" | jq -r '.[] | @base64'); do
22-
local ignore_file=0
23-
for file_to_ignore in $files_to_ignore; do
24-
if [ -z "$file_to_ignore" ]; then
25-
continue
26-
fi
27-
if [[ "$(jq::base64 '.filename')" == $file_to_ignore ]]; then
28-
ignore_file=1
25+
filename=$(jq::base64 '.filename')
26+
ignore=false
27+
28+
for pattern in $files_to_ignore; do
29+
if [[ $filename == $pattern ]]; then
30+
ignore=true
31+
break
2932
fi
3033
done
31-
if [ $ignore_file -eq 0 ]; then
32-
((changes += $(jq::base64 '.changes')))
34+
35+
if [ "$ignore" = false ]; then
36+
((additions += $(jq::base64 '.additions')))
37+
38+
if [ "$ignore_line_deletions" != "true" ]; then
39+
((deletions += $(jq::base64 '.deletions')))
40+
fi
3341
fi
3442
done
35-
36-
echo $changes
3743
fi
44+
45+
echo $((additions + deletions))
3846
}
3947

4048
github::add_label_to_pr() {

src/github_actions.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
#!/usr/bin/env bash
22

33
github_actions::get_pr_number() {
4-
jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH"
4+
local -r pull_request_number=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
5+
6+
if [[ "$pull_request_number" != "null" ]]; then
7+
echo "$pull_request_number"
8+
else
9+
echo "Not a pull request event"
10+
exit 1
11+
fi
512
}

src/labeler.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ labeler::label() {
99
local -r fail_if_xl="${10}"
1010
local -r message_if_xl="${11}"
1111
local -r files_to_ignore="${12}"
12+
local -r ignore_line_deletions="${13}"
1213

1314
local -r pr_number=$(github_actions::get_pr_number)
14-
local -r total_modifications=$(github::calculate_total_modifications "$pr_number" "$files_to_ignore")
15+
local -r total_modifications=$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")
1516

1617
log::message "Total modifications (additions + deletions): $total_modifications"
1718
log::message "Ignoring files (if present): $files_to_ignore"

src/main.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ source "$PR_SIZE_LABELER_HOME/src/misc.sh"
99
##? Adds a size label to a GitHub Pull Request
1010
##?
1111
##? Usage:
12-
##? 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>
12+
##? 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>
1313
main() {
1414
eval "$(/root/bin/docpars -h "$(grep "^##?" "$PR_SIZE_LABELER_HOME/src/main.sh" | cut -c 5-)" : "$@")"
1515

@@ -31,7 +31,8 @@ main() {
3131
"$xl_label" \
3232
"$fail_if_xl" \
3333
"$message_if_xl" \
34-
"$files_to_ignore"
34+
"$files_to_ignore" \
35+
"$ignore_line_deletions"
3536

3637
exit $?
3738
}

tests/fixtures/pull_request_api

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"url": "https://api.github.com/repos/test/pulls/123",
3+
"number": 123,
4+
"state": "open",
5+
"locked": false,
6+
"title": "YOLO PR",
7+
"user": {},
8+
"body": "",
9+
"created_at": "2024-04-12T17:08:32Z",
10+
"updated_at": "2024-04-12T20:03:46Z",
11+
"closed_at": null,
12+
"merged_at": null,
13+
"merge_commit_sha": "9ec1fc67bbc7bd9151270",
14+
"assignee": null,
15+
"assignees": [],
16+
"requested_reviewers": [],
17+
"requested_teams": [],
18+
"labels": [],
19+
"milestone": null,
20+
"draft": false,
21+
"head": {},
22+
"base": {},
23+
"author_association": "CONTRIBUTOR",
24+
"auto_merge": null,
25+
"active_lock_reason": null,
26+
"merged": false,
27+
"mergeable": true,
28+
"rebaseable": false,
29+
"mergeable_state": "blocked",
30+
"merged_by": null,
31+
"comments": 4,
32+
"review_comments": 0,
33+
"maintainer_can_modify": false,
34+
"commits": 9,
35+
"additions": 173,
36+
"deletions": 1,
37+
"changed_files": 4
38+
}

tests/github_test.sh

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,39 @@ function set_up() {
55
source ./src/github.sh
66
}
77

8+
pr_number=123
9+
files_to_ignore=''
10+
ignore_line_deletions='false'
11+
12+
function test_should_count_changes() {
13+
mock curl cat ./tests/fixtures/pull_request_api
14+
15+
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
16+
}
17+
18+
function test_should_count_changes_ignore_deletions() {
19+
ignore_line_deletions='true'
20+
21+
mock curl cat ./tests/fixtures/pull_request_api
22+
23+
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
24+
}
25+
26+
# NOTE: when `files_to_ignore` is set, we have to invoke the PR files API and iterate each file
27+
# one at at time. This is why the mock call is diffent in the subsequent test cases
828
function test_should_ignore_files_with_glob() {
9-
local -r pr_number=123
10-
local -r files_to_ignore=("*.lock" ".editorconfig")
11-
mock curl cat ./tests/fixtures/test_should_ignore_files_with_regex_response
29+
files_to_ignore=("*.lock" ".editorconfig")
30+
31+
mock curl cat ./tests/fixtures/pull_request_files_api
1232

13-
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}")"
33+
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
1434
}
35+
36+
function test_should_ignore_files_with_glob_ignore_deletions() {
37+
files_to_ignore=("*.lock" ".editorconfig")
38+
ignore_line_deletions='true'
39+
40+
mock curl cat ./tests/fixtures/pull_request_files_api
41+
42+
assert_match_snapshot "$(github::calculate_total_modifications "$pr_number" "${files_to_ignore[*]}" "$ignore_line_deletions")"
43+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
174

0 commit comments

Comments
 (0)