-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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 status receiver for GitHub #635
Conversation
|
There is a related pull request #516. Also, using a blocking api from the main thread is not good. |
|
I am aware of #516. To me, it looks like the original author is no longer interested into that branch. Are you still interested into having this code into main buildbot, or do you prefer it as an external extension? I don't like that implementation since it does not uses a token and it has its own implementation of github api. Are you ok with using pygithub for working with GitHub? Would it be ok to use deferToThread? Thanks! |
| @@ -0,0 +1,221 @@ | |||
| # This file is part of Buildbot. Buildbot is free software: you can | |||
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.
The filename is redundant. It should just be github.py. I know we have a bunch of other redundantly-named status modules, but that doesn't make it right..
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 can not name it github.py since "github" is already used by PyGitHub and then I can not do "from github import Stuff" since it will import from itself.
I would be happy to rename it to github.py. Is there a workaround for this ?
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.
You can use absolute imports - see http://docs.python.org/release/2.5/whatsnew/pep-328.html
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.
Many thanks for this advice. I will switch to absolute import right away! Happy to see this fixed in latest python version!
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.
Well, it was fixed years ago in Python-2.5, but we supported Python-2.4 until relatively recently.
|
Using pygithub with deferToThread is an acceptable solution. Certainly using the latest GitHub API is a big plus, as is using OAuth2 and a library that will keep up with API updates. PyGithub seems to add substantial functionality. I would like to get something of this sort merged into to Buildbot - I think this is an important capability lacking in Buildbot right now. Two things I'd like to see:
|
|
Hi. Thanks for the review. I will update it to deferToThread and add documentation and tests. The blocking code was only as a simple showcase. I will use sourcestamps to send status. I agree with your usecase. I am using an internal git mirror for buildot, so Buildbot repository name/URL is not the same as GitHub repository URL. By default, I can send status updated to all repos from the sourcestamps, but allow overwriting this behavior. Can you please explain how do you want the "comment on pull requests" feature to work? Cheers, |
|
I probably spoke too soon about pull requests. I think the code already in this pull request could be easily adapted to that end once we have a scheduler that pays attention to pull requests. |
|
Thanks for the review. Please check "Changes requested during review" from the pull description and let me know if something is wrong or is missing. I will leave the discussion about "comment on pull requests" for another review. First we need to add a scheduler which listen for GitHub notifications or polls GitHub status for a repo. This is on my TODO list. |
|
I have also updated the list of "Use cases for the plugin" . I am not sure if we should add "alwaysUseGithubRepo" options, or just use "resolveGitHubRepo" to solve all other custom logic. Please check the list and let me know if something is wrong or is missing |
|
The changes requested looks good. Per discussion in the commit, I think it's best to omit (Minor note -- we should be consistent in capitalizing GitHub with its capital 'H', as the company itself does - so |
|
Thanks. I will use GitHub and gitHub names. gitHubRepo should take care of defining on which GitHub repo to send the status. What property should be used by default for sending the SHA. It is ok to use the "revision" property? How should this plugin handle the case where multiple repos are used for a builder? |
|
The default should probably use the revision of the default codebase (the empty string). So that means |
|
I'd guess that watching for buildsets, rather than builds is what often would be desired. Regarding token genertaion, txgithub has that. |
|
Hi @tomprince , How a Buildbot Status plugin, can access the Buildsets. This is what I found about buildset, but I don't know how I can handle them from the plugin: |
|
Hi @djmitche I tried to push this forward by submitting another round of review request. This was delayed since I am waiting for an update in txgithub. Please re-read pull description as I have updated it to reflect latest changes. I have no experience with projects built from multiple repositories so I don't know how we should support them. I think that we should release the plugin with support for single repositories, and when we receive feedback I volunteer to implement the requested changes. It would be nice if for simple projects, the status could just look for a Git Step and get the repo_owner and repo_name from that URL. I don't know how this can be done. This code is untested but I will write the tests once the general lines are ok. |
|
Hi @djmitche . Did you had time to check latest changed in documentation and implementation? This branch still waits for an official release of txgithub tomprince/txgithub#2. The GitHub communication is in one way and is isolated in a method. I think that we can mock the request and continue with this work. Before putting more work into this I would like to know if the current direction is right. Thanks! |
| SUCCESS: 'success', | ||
| FAILURE: 'failure', | ||
| EXCEPTION: 'error', | ||
| } |
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.
There are more than these three states, so there should be a fallback when indexing this dictionary.
|
Huh, i could have sworn I replied earlier, but that was during PyCon. Sorry. Anyway, I've had a look at the code, and it looks fine. As for supporting multiple projects, we will need to have support for that up-front. Here's why: we've merged a number of incomplete implementations with promises to finish them later, and in many cases that hasn't worked out -- probably for perfectly valid reasons such as changing jobs or no longer needing the functionality. This is unfair both to users, who expect fully-implemented features, and to maintainers, who must eventually make the decision to rip out the feature or spend time implementing the unfinished portions. |
| self.assertEqual('1 hours, 1 minutes', result) | ||
|
|
||
| result = self.status._timeDeltaToHumanReadable(1, 60 * 60 + 62) | ||
| self.assertEqual('1 hours, 1 minutes, 1 seconds', result) |
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.
As another example you dont have here, _timeDeltaToHumanReadable would return
"1 day, 1 second"
as a result ... the purist in me thinks that
"1 day, 0 hours, 0 minutes, 1 second"
is actually better.
But, just a personal subjective opinion.
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 added the missing test.
Maybe this is cultural difference. I wanted to create a human readable format, and in normal communications from person to person, I say that the build took 1 day and 1 second and never "1 day, 0 hours, 0 minute and 1second".
This code is is not used in this branch so we can get rid of it.
As discussed with Dusting I will implement the start/end description interpolation in another branch.
Let me know if you want me to remove this code.
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.
No, I have no objection. It was more a passing thought. Just thought I'd point it out in case you didnt intend it, or in case someone else has a strong opinion.
|
Thanks @djmitche and @jaredgrubb for the review. I have updated the test and documentation. Please review the changes and let me know if anything else need to be changes. Cheers |
| repoName = Interpolate("%(prop:github_repo_name)s" | ||
| sha = Interpolate("%(src::revision)s") | ||
| startDescription = Interpolate('Build started.') | ||
| endDescription = Interpolate('Build done.') |
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'd remove the Interpolate from these 'description' ones too.
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 have removed the startDescription and endDescription and will expand them when I will implement the special interpolation for them.
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.
Yes, you removed them from the code. But you should remove them from these docs too.
|
These are all good points, and it seems like we're zeroing in on "finished." As far as I'm concerned, we can merge when the remaining details are taken care of. |
|
@adiroiban: Great job on this by the way! This is a great addition to buildbot. |
|
Thanks @jaredgrubb for the feedback and the I tried to expand the documentation with an example of how to define the github_repo_name on a builder. Please let me know if this make sense or otherwise I am happy to update the documentation. Cheers |
|
Hi. Any progress with this feature? Sould be really cool to have it merged in the master branch. |
|
AFAIK the code is ok, but it would help to get some test from other persons. @DamnWidget if you have time, it would help if you could test the code and validate it based on your requirements. Thanks! |
|
The status receiver seems to cause exceptions when I enable it. It does send status updates to GitHub, but it halts builds immediately when enabled: Tried on master with this PR pulled in and tried just the branch this PR is from. Same results both times. Happy to help track this down, but I'm a bit clueless on how to trace Twisted defers. :) |
|
So 'w' here is a deferred. Looks like a deferred got added into the self.watchers list via the subscribe method. |
|
Thank you, that was enough to get me hunting and figure out what's going on. :) buildStarted() shouldn't return a deferred that doesn't include a stepStarted method. Of course, there's still a bunch of deferred logic which must occur when a build is started, so the simple solution (borrowing from the TinderboxMailNotifier) is to put the deferred logic in a separate method which is called from buildStarted(). Here's roughly what I'm using: def buildStarted(self, builderName, build):
self._startingStatus(builderName, build)
@defer.inlineCallbacks
def _startingStatus(self, builderName, build):
status = yield self._getGitHubRepoProperties(build)
if not status:
defer.returnValue(None)
(startTime, endTime) = build.getTimes()
description = yield build.render(self._startDescription)
status.update({
'state': 'pending',
'description': description,
'builderName': builderName,
'startDateTime': datetime.datetime.fromtimestamp(
startTime).isoformat(' '),
'endDateTime': 'In progress',
'duration': 'In progress',
})
result = yield self._sendGitHubStatus(status)
defer.returnValue(result) |
|
Thanks @kyle-johnson for testing. Sorry for the error. I am now updating the code and tests and will push the changes. |
|
Hi. I have fixed the code and updated the tests. Please check that everything is ok. |
|
Let's merge once that fix is in. @jaredgrubb, if I get pulled away from reviews again, please feel free to merge directly. |
|
Hi. Thanks for the review. Is there a better way to fix this? other than logging the deferred error? I have extended the tests to check for the missing scenarios and used self.successResultOf(d) insted of d.addCallback(result.append). For logging the error, i used log.err . Please let me know if I should use log.msg. Thanks! |
|
This looks great! No, at some point things "go wrong" and the best you can do is log them. The tests for logging are very thorough. I'm a little worried about using the private |
|
Two minor problems, then. First, the tests require txgithub, and fail without. Since we haven't added that requirement to setup.py (and I'd rather not do so), the tests should really skip if that module is not available, rather than fali. Second, I get two errors: my packages: |
|
I skipped the tests when txgithub could not be imported. I could not find a setUpClass for twisted.trial.TestCase. This is why I added the skip in setup. It will show 21 skipped tests instead of a single skipped test. I have updated the date time test and I hope this time they will pass. Please check the latest changes. Thanks! |
|
Twisted doesn't do setUpClass, I think because it's based on an older unittest module. Passes for me -- I'm merging now. |
| """ | ||
| Convert Buildbot states into GitHub states. | ||
| """ | ||
| # GitHub defines `success`, `failure` and `error` states. |
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.
actually, there's "pending", too, nowadays: http://developer.github.com/v3/repos/statuses/#parameters-1
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.
The 'pending' state is sent in _sendStartStatus . This method is here to convert Buidbot states into GitHub final states.
Why would you want to send 'pending' state to GitHub as the final message for a build?
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.
ah, I see. sorry, got lead astray by the (currently incorrect) formulation of L205. Never mind, then. :-)
Problem description
GitHub provides a simple API for publishing build status for a revision from a repo.
It would be nice is Buildbot could work with GitHub to publish status for builders.
Here is my try.
Please let me know if this is on the right track and what needs to be changed.
This tried to do the same think as: #516
Use cases for the plugin
Changes requested during review
Changes description
This depend on a patch made to txgitub to support github changes. Hope the patch will be accepted soon.
It uses a token for authentication and I have documented how one can obtain a token.
No testes are present. If everything is ok I will to write the tests.
It depends on an external txgithub package but I tried to avoid reinventing the wheel.
How to try and test the changes
Get txgithub version from here tomprince/txgithub#1:
Check documentation for instruction.
Watch a pull request in GitHub.