Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a comment when downloading and merging from a PR fails via comment_download_pr() #248

Merged
merged 16 commits into from
Feb 14, 2024

Conversation

Neves-P
Copy link
Member

@Neves-P Neves-P commented Feb 11, 2024

Adds a new function comment_download_pr() that takes the exit codes from download_pr() to give an helpful message via a GH comment on an open PR.

The aim is to mostly handle situations where a merge conflict due to an upstream merge prevents the git apply step in download_pr() from working. At this stage of download_pr(), the recent changes (a patch) are downloaded and git apply is used. When a merge conflict is present, git apply fails with an error and which not reported by the bot and made visible to the user.

For this change, I also explicitly pass the error codes out of download_pr() to be able to expose the error message to the user and handle the errors.

To be done in the future: add unit tests to the new functionality. I have started, but not managed to finish the mocking and testing framework for this function. Adding this PR so we have have this functionality earlier.

This PR addresses #212.

@Neves-P
Copy link
Member Author

Neves-P commented Feb 11, 2024

I'll handle all the linter comments tomorrow (12/02)

Copy link
Contributor

@trz42 trz42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work and more than just checking the result of git apply.

For some print statements, log might be better.

The calling function may not easily know which step (cloning the repo, branching, downloading the diff or applying the diff) failed. If the result would contain a 4th item one might include that information and use it when checking the exit code. Thus the note to the user could be adjusted and also the "Tip". Alternatively, one might only check the result of git apply.

Would the comment be created for all potential jobs or just once (because an exception is raised)? If multiple comments would be created, might be ok for now as it is already an improvement.

tasks/build.py Outdated
@@ -346,21 +346,60 @@ def download_pr(repo_name, branch_name, pr, arch_job_dir):
# - 'curl' diff for pull request
# - 'git apply' diff file
git_clone_cmd = ' '.join(['git clone', f'https://github.com/{repo_name}', arch_job_dir])
clone_output, clone_error, clone_exit_code = run_cmd(git_clone_cmd, "Clone repo", arch_job_dir)
print(f'cloning with command {git_clone_cmd}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prints to stdout. Should it maybe go to a log file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolutely, I've changed this and other occurrences to use log().

tasks/build.py Outdated

git_checkout_cmd = ' '.join([
'git checkout',
branch_name,
])
print(f'checking out with command {git_checkout_cmd}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prints to stdout. Should it maybe go to a log file?

tasks/build.py Outdated

curl_cmd = f'curl -L https://github.com/{repo_name}/pull/{pr.number}.diff > {pr.number}.diff'
curl_output, curl_error, curl_exit_code = run_cmd(curl_cmd, "Obtain patch", arch_job_dir)

print(f'curl with command {curl_cmd}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prints to stdout. Should it maybe go to a log file?

tasks/build.py Outdated
git_apply_cmd = f'git apply {pr.number}.diff'
git_apply_output, git_apply_error, git_apply_exit_code = run_cmd(git_apply_cmd, "Apply patch", arch_job_dir)
print(f'git apply with command {git_apply_cmd}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This prints to stdout. Should it maybe go to a log file?

tasks/build.py Outdated
download_comment = (f"`{download_pr_error}`"
f"\nUnable to download or merge changes between the source branch and the destination branch.\n"
f"\nTip: This can usually be resolved by syncing your branch and resolving any merge conflicts.")
download_comment = pr_comments.create_comment(repo_name=base_repo_name, pr_number=pr.number, comment=download_comment)
Copy link
Contributor

@trz42 trz42 Feb 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This creates a new comment (for each job that failed), right? So we might get many new comments. Wonder if it could be possible to pass the result back to the calling function such that it is included in the responses to the bot: build command(s)?

Edit: Maybe just one comment is added because an exception is raised for the first error that happened?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. I actually meant for it to just comment once and stop with the exception, but I did not actually verify that it works that way because when I was playing around with it I was only building for one target: Neves-Bot/software-layer#12 (comment)

In that case of course the bot could only write one comment for that one target, so I'm completely sure the raising the error is enough 🤔

@Neves-P
Copy link
Member Author

Neves-P commented Feb 12, 2024

Nice work and more than just checking the result of git apply.

Thank you! I've address the other change requests individually.

The calling function may not easily know which step (cloning the repo, branching, downloading the diff or applying the diff) failed. If the result would contain a 4th item one might include that information and use it when checking the exit code. Thus the note to the user could be adjusted and also the "Tip". Alternatively, one might only check the result of git apply.

Indeed, that's a great point, I've tried addressing that just now, where the error reporting and tip are handled depending on where the error occurs in download_pr(). This required returning a new error_stage variable to inform comment_download_pr() of what to do. There might be a more clever way to do this, but I couldn't think of anything simple at first thought.

One very important note: I am in the process of reinstalling the bot on our HPC and setting it up to build for all the CPU targets we need in Groningen, so until that is done I can't test this at the moment as I was doing here: Neves-Bot/software-layer#12. I know the code before the latest commits was working, but I can't say the same for this revision. I hope to have some time do finish that this week and then I'll already test this code. Unless there is a way of testing this outside of production code that I'm not aware of, it may be wise to wait on the merge until then :)

Copy link
Contributor

@trz42 trz42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. Just a small suggestion on how to use string constants, e.g., define a variable at the beginning, then use that variable.

The text snippets that are used to print error messages could also be made configurable. That would allow us to change them in the configuration file (instead of changing them in the bot code). What do you think, would this make sense or would it be overkill here?

tasks/build.py Outdated
git_clone_cmd, "Clone repo", arch_job_dir, raise_on_error=False
)
if clone_exit_code != 0:
error_stage = 'git clone'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good. Minor suggestion

Suggested change
error_stage = 'git clone'
error_stage = ERROR_GIT_CLONE

and at the beginning (lines 34-79) add something like

ERROR_GIT_CLONE = 'git clone'

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, for every occurrence of error_stage.

tasks/build.py Outdated
"""
if download_pr_exit_code != 0:
fn = sys._getframe().f_code.co_name
if error_stage == 'git clone':
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use globally defined variable ERROR_GIT_CLONE, e.g.,

Suggested change
if error_stage == 'git clone':
if error_stage == ERROR_GIT_CLONE:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved string constants to globally defined variables in header.

@Neves-P
Copy link
Member Author

Neves-P commented Feb 14, 2024

Thanks for the review! I've tried addressing them all, the string constants are globally defined at the top now and I've moved the text snippets to the cfg file. Let me know if something isn't right or if I should make more changes 👍

Copy link
Contributor

@trz42 trz42 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice work @Neves-P !!! Apologies for so many requests for changes.

@trz42 trz42 merged commit 75893a4 into EESSI:develop Feb 14, 2024
7 checks passed
This was referenced Feb 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants