-
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #35 from voxpupuli/event-handling
WIP: Event handling
- Loading branch information
Showing
13 changed files
with
199 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
class GithubEvent | ||
attr_reader :processor | ||
delegate :process, to: :processor | ||
|
||
## | ||
# The GithubEvent handler checks which type of event we are dealing with. | ||
# | ||
# If it is a known event, create a specific handler and let it take care of | ||
# the next steps. If not kick off a Sentry error. | ||
|
||
def initialize(payload, type) | ||
case type | ||
when 'pull_request' | ||
@processor = GithubEvent::PullRequest.new(payload) | ||
else | ||
Raven.capture_message('Unknown Hook Received', extra: payload) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class GithubEvent | ||
class Base | ||
attr_reader :payload | ||
|
||
## | ||
# Receive the payload and start processing it | ||
|
||
def initialize(payload) | ||
@payload = payload | ||
process | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
class GithubEvent | ||
class PullRequest < GithubEvent::Base | ||
attr_reader :gh_pull_request | ||
|
||
## | ||
# Currently we only care about syncing our database with GitHub as our validation | ||
# will take action if necessary. | ||
|
||
def process | ||
::PullRequest.update_with_github(payload['pull_request']) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,8 @@ | ||
class Label < ApplicationRecord | ||
has_and_belongs_to_many :pull_requests | ||
|
||
# TODO: Find out how to manage predefined labels | ||
def self.needs_rebase | ||
find_or_create_by(name: 'needs-rebase', color: '207de5') | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,89 @@ | ||
class PullRequest < ApplicationRecord | ||
belongs_to :repository | ||
# It is easier overall to use the GitHub ID for relation management. | ||
# It allows us to maintain, update or the Repository or PullRequest without | ||
# the counterpart. | ||
belongs_to :repository, primary_key: :github_id, foreign_key: :gh_repository_id, inverse_of: :pull_requests | ||
|
||
has_and_belongs_to_many :labels | ||
after_save :queue_validation | ||
|
||
## | ||
# This method is used for updating our database with the current state of the PullRequest | ||
# in GitHub. Therefore it's used with the payload of the webhook content processed by | ||
# GithubEvent handler and by the content from the api fetched by the periodic check. | ||
|
||
def self.update_with_github(gh_pull_request) | ||
PullRequest.where(github_id: gh_pull_request['id']).first_or_initialize.tap do |pull_request| | ||
pull_request.number = gh_pull_request['number'] | ||
pull_request.state = gh_pull_request['state'] | ||
pull_request.title = gh_pull_request['title'] | ||
pull_request.body = gh_pull_request['body'] | ||
pull_request.gh_created_at = gh_pull_request['created_at'] | ||
pull_request.gh_updated_at = gh_pull_request['updated_at'] | ||
pull_request.gh_repository_id = gh_pull_request['base']['repo']['id'] | ||
pull_request.closed_at = gh_pull_request['closed_at'] | ||
pull_request.merged_at = gh_pull_request['merged_at'] | ||
pull_request.mergeable = gh_pull_request['mergeable'] | ||
pull_request.save | ||
|
||
gh_pull_request['labels'].each do |label| | ||
pull_request.labels << Label.find_or_create_by(name: label['name'], color: label['color']) | ||
end | ||
end | ||
end | ||
|
||
## | ||
# Ensure that the Label is attached to the PullRequest | ||
# | ||
# Therefore ensure that the Label exists for the corresponding repository | ||
# | ||
# Then ensure the Label is attached to this PullRequest by checking the list | ||
# of attached Labels. Unfortunately this seems to be the only option | ||
# | ||
# If the list does not include the given Label we attach it | ||
|
||
def ensure_label_is_attached(label) | ||
repository.ensure_label_exists(label) | ||
|
||
attached_labels = Github.client.labels_for_issue(gh_repository_id, number) | ||
return if attached_labels.any? { |attached_label| attached_label['name'] == label.name } | ||
|
||
Github.client.add_labels_to_an_issue(gh_repository_id, number, [label.name]) | ||
end | ||
|
||
## | ||
# We simply remove the given Label if it exists | ||
|
||
def ensure_label_is_detached(label) | ||
Github.client.remove_label(gh_repository_id, number, label.name) | ||
end | ||
|
||
## | ||
# if the PullRequest is mergeable we need to check if the 'needs-rebase' Label | ||
# is attached. If so, we need to remove it. | ||
# | ||
# If the PullRequest is not yet mergeable we need to attach the 'needs-rebase' | ||
# Label. Therefore we also need to check if the Label exists on repository level. | ||
# | ||
# The saved_changes variable includes all the stuff that has changed. | ||
# We currently don't care about them | ||
|
||
def validate(_saved_changes) | ||
if mergeable | ||
ensure_label_is_detached(Label.needs_rebase) | ||
else | ||
repository.ensure_label_exists(Label.needs_rebase) | ||
ensure_label_is_attached(label) | ||
end | ||
end | ||
|
||
private | ||
|
||
## | ||
# Since we want to be a fancy responsive application we to all the validation | ||
# stuff which might result in some new querys and api requests asyncronously. | ||
|
||
def queue_validation | ||
ValidatePullRequestWorker.perform_async(id, saved_changes) if saved_changes? | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
class ValidatePullRequestWorker | ||
include Sidekiq::Worker | ||
|
||
## | ||
# As validation may take a bit more time we do it async. | ||
# This worker is not meant to hold any logic but only trigger the | ||
# validation in its asyncronous context. | ||
|
||
def perform(id, saved_changes) | ||
PullRequest.find(id).validate(saved_changes) | ||
end | ||
end |
7 changes: 7 additions & 0 deletions
7
db/migrate/20190730094710_add_mergeable_and_gh_repo_id_to_pull_requests.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
class AddMergeableAndGhRepoIdToPullRequests < ActiveRecord::Migration[5.2] | ||
def change | ||
add_column :pull_requests, :mergeable, :boolean | ||
add_column :pull_requests, :gh_repository_id, :integer | ||
add_column :pull_requests, :github_id, :integer | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters