-
Notifications
You must be signed in to change notification settings - Fork 39
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
GitHub Status API Integration #412
base: master
Are you sure you want to change the base?
Conversation
0f24fbc
to
cfe0348
Compare
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.
Looks good, but some things can be simplified and logically reorganized. Also please add some tests.
@@ -34,12 +34,14 @@ def process_branch | |||
end | |||
|
|||
def rubocop_comments | |||
MessageBuilder.new(results, branch).comments | |||
message_builder = MessageBuilder.new(results, branch) | |||
@status = message_builder.commit_status |
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 don't think this is The Right Way™ to pass the information, the rubocop_comments
method is being used just in the replace_rubocop_comments
method, so it's safe to move its content there. This way you don't need the instance variable at all. Then you can refactor or even rename the method and maybe break it into small(er) chunk.
end | ||
|
||
def replace_rubocop_comments | ||
logger.info("Updating PR #{pr_number} with rubocop comment.") | ||
GithubService.replace_comments(fq_repo_name, pr_number, rubocop_comments) do |old_comment| | ||
GithubService.replace_comments(fq_repo_name, pr_number, rubocop_comments, @status) do |old_comment| |
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.
See my comment above...
lib/github_service.rb
Outdated
|
||
unless commit_status.nil? | ||
commit_status["options"]["target_url"] = retval["html_url"] | ||
add_status(commit_status) |
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.
Adding the status is depending on the comment's ID, however, it is an operation on the same level so this method call doesn't belong here, but AFTER the add_comments
is called.
lib/github_service.rb
Outdated
raise "no block given" unless block_given? | ||
|
||
to_delete = issue_comments(fq_repo_name, issue_number).select { |c| yield c } | ||
delete_comments(fq_repo_name, to_delete.map(&:id)) | ||
add_comments(fq_repo_name, issue_number, new_comments) | ||
add_comments(fq_repo_name, issue_number, new_comments, commit_status) |
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 think you should put the add_status
call after this line, see above...
Gemfile.lock
Outdated
@@ -396,4 +396,4 @@ DEPENDENCIES | |||
webmock | |||
|
|||
BUNDLED WITH | |||
1.15.4 | |||
1.16.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.
Don't forget to change this back please...
ef1f877
to
bb0aee2
Compare
GithubService.replace_comments(fq_repo_name, pr_number, rubocop_comments) do |old_comment| | ||
msg_builder_result = rubocop_comments | ||
|
||
GithubService.replace_comments(fq_repo_name, pr_number, msg_builder_result[:comments], msg_builder_result[:status]) do |old_comment| |
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.
Do you really need the 2 arguments if you're taking them from the same hash? Send the whole hash instead!
@@ -14,6 +14,20 @@ def comments | |||
message_builder.comments | |||
end | |||
|
|||
# requirements to "create_status(repo, sha, state, options)" | |||
def commit_status |
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.
Why is this method under the MessageBuilder
? Maybe this can be moved to a better place.
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.
Agreed. This feels like it should live somewhere 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.
lib/github_service.rb
Outdated
first_comment = add_comments(fq_repo_name, issue_number, new_comments) | ||
|
||
# add_status creates a commit status pointing to the first comment URL | ||
add_status(commit_status, first_comment) |
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.
add_status(commit_status, first_comment) unless first_comment.nil?
Then you don't need the condition in the add_status
.
lib/github_service.rb
Outdated
def add_status(comstat, comment) | ||
unless comstat.nil? | ||
comstat["options"]["target_url"] = comment["html_url"] | ||
create_status(comstat["repo"], comstat["sha"], comstat["state"], comstat["options"]) |
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.
Again, you're sending arguments from a single hash, these things can be simplified.
4395636
to
d59d903
Compare
lib/github_service.rb
Outdated
add_comment(fq_repo_name, issue_number, comment) | ||
end | ||
end.first |
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 like the idea of returning the comments, but from a clean standpoint, this method should just return all of the comments. If the caller only needs the first one, they should be the one to call .first. This way you also don't need the comment describing why you need the .first.
9f39949
to
85b2f5a
Compare
"state" => state ? "success" : "error", | ||
"options" => { | ||
"context" => "miq-bot", # TODO: it should be user name variable | ||
"target_url" => nil, |
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.
Why is this nil
? Can't be this parametrized as state
?
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.
@skateman The key is required and the value is added when the URL of the comment is obtained.
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.
OK, what about the 2nd part of the question? 😉
42e8f34
to
9699f2d
Compare
56fc858
to
20a574f
Compare
@miq-bot remove_label wip |
caad3ad
to
b0e6911
Compare
@@ -39,7 +39,10 @@ def rubocop_comments | |||
|
|||
def replace_rubocop_comments | |||
logger.info("Updating PR #{pr_number} with rubocop comment.") | |||
GithubService.replace_comments(fq_repo_name, pr_number, rubocop_comments) do |old_comment| | |||
|
|||
status = results["files"].select { |f| f["offenses"].any? }.empty? |
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.
Can you just do status = results["files"].any? { |f| f["offenses"].any? }
?
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 works exactly the opposite. I will have to negate it as
status = !results["files"].any? { |f| f["offenses"].any? }
otherwise I will have to remake the rest of the code. Do you agree with the negation?
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 you're looking for the negation, then you can also do
results["files"].none? { |f| f["offenses"].any? }
lib/github_service.rb
Outdated
first_comment = add_comments(fq_repo_name, issue_number, new_comments).first | ||
|
||
# add_status creates a commit status pointing to the first comment URL | ||
unless first_comment.nil? && status.nil? |
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.
unless nil && nil
is melting my head with triple-negatives. This would be much easier to read in the positive. I think it's
if first_comment && status
add_status(...)
end
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.
@Fryguy Can it be like this?
if first_comment && !status.nil?
add_status(...)
end
The status variable contain a boolean value so your example will not work in case of status has False
value.
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 ok, then yes, first_comment && !status.nil?
is good.
spec/lib/github_service_spec.rb
Outdated
|
||
RSpec.describe GithubService do | ||
let(:repo) { "owner/repository" } | ||
let(:sha) { "cd16q9z48b3b0xbb91wb311" } |
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.
Pretty sure a SHA only has hexidecimal digits ;)
high level I like the ability to use the github api status, but I'm not sure I want to block the PR expect in specific cases (like 💣 💥 🔥 🚒) |
@Fryguy by block do you mean red status? AFAIK we don't block PRs based on any status... |
Sorry, yes, red status. If too many PRs go "red" then it's harder for reviewers to differentiate between actual failed PRs (i.e. travis didn't pass) vs not actually failed PRs (like how when code climate goes red on 1 new issue). |
@Fryguy this makes sense, so let's add a green status when all is good and a red when 💣 💥 🔥 🚒 happens. For other cases I would just simply not set the status...what do you think? |
@europ I'm thinking the third case
should still show the status API entry, but it should be a) green and b) say something like "Changes requested" |
@Fryguy There is a possibility to use "yellow" status - the pending status. There are 4 available statuses:
Would you like to use the "yellow" one (pending status) for this case with a message "detected offenses required to fix"? |
The problem there is that when PR reviewers see "yellow" they think "the CI for this PR is still running", which is not what we want. I'm thinking just use green. |
Commits are marked with [success/error] state depending on offence detection. If there are any offences in the code, the commit is marked with error state otherwise with success state. It is reflected at the end of PR in the check conclusion part.
@Fryguy The commits are from now marked every time depending of the detected offences as you requested. There are 3 types of commit marking:
|
Checked commit europ@1354dd8 with ruby 2.3.3, rubocop 0.52.1, haml-lint 0.20.0, and yamllint 1.10.0 |
This pull request is not mergeable. Please rebase and repush. |
This feature will allow miq-bot to mark the latest commit with a status which depends from the offence(s).
Commits are marked with
success
orerror
state based on offence(s) detection viacreate_status
. If there are any offences in the code, the latest commit is marked witherror
state, otherwise withsuccess
state. It is reflected at the end of pull request in thechecks
section. The status also involves a reference (URL) to the comment which has the description about the offences.Detailed description about the creation of a commit status.
The commit state is stated in
rubocop_checker.rb
which will be used as a marking state for the last commit. This state is passed to thereplace_comments
method ingithub_service.rb
as an optional parameter also with the hash (sha) of the last commit which is going to be marked with this state. Inreplace_comments
the comment(s) writing is firstly proceed as it was originally. After writing the comment(s) about the offence(s) the id of each comment is preserved due to the missing URL which will be used in the commit status as a reference to the comment including the commit status description including the offence(s). The first comment id is selected and a payload is created which is required for thecreate_status
. Obtaining these information, the last commit is marked with the adequate state, a little state description and link to the comment including detailed description.\cc
@skateman
@romanblanco
Preview
success
error
NOTE: The
Details
refers to the comment shown above.