Skip to content

Commit 0b3d88b

Browse files
authored
Enable deltas reporting on pushes (#64)
Previously, the action only allowed reporting of memory usage change when the workflow was triggered by a pull_request event. This meant the action could only be used to determine the impact of changes proposed via pull requests. This information can also be useful to have either when pushing commits to a feature branch in preparation for a pull request, or for development work flows where pull requests are not always used (as is very common for individual Arduino projects). This will result in longer push triggered workflow run duration for people with the enable-size-deltas input set to true, but no other impact. If the previous behavior of only reporting deltas for workflows triggered by a pull_request event is desired, this can be achieved using GitHub Actions expression syntax , by changing the enable-size-deltas input's value from true to ${{ github.event_name == 'pull_request' }}.
1 parent c6fccf8 commit 0b3d88b

File tree

4 files changed

+156
-95
lines changed

4 files changed

+156
-95
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ GitHub access token used to get information from the GitHub API. Only needed if
119119

120120
### `enable-size-deltas-report`
121121

122-
Set to `true` to cause the action to determine the change in memory usage of the compiled sketches between the pull request branch and the tip of the pull request's base branch. This may be used with the [`arduino/actions/libraries/report-size-deltas` action](https://github.com/arduino/actions/tree/master/libraries/report-size-deltas). Default `false`.
122+
Set to `true` to cause the action to determine the change in memory usage of the compiled sketches. If the workflow is triggered by a `pull_request` event, the comparison is between the pull request branch and the tip of the pull request's base branch. If the workflow is triggered by a `push` event, the comparison is between the pushed commit and its immediate parent. This may be used with the [`arduino/actions/libraries/report-size-deltas` action](https://github.com/arduino/actions/tree/master/libraries/report-size-deltas). Default `false`.
123123

124124
## Example usage
125125

action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ inputs:
2626
description: 'GitHub access token used to get information from the GitHub API. Only needed if you are using the size deltas report feature with a private repository.'
2727
default: ''
2828
enable-size-deltas-report:
29-
description: 'Set to true to cause the action to determine the change in memory usage of the compiled sketches between the head and base refs of a PR'
29+
description: 'Set to true to cause the action to determine the change in memory usage of the compiled sketches between the head and base refs of a PR and the immediate parent commit of a push'
3030
default: false
3131
runs:
3232
using: 'docker'

compilesketches/compilesketches.py

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ def __init__(self, cli_version, fqbn_arg, platforms, libraries, sketch_paths, ve
126126
else:
127127
self.github_api = github.Github(login_or_token=github_token)
128128

129+
self.deltas_base_ref = self.get_deltas_base_ref()
130+
129131
self.enable_size_deltas_report = parse_boolean_input(boolean_input=enable_size_deltas_report)
130132
# The enable-size-deltas-report input has a default value so it should always be either True or False
131133
if self.enable_size_deltas_report is None:
@@ -134,6 +136,31 @@ def __init__(self, cli_version, fqbn_arg, platforms, libraries, sketch_paths, ve
134136

135137
self.sketches_report_path = pathlib.PurePath(sketches_report_path)
136138

139+
def get_deltas_base_ref(self):
140+
"""Return the Git ref to make deltas comparisons against."""
141+
if os.environ["GITHUB_EVENT_NAME"] == "pull_request":
142+
# For pull requests, the comparison is done against the PR's base branch
143+
return self.get_pull_request_base_ref()
144+
else:
145+
# For pushes, the base ref is the immediate parent
146+
return get_parent_commit_ref()
147+
148+
def get_pull_request_base_ref(self):
149+
"""Return the name of the pull request's base branch."""
150+
# Determine the pull request number, to use for the GitHub API request
151+
with open(file=os.environ["GITHUB_EVENT_PATH"]) as github_event_file:
152+
pull_request_number = json.load(github_event_file)["pull_request"]["number"]
153+
154+
# Get the PR's base ref from the GitHub API
155+
try:
156+
repository_api = self.github_api.get_repo(full_name_or_id=os.environ["GITHUB_REPOSITORY"])
157+
except github.UnknownObjectException:
158+
print("::error::Unable to access repository data. Please specify the github-token input in your "
159+
"workflow configuration.")
160+
sys.exit(1)
161+
162+
return repository_api.get_pull(number=pull_request_number).base.ref
163+
137164
def compile_sketches(self):
138165
"""Do compilation tests and record data."""
139166
self.install_arduino_cli()
@@ -768,19 +795,19 @@ def get_sketch_report(self, compilation_result):
768795
current_sizes = self.get_sizes_from_output(compilation_result=compilation_result)
769796
previous_sizes = None
770797
if self.do_size_deltas_report(compilation_result=compilation_result, current_sizes=current_sizes):
771-
# Get data for the sketch at the tip of the target repository's default branch
772-
# Get the pull request's head ref
798+
# Get data for the sketch at the base ref
799+
# Get the head ref
773800
repository = git.Repo(path=os.environ["GITHUB_WORKSPACE"])
774801
original_git_ref = repository.head.object.hexsha
775802

776-
# git checkout the PR's base ref
777-
self.checkout_pull_request_base_ref()
803+
# git checkout the base ref
804+
self.checkout_deltas_base_ref()
778805

779806
# Compile the sketch again
780807
print("Compiling previous version of sketch to determine memory usage change")
781808
previous_compilation_result = self.compile_sketch(sketch_path=compilation_result.sketch)
782809

783-
# git checkout the PR's head ref to return the repository to its previous state
810+
# git checkout the head ref to return the repository to its previous state
784811
repository.git.checkout(original_git_ref)
785812

786813
previous_sizes = self.get_sizes_from_output(compilation_result=previous_compilation_result)
@@ -855,37 +882,22 @@ def do_size_deltas_report(self, compilation_result, current_sizes):
855882
"""
856883
return (
857884
self.enable_size_deltas_report
858-
and os.environ["GITHUB_EVENT_NAME"] == "pull_request"
859885
and compilation_result.success
860886
and any(size.get(self.ReportKeys.absolute) != self.not_applicable_indicator for
861887
size in current_sizes)
862888
)
863889

864-
def checkout_pull_request_base_ref(self):
865-
"""git checkout the base ref of the pull request"""
890+
def checkout_deltas_base_ref(self):
891+
"""git checkout the base ref of the deltas comparison"""
866892
repository = git.Repo(path=os.environ["GITHUB_WORKSPACE"])
867893

868-
# Determine the pull request number, to use for the GitHub API request
869-
with open(file=os.environ["GITHUB_EVENT_PATH"]) as github_event_file:
870-
pull_request_number = json.load(github_event_file)["pull_request"]["number"]
871-
872-
# Get the PR's base ref from the GitHub API
873-
try:
874-
repository_api = self.github_api.get_repo(full_name_or_id=os.environ["GITHUB_REPOSITORY"])
875-
except github.UnknownObjectException:
876-
print("::error::Unable to access repository data. Please specify the github-token input in your workflow"
877-
" configuration.")
878-
sys.exit(1)
879-
880-
pull_request_base_ref = repository_api.get_pull(number=pull_request_number).base.ref
881-
882-
# git fetch the PR's base ref
894+
# git fetch the deltas base ref
883895
origin_remote = repository.remotes["origin"]
884-
origin_remote.fetch(refspec=pull_request_base_ref, verbose=self.verbose, no_tags=True, prune=True,
896+
origin_remote.fetch(refspec=self.deltas_base_ref, verbose=self.verbose, no_tags=True, prune=True,
885897
depth=1)
886898

887-
# git checkout the PR base ref
888-
repository.git.checkout(pull_request_base_ref)
899+
# git checkout the deltas base ref
900+
repository.git.checkout(self.deltas_base_ref)
889901

890902
def get_sizes_report(self, current_sizes, previous_sizes):
891903
"""Return a list containing all memory usage data assembled.
@@ -1101,6 +1113,12 @@ def parse_boolean_input(boolean_input):
11011113
return parsed_boolean_input
11021114

11031115

1116+
def get_parent_commit_ref():
1117+
"""Return the Git ref of the immediate parent commit."""
1118+
repository_object = git.Repo(path=os.environ["GITHUB_WORKSPACE"])
1119+
return repository_object.head.object.parents[0].hexsha
1120+
1121+
11041122
def path_relative_to_workspace(path):
11051123
"""Returns the path relative to the workspace of the action's Docker container. This is the path used in all
11061124
human-targeted output.

0 commit comments

Comments
 (0)