shipit-engine 0.40.1 → 0.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 331361f1d585cf851921f54504a49c6ffb6f608a5ed27d5debcba8ee53e4e908
4
- data.tar.gz: 753f0e91f16d3f67f31b97ce13a2064db558c480329e15bac53f349d0c673f95
3
+ metadata.gz: bafbe17c7fb151098a26f705e72fa102d72a160525954fabfddb40cfaf5e102c
4
+ data.tar.gz: 65971811403084320352425fea9a55a6ab013e9ab45d6ee2db2b1db2d2be589e
5
5
  SHA512:
6
- metadata.gz: f8f620eb8c8740c6ffe92aa8636a52ddc3892b025471b7fbf9303cc6a6978c2b08fa0740ab3a1b0ee09bf6ba8cb8c53a8f1b5f027268759d76f4ad50a359d04f
7
- data.tar.gz: 7e714cb2899659ebbc72f64f56985af7ca09be4fdc22cbe281e2e53b3e5aacce8cbdf030049d873cac644d28bbdba4fcee00c25f4ed1c66ba0101e94f72e9ffb
6
+ metadata.gz: 72af323c05c61f27f55e7f7ec5f4cdadd3cd53b0399dd163e7ebbc2700f0eca8965d44ab502bb922e808e3b409fc6375fb96c9dc695b35f23aed82d0c9bee27d
7
+ data.tar.gz: c2d9c9fe1f7782cef895d38085611323ec29462022f02327124839245789b100a139b38def2e0def37645dae2eeddb369e81d45453b188660685369d1a8b611f
@@ -105,5 +105,13 @@ module Shipit
105
105
  def contributor_class(stacks_contributed_to, stack_id)
106
106
  stacks_contributed_to.include?(stack_id) ? "contributor" : "not-matching"
107
107
  end
108
+
109
+ def deployment_checks_message(stack)
110
+ if !stack.deployment_checks_passed? && Shipit.deployment_checks.respond_to?(:message)
111
+ Shipit.deployment_checks.message(stack)
112
+ else
113
+ "Deploys have been locked by an external system"
114
+ end
115
+ end
108
116
  end
109
117
  end
@@ -7,6 +7,8 @@ module Shipit
7
7
  attr_reader :stack
8
8
 
9
9
  MAX_FETCHED_COMMITS = 25
10
+ MAX_RETRY_ATTEMPTS = 5
11
+ RETRY_DELAY = 5.seconds
10
12
  queue_as :default
11
13
  on_duplicate :drop
12
14
 
@@ -15,10 +17,19 @@ module Shipit
15
17
 
16
18
  def perform(params)
17
19
  @stack = Stack.find(params[:stack_id])
20
+ expected_head_sha = params[:expected_head_sha]
21
+ retry_count = params[:retry_count] || 0
18
22
 
19
23
  handle_github_errors do
20
24
  new_commits, shared_parent = fetch_missing_commits { stack.github_commits }
21
25
 
26
+ # Retry on Github eventual consistency: webhook indicated new commits but we found none
27
+ if expected_head_sha && new_commits.empty? && !commit_exists?(expected_head_sha) &&
28
+ retry_count < MAX_RETRY_ATTEMPTS
29
+ GithubSyncJob.set(wait: RETRY_DELAY * retry_count).perform_later(params.merge(retry_count: retry_count + 1))
30
+ return
31
+ end
32
+
22
33
  stack.transaction do
23
34
  shared_parent&.detach_children!
24
35
  appended_commits = new_commits.map do |gh_commit|
@@ -63,5 +74,9 @@ module Shipit
63
74
  def lookup_commit(sha)
64
75
  stack.commits.find_by(sha:)
65
76
  end
77
+
78
+ def commit_exists?(sha)
79
+ stack.commits.exists?(sha:)
80
+ end
66
81
  end
67
82
  end
@@ -602,8 +602,8 @@ module Shipit
602
602
  tasks.where(type: 'Shipit::Deploy').success.order(id: :desc).limit(100).durations
603
603
  end
604
604
 
605
- def sync_github
606
- GithubSyncJob.perform_later(stack_id: id)
605
+ def sync_github(expected_head_sha: nil)
606
+ GithubSyncJob.perform_later(stack_id: id, expected_head_sha:)
607
607
  end
608
608
 
609
609
  def links
