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
fix: hooks processing fails when config includes token #693
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #693 +/- ##
==========================================
+ Coverage 84.31% 84.39% +0.08%
==========================================
Files 69 69
Lines 2747 2749 +2
==========================================
+ Hits 2316 2320 +4
+ Misses 431 429 -2
|
@TigreModerata - you helped with hooks processor recently on couple occasions. Wondering if you would be able to help with a review of this PR. Thanks! |
Yes, sure, I'm sorry I was slow with my PR (very busy last week, unexpectedly). Good thing you did it anyway, because I wasn't going to add extra logic, rather I was just going to revert back to updating all hooks no matter what. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest reducing the number of nested if's: usually in python I think more than 3 steps is considered too much.
As for the situation when a token is included in the config: one possibility would be to add an empty-string token to the gl_hook by hand, so that the rest of the processor can continue and compare the config as before. I think it improves readability and makes the nested-if's simplification easy. I don't see any obvious objections to this right now, but maybe you can correct me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to include my code snippets here, but it's unreadable if I suggest code one line at a time (I can't see how to do multiline suggestions).
debug("Changed hook to '%s'", changed_hook) | ||
elif hook_id and not any(diffs): | ||
debug(f"Hook {hook} remains unchanged") | ||
debug(f"Created hook: {created_hook}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
debug(f"Created hook: {created_hook}") | |
debug(f"Created hook: {created_hook}") | |
continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'continue' to skip right ahead to the next element in the for loop.
elif hook_id and not any(diffs): | ||
debug(f"Hook {hook} remains unchanged") | ||
debug(f"Created hook: {created_hook}") | ||
else: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
else: | |
gl_hook: dict = hook_in_gitlab.asdict() if hook_in_gitlab else {} | |
if "token" in hook_config: | |
debug( | |
f"The hook '{hook}' config includes a token. Diff between config vs gitlab cannot be confirmed" | |
) | |
gl_hook["token"] = "" | |
diffs = ( | |
map( | |
lambda k: hook_config[k] != gl_hook[k], | |
hook_config.keys(), | |
) | |
if gl_hook | |
else iter(()) | |
) | |
if any(diffs): | |
debug( | |
f"The hook '{hook}' config is different from what's in gitlab OR it contains a token" | |
) | |
debug(f"Updating hook '{hook}'") | |
updated_hook: Dict[str, Any] = project.hooks.update(hook_id, hook_config) | |
debug(f"Updated hook: {updated_hook}") | |
else: | |
debug(f"Hook '{hook}' remains unchanged") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This whole chunk instead of the rest of the code below the 'continue' after the creation of new hooks, to the end of the for loop. If you don't like the "" empty token assignement, you can leave that part as you had it, deal with the update of hooks with tokens, but then using the 'continue' to avoid another 'else' with further nested if's...
Hey 👋 . no worries at all. Wasn't expecting anything right away. I had a small opportunity and the idea about the extra logic. Thought I'd give it a shot. Thanks for the feedbacks btw. I'm a python newbi 😛 If/when I have some time next, I'll look those. I didn't understand clearly about the latter suggestions. Looking at it from mobile. Will check it out later. Thanks again. |
Yeah, you mentioned you were new to python, that's the only reason I even proposed any changes, the logic and everything was fine as it was, obviously :) |
Thanks for the feedbacks and suggestions. They all make sense to me. It is good to avoid nested conditions or loops in general; not just for python, I believe. I ended up moving the config diff logic to a separate function to make the hook processing logics a bit more readable. When you get a chance, please take another look. Thanks again. |
…-existent hook deletion
@amimas last version looks great to me! :) |
Thanks! Pushed one more small update based on the security tests being reported. It was complaining about the setting the token to an empty value, which makes sense. But, I realized I don't even need to do that. Please have a look if you get a chance. |
OK, I had feared that the token setting to "" conflicting somewhere, plus it's really unnecessary (why introduce dodgy settings when they are not even needed?)... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tiny unimportant comment (if I were to nitpick anything "unpythonic"), just to show that one can write it in one line, but I don't think there is any real advantage
else iter(()) | ||
) | ||
|
||
if any(diffs): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if any(diffs): | |
return True if any(diffs) else False |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not nitpicking. I'm glad you mentioned it. I do tend to forget about python style syntax. Thanks for pointing this out. It's small, simple, and easier to read instead of going through 4 lines.
So... I was browsing through the code and realized there's already existing logic in the super class to check whether an entity requires update or not. We didn't need to write our own logic. I didn't know about it 🤦 . Refactored the code and removed the diff checking logic from hooks processor. Used the existing logic instead. |
gulp... I should've noticed! Well, on the bright side... it had to be done (the check added to the superclass), all the better that it has already :D |
The hooks processor was recently refactored in #635 . One of the change was to inspect and only update a hook when it is needed so that unnecessary api call/update is avoided. This was done by comparing hooks config with data from gitlab about project hooks.
The above fails when a hook config includes a
token
attribute. It's treated as secret and so it is not available in the gitlab data. The comparison fails and gitlabform produces error processing the project.This PR fixes this issue by adding additional logic for hooks config with token. In this case an update is always done. Otherwise continue with existing logic of updating only if necessary. Updated test cases to validate it.
Fixes #685