Skip to content

Commit

Permalink
Support ignore deletions with "ignore_line_deletions" param (#71)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
johnlk and JavierCane authored Apr 16, 2024
1 parent 1cc5389 commit f2aafc4
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 40 deletions.
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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'
40 changes: 24 additions & 16 deletions src/github.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand Down
9 changes: 8 additions & 1 deletion src/github_actions.sh
Original file line number Diff line number Diff line change
@@ -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
}
3 changes: 2 additions & 1 deletion src/labeler.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 3 additions & 2 deletions src/main.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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-)" : "$@")"

Expand All @@ -31,7 +31,8 @@ main() {
"$xl_label" \
"$fail_if_xl" \
"$message_if_xl" \
"$files_to_ignore"
"$files_to_ignore" \
"$ignore_line_deletions"

exit $?
}
38 changes: 38 additions & 0 deletions tests/fixtures/pull_request_api
Original file line number Diff line number Diff line change
@@ -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
}
File renamed without changes.
37 changes: 33 additions & 4 deletions tests/github_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,39 @@ function set_up() {
source ./src/github.sh
}

pr_number=123
files_to_ignore=''
ignore_line_deletions='false'

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() {
local -r pr_number=123
local -r files_to_ignore=("*.lock" ".editorconfig")
mock curl cat ./tests/fixtures/test_should_ignore_files_with_regex_response
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[*]}")"
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")"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
174
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
173
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
224

0 comments on commit f2aafc4

Please sign in to comment.