@@ -6,12 +6,14 @@ module Shipit
6
6
  class PushHandler < Handler
7
7
  params do
8
8
  requires :ref
9
+ requires :after
9
10
  end
11
+
10
12
  def process
11
13
  stacks
12
14
  .not_archived
13
15
  .where(branch:)
14
- .find_each(&:sync_github)
16
+ .find_each { |stack| stack.sync_github(expected_head_sha: params.after) }
15
17
  end
16
18
 
17
19
  private
@@ -4,7 +4,11 @@
4
4
  <%= render 'shipit/shared/author', author: commit.author %>
5
5
  <% end %>
6
6
 
7
- <%= render 'shipit/statuses/status', status: commit.status %>
7
+ <% if commit.status.group? %>
8
+ <%= render 'shipit/statuses/group', group: commit.status %>
9
+ <% else %>
10
+ <%= render 'shipit/statuses/status', status: commit.status %>
11
+ <% end %>
8
12
  <div class="commit-details">
9
13
  <span class="commit-title"><%= render_commit_message_with_link commit %></span>
10
14
  <p class="commit-meta">
@@ -76,4 +76,15 @@
76
76
  </div>
77
77
  </div>
78
78
  </div>
79
+ <% elsif !stack.deployment_checks_passed? %>
80
+ <div class="banner banner--orange">
81
+ <div class="banner__inner wrapper">
82
+ <div class="banner__content">
83
+ <h2 class="banner__title">Stack has been locked by external system!</h2>
84
+ <p class = "banner__text">
85
+ <%= simple_format(deployment_checks_message(stack)) %>
86
+ </p>
87
+ </div>
88
+ </div>
89
+ </div>
79
90
  <% end %>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Shipit
4
- VERSION = '0.40.1'
4
+ VERSION = '0.41.1'
5
5
  end
@@ -23,9 +23,11 @@ module Shipit
23
23
  test ":push with the target branch queues a GithubSyncJob" do
24
24
  request.headers['X-Github-Event'] = 'push'
25
25
 
26
- body = JSON.parse(payload(:push_master)).to_json
27
- assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
28
- post :create, body:, as: :json
26
+ parsed_body = JSON.parse(payload(:push_master))
27
+ expected_head_sha = parsed_body["after"]
28
+
29
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id, expected_head_sha:]) do
30
+ post :create, body: parsed_body.to_json, as: :json
29
31
  end
30
32
  end
31
33
 
@@ -118,5 +118,50 @@ module Shipit
118
118
 
119
119
  assert_equal true, @stack.reload.inaccessible_since?
120
120
  end
121
+
122
+ test "#perform retries when expected_head_sha is not found in the github response" do
123
+ expected_sha = "abcd1234"
124
+ Stack.any_instance.expects(:github_commits).returns(@github_commits)
125
+ @job.expects(:fetch_missing_commits).yields.returns([[], nil])
126
+ @job.expects(:commit_exists?).with(expected_sha).returns(false)
127
+
128
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id, expected_head_sha: expected_sha, retry_count: 1]) do
129
+ @job.perform(stack_id: @stack.id, expected_head_sha: expected_sha)
130
+ end
131
+ end
132
+
133
+ test "#perform stops retrying after MAX_RETRY_ATTEMPTS" do
134
+ expected_sha = "abcd1234"
135
+ Stack.any_instance.expects(:github_commits).returns(@github_commits)
136
+ @job.expects(:fetch_missing_commits).yields.returns([[], nil])
137
+ @job.expects(:commit_exists?).with(expected_sha).returns(false)
138
+
139
+ assert_no_enqueued_jobs(only: GithubSyncJob) do
140
+ @job.perform(stack_id: @stack.id, expected_head_sha: expected_sha, retry_count: GithubSyncJob::MAX_RETRY_ATTEMPTS)
141
+ end
142
+ end
143
+
144
+ test "#perform processes normally when expected_head_sha exists" do
145
+ expected_sha = "abcd1234"
146
+ Stack.any_instance.expects(:github_commits).returns(@github_commits)
147
+ @job.expects(:fetch_missing_commits).yields.returns([[], nil])
148
+ @job.expects(:commit_exists?).with(expected_sha).returns(true)
149
+
150
+ assert_enqueued_with(job: CacheDeploySpecJob, args: [@stack]) do
151
+ @job.perform(stack_id: @stack.id, expected_head_sha: expected_sha)
152
+ end
153
+ end
154
+
155
+ test "#perform processes normally when new commits are found" do
156
+ expected_sha = "abcd1234"
157
+ new_commit = stub(sha: expected_sha)
158
+ Stack.any_instance.expects(:github_commits).returns(@github_commits)
159
+ @job.expects(:fetch_missing_commits).yields.returns([[new_commit], nil])
160
+ @job.expects(:append_commit).with(new_commit).returns(stub(revert?: false))
161
+
162
+ assert_enqueued_with(job: CacheDeploySpecJob, args: [@stack]) do
163
+ @job.perform(stack_id: @stack.id, expected_head_sha: expected_sha)
164
+ end
165
+ end
121
166
  end
122
167
  end
@@ -70,7 +70,7 @@ module Shipit
70
70
  stack.archive!(shipit_users(:codertocat))
71
71
  end
72
72
 
73
- assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id]) do
73
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id, expected_head_sha: nil]) do
74
74
  stack.unarchive!
75
75
  end
76
76
  end
@@ -997,13 +997,13 @@ module Shipit
997
997
  @stack.archive!(shipit_users(:codertocat))
998
998
  end
999
999
 
1000
- assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
1000
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id, expected_head_sha: nil]) do
1001
1001
  @stack.unarchive!
1002
1002
  end
1003
1003
  end
1004
1004
 
1005
1005
  test "#update that changes the branch name triggers a GithubSync job" do
1006
- assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id]) do
1006
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: @stack.id, expected_head_sha: nil]) do
1007
1007
  @stack.update!(branch: 'test')
1008
1008
  end
1009
1009
  end
@@ -26,7 +26,7 @@ module Shipit
26
26
  scope: stack.repository.stacks
27
27
  )
28
28
 
29
- assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id]) do
29
+ assert_enqueued_with(job: GithubSyncJob, args: [stack_id: stack.id, expected_head_sha: nil]) do
30
30
  review_stack.unarchive!
31
31
  end
32
32
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module Shipit
6
+ class StackHelperTest < ActionView::TestCase
7
+ include Shipit::StacksHelper
8
+
9
+ def setup
10
+ @stack = shipit_stacks(:shipit)
11
+ end
12
+
13
+ test "deployment_checks_message default" do
14
+ assert_equal "Deploys have been locked by an external system", deployment_checks_message(@stack)
15
+ end
16
+
17
+ test "deployment_checks_message custom message" do
18
+ module FakeDeploymentCheck
19
+ extend self
20
+
21
+ def call(_stack)
22
+ false
23
+ end
24
+
25
+ def message(_stack)
26
+ "test message"
27
+ end
28
+ end
29
+ begin
30
+ original_deployment_checks = Shipit.deployment_checks
31
+ Shipit.deployment_checks = FakeDeploymentCheck
32
+ assert_equal "test message", deployment_checks_message(@stack)
33
+ ensure
34
+ Shipit.deployment_checks = original_deployment_checks
35
+ end
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shipit-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.40.1
4
+ version: 0.41.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
@@ -1023,6 +1023,7 @@ files:
1023
1023
  - test/unit/shipit_helper_test.rb
1024
1024
  - test/unit/shipit_task_execution_strategy_test.rb
1025
1025
  - test/unit/shipit_test.rb
1026
+ - test/unit/stack_helper_test.rb
1026
1027
  - test/unit/user_serializer_test.rb
1027
1028
  - test/unit/variable_definition_test.rb
1028
1029
  - vendor/assets/javascripts/clusterize.js
@@ -1050,7 +1051,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
1050
1051
  - !ruby/object:Gem::Version
1051
1052
  version: '0'
1052
1053
  requirements: []
1053
- rubygems_version: 3.7.1
1054
+ rubygems_version: 3.7.2
1054
1055
  specification_version: 4
1055
1056
  summary: Application deployment software
1056
1057
  test_files:
@@ -1254,5 +1255,6 @@ test_files:
1254
1255
  - test/unit/shipit_helper_test.rb
1255
1256
  - test/unit/shipit_task_execution_strategy_test.rb
1256
1257
  - test/unit/shipit_test.rb
1258
+ - test/unit/stack_helper_test.rb
1257
1259
  - test/unit/user_serializer_test.rb
1258
1260
  - test/unit/variable_definition_test.rb