Skip to content

Commit

Permalink
Create a GitHub deployment for the batch head
Browse files Browse the repository at this point in the history
  • Loading branch information
DazWorrall committed Jan 9, 2020
1 parent 826e578 commit 99a698d
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 41 deletions.
27 changes: 27 additions & 0 deletions app/jobs/shipit/create_deployments_for_task_job.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Shipit
class CreateDeploymentsForTaskJob < BackgroundJob
include BackgroundJob::Unique

queue_as :default

def perform(task)
# Create one deployment for the head of the batch
task.commit_deployments.create!(sha: task.until_commit.sha)

# Create one for each pull request in the batch, to give feedback on the PR timeline
task.commits.select(&:pull_request?).each do |commit|
task.commit_deployments.create!(sha: pull_request_head_for_commit(commit))
end

# Immediately update to publish the status to the commit deployments
task.update_commit_deployments
end

private

def pull_request_head_for_commit(commit)
pull_request = Shipit.github.api.pull_request(commit.stack.github_repo_name, commit.pull_request_number)
pull_request.head.sha
end
end
end
10 changes: 1 addition & 9 deletions app/models/shipit/commit_deployment.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module Shipit
class CommitDeployment < ActiveRecord::Base
belongs_to :commit
belongs_to :task
has_many :statuses, dependent: :destroy, class_name: 'CommitDeploymentStatus'

Expand All @@ -9,8 +8,6 @@ class CommitDeployment < ActiveRecord::Base
delegate :stack, :author, to: :task

def create_on_github!
return unless commit.pull_request?

create_deployment_on_github!
statuses.order(id: :asc).each(&:create_on_github!)
rescue Octokit::NotFound, Octokit::Forbidden
Expand All @@ -34,11 +31,6 @@ def create_deployment_on_github!
update!(github_id: response.id, api_url: response.url)
end

def pull_request_head
pull_request = Shipit.github.api.pull_request(stack.github_repo_name, commit.pull_request_number)
pull_request.head.sha
end

def schedule_create_on_github
CreateOnGithubJob.perform_later(self)
end
Expand All @@ -48,7 +40,7 @@ def schedule_create_on_github
def create_deployment_on_github(client)
client.create_deployment(
stack.github_repo_name,
pull_request_head,
sha,
auto_merge: false,
required_contexts: [],
description: "Via #{Shipit.app_name}",
Expand Down
15 changes: 5 additions & 10 deletions app/models/shipit/deploy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,15 +217,14 @@ def report_faulty!(user: self.user, description: "@#{user.login} signaled this r
end
end

def update_commit_deployments
commit_deployments.append_status(status)
end

private

def create_commit_deployments
commits.each do |commit|
commit_deployments.create!(commit: commit)
end

# Immediately update to publish the status to the commit deployments
update_commit_deployments
CreateDeploymentsForTaskJob.perform_later(self)
end

def update_release_status
Expand All @@ -250,10 +249,6 @@ def update_release_status
end
end

def update_commit_deployments
commit_deployments.append_status(status)
end

def trigger_revert_if_required
return unless rollback_once_aborted?
return unless supports_rollback?
Expand Down
7 changes: 7 additions & 0 deletions db/migrate/20200109132519_add_sha_to_commit_deployments.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
class AddShaToCommitDeployments < ActiveRecord::Migration[6.0]
def change
add_column :commit_deployments, :sha, :string, limit: 40
add_index :commit_deployments, :sha
add_index :commit_deployments, [:task_id, :sha], unique: true
end
end
5 changes: 4 additions & 1 deletion test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2020_01_02_175621) do
ActiveRecord::Schema.define(version: 2020_01_09_132519) do

create_table "api_clients", force: :cascade do |t|
t.text "permissions", limit: 65535
Expand Down Expand Up @@ -55,7 +55,10 @@
t.string "api_url"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "sha", limit: 40
t.index ["commit_id", "task_id"], name: "index_commit_deployments_on_commit_id_and_task_id", unique: true
t.index ["sha"], name: "index_commit_deployments_on_sha"
t.index ["task_id", "sha"], name: "index_commit_deployments_on_task_id_and_sha", unique: true
t.index ["task_id"], name: "index_commit_deployments_on_task_id"
end

Expand Down
2 changes: 2 additions & 0 deletions test/dummy/db/seeds.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ module Shipit
Commit.send(:define_method, :refresh_statuses!) {}
Commit.send(:define_method, :refresh_check_runs!) {}
ReleaseStatus.send(:define_method, :create_status_on_github!) {}
CommitDeployment.send(:define_method, :schedule_create_on_github) {}
CommitDeploymentStatus.send(:define_method, :schedule_create_on_github) {}

users = 3.times.map do
User.create!(
Expand Down
16 changes: 8 additions & 8 deletions test/fixtures/shipit/commit_deployments.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,37 @@
shipit_deploy_second:
commit_id: 2 # second
sha: f890fd8b5f2be05d1fedb763a3605ee461c39074 # second
task_id: 1 # shipit
api_url: https://api.github.com/repos/shopify/shipit-engine/deployments/1
github_id: 1

shipit2_deploy_third:
commit_id: 3 # third
sha: 367578b362bf2b4df5903e1c7960929361c39074 # third
task_id: 2 # shipit2
api_url: https://api.github.com/repos/shopify/shipit-engine/deployments/2
github_id: 2

shipit_pending_third:
commit_id: 3 # third
sha: 367578b362bf2b4df5903e1c7960929361c39074 # third
task_id: 4 # shipit_pending
api_url: https://api.github.com/repos/shopify/shipit-engine/deployments/3
github_id: 3

shipit_pending_fourth:
commit_id: 4 # fourth
sha: 467578b362bf2b4df5903e1c7960929361c3435a # fourth
task_id: 4 # shipit_pending

shipit_running_fourth:
commit_id: 4 # fourth
sha: 467578b362bf2b4df5903e1c7960929361c3435a # fourth
task_id: 5 # shipit_running

shipit_complete_fourth:
commit_id: 4 # fourth
sha: 467578b362bf2b4df5903e1c7960929361c3435a # fourth
task_id: 6 # shipit_complete

shipit_aborted_fourth:
commit_id: 4 # fourth
sha: 467578b362bf2b4df5903e1c7960929361c3435a # fourth
task_id: 7 # shipit_aborted

shipit_rollback_fourth:
commit_id: 4 # fourth
sha: 467578b362bf2b4df5903e1c7960929361c3435a # fourth
task_id: 8 # shipit_rollback
25 changes: 25 additions & 0 deletions test/jobs/create_deployments_for_task_job_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require 'test_helper'

module Shipit
class CreateDeploymentsForTaskJobTest < ActiveSupport::TestCase
setup do
@task = shipit_tasks(:shipit_pending)
@task.commit_deployments.delete_all
end

test "creates one CommitDeployment and status per commit, and one more for the batch head" do
pull_request_response = stub(head: stub(sha: '6dcb09b5b57875f334f61aebed695e2e4193db5e'))
Shipit.github.api.expects(:pull_request).with('shopify/shipit-engine', 7).returns(pull_request_response)

expected_delta = @task.commits.select(&:pull_request?).size + 1
assert_difference -> { CommitDeployment.count }, expected_delta do
assert_difference -> { CommitDeploymentStatus.count }, expected_delta do
CreateDeploymentsForTaskJob.perform_now(@task)
end
end

refute_nil CommitDeployment.find_by(sha: '6dcb09b5b57875f334f61aebed695e2e4193db5e')
refute_nil CommitDeployment.find_by(sha: @task.until_commit.sha)
end
end
end
3 changes: 1 addition & 2 deletions test/models/commit_deployment_status_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ class CommitDeploymentStatusTest < ActiveSupport::TestCase
@status = shipit_commit_deployment_statuses(:shipit2_deploy_third_in_progress)
@deployment = @status.commit_deployment
@task = @deployment.task
@commit = @deployment.commit
@author = @deployment.author
end

Expand All @@ -17,7 +16,7 @@ class CommitDeploymentStatusTest < ActiveSupport::TestCase
'in_progress',
accept: "application/vnd.github.flash-preview+json",
target_url: "http://shipit.com/shopify/shipit-engine/production/deploys/#{@task.id}",
description: "walrus triggered the deploy of shopify/shipit-engine/production to #{@commit.sha}",
description: "walrus triggered the deploy of shopify/shipit-engine/production to #{@deployment.sha}",
).returns(response)

@status.create_on_github!
Expand Down
8 changes: 2 additions & 6 deletions test/models/commit_deployment_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,22 @@ module Shipit
class CommitDeploymentTest < ActiveSupport::TestCase
setup do
@deployment = shipit_commit_deployments(:shipit_pending_fourth)
@commit = @deployment.commit
@task = @deployment.task
@stack = @task.stack
@author = @deployment.author
end

test "there can only be one record per deploy and commit pair" do
assert_raises ActiveRecord::RecordNotUnique do
CommitDeployment.create!(task: @deployment.task, commit: @deployment.commit)
CommitDeployment.create!(task: @deployment.task, sha: @deployment.sha)
end
end

test "creation on GitHub" do
pull_request_response = stub(head: stub(sha: '6dcb09b5b57875f334f61aebed695e2e4193db5e'))
@author.github_api.expects(:pull_request).with('shopify/shipit-engine', 7).returns(pull_request_response)

deployment_response = stub(id: 42, url: 'https://example.com')
@author.github_api.expects(:create_deployment).with(
'shopify/shipit-engine',
pull_request_response.head.sha,
@deployment.sha,
auto_merge: false,
required_contexts: [],
description: "Via Shipit",
Expand Down
8 changes: 3 additions & 5 deletions test/models/deploys_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,17 +300,15 @@ def setup
end
end

test "creating a deploy creates one CommitDeployment and status per commit" do
test 'create enqueues CreateDeploymentsForTaskJob' do
shipit = shipit_stacks(:shipit)
deploy = shipit.deploys.build(
since_commit: shipit.commits.first,
until_commit: shipit.commits.last,
)

assert_difference -> { CommitDeployment.count }, deploy.commits.size do
assert_difference -> { CommitDeploymentStatus.count }, deploy.commits.size do
deploy.save!
end
assert_enqueued_with(job: CreateDeploymentsForTaskJob, args: [deploy]) do
deploy.save!
end
end

Expand Down

0 comments on commit 99a698d

Please sign in to comment.