shipit-engine 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +41 -37
- data/app/assets/javascripts/task/tty.js.coffee +40 -22
- data/app/assets/stylesheets/_pages/_deploy.scss +1 -0
- data/app/controllers/shipit/api/locks_controller.rb +3 -3
- data/app/controllers/shipit/api/stacks_controller.rb +14 -1
- data/app/controllers/shipit/commit_checks_controller.rb +9 -2
- data/app/controllers/shipit/shipit_controller.rb +1 -1
- data/app/controllers/shipit/stacks_controller.rb +11 -5
- data/app/controllers/shipit/status_controller.rb +1 -1
- data/app/controllers/shipit/webhooks_controller.rb +15 -5
- data/app/helpers/shipit/deploys_helper.rb +1 -1
- data/app/helpers/shipit/shipit_helper.rb +2 -0
- data/app/jobs/shipit/perform_commit_checks_job.rb +2 -0
- data/app/jobs/shipit/perform_task_job.rb +18 -8
- data/app/models/shipit/commit.rb +22 -12
- data/app/models/shipit/commit_checks.rb +20 -53
- data/app/models/shipit/deploy.rb +1 -1
- data/app/models/shipit/ephemeral_commit_checks.rb +76 -0
- data/app/models/shipit/stack.rb +40 -10
- data/app/models/shipit/status.rb +14 -8
- data/app/models/shipit/status_group.rb +1 -1
- data/app/models/shipit/task.rb +2 -0
- data/app/models/shipit/unknown_status.rb +4 -0
- data/app/models/shipit/user.rb +9 -1
- data/app/serializers/shipit/stack_serializer.rb +6 -1
- data/app/views/shipit/commit_checks/_checks.html.erb +13 -0
- data/app/views/shipit/commit_checks/show.html.erb +5 -0
- data/app/views/shipit/stacks/_header.html.erb +1 -1
- data/app/views/shipit/stacks/show.html.erb +15 -0
- data/config/routes.rb +2 -1
- data/db/migrate/20140226233935_create_baseline.rb +10 -10
- data/db/migrate/20160802092812_add_continuous_delivery_delayed_since_to_stacks.rb +5 -0
- data/db/migrate/20160822131405_add_locked_since_to_stacks.rb +5 -0
- data/lib/shipit.rb +4 -0
- data/lib/shipit/command.rb +1 -1
- data/lib/shipit/commands.rb +10 -7
- data/lib/shipit/csv_serializer.rb +1 -1
- data/lib/shipit/stack_commands.rb +17 -5
- data/lib/shipit/task_commands.rb +2 -2
- data/lib/shipit/version.rb +1 -1
- data/lib/snippets/push-to-heroku +20 -16
- data/test/controllers/api/deploys_controller_test.rb +8 -8
- data/test/controllers/api/hooks_controller_test.rb +11 -9
- data/test/controllers/api/locks_controller_test.rb +16 -6
- data/test/controllers/api/outputs_controller_test.rb +1 -1
- data/test/controllers/api/stacks_controller_test.rb +48 -3
- data/test/controllers/api/tasks_controller_test.rb +6 -6
- data/test/controllers/commit_checks_controller_test.rb +3 -3
- data/test/controllers/deploys_controller_test.rb +13 -13
- data/test/controllers/rollbacks_controller_test.rb +7 -7
- data/test/controllers/stacks_controller_test.rb +36 -29
- data/test/controllers/tasks_controller_test.rb +14 -14
- data/test/controllers/webhooks_controller_test.rb +16 -25
- data/test/dummy/config/application.rb +0 -3
- data/test/dummy/config/environments/test.rb +2 -2
- data/test/dummy/data/stacks/byroot/junk/production/git/bar.txt +2 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/bin/slow +7 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/bin/timeout +10 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/dkfdsf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/dskjfsd +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/dslkjfjsdf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/plopfizz +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/sd +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/sdkfjsdf +1 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/sdlfjsdfdsfj +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/sdlkfjsdlkfjsdlkfjdsfsdfksdfjsldkfjsdlkfjsdf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/shipit.yml +21 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/toto.txt +2 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +15 -13
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/fixtures/shipit/commit_deployments.yml +8 -8
- data/test/fixtures/shipit/output_chunks.yml +12 -12
- data/test/fixtures/shipit/tasks.yml +9 -1
- data/test/fixtures/shipit/users.yml +9 -2
- data/test/jobs/perform_task_job_test.rb +14 -11
- data/test/models/commits_test.rb +33 -14
- data/test/models/stacks_test.rb +78 -4
- data/test/models/users_test.rb +16 -0
- data/test/unit/commands_test.rb +4 -0
- data/test/unit/deploy_commands_test.rb +1 -1
- metadata +133 -34
- data/app/jobs/shipit/git_mirror_update_job.rb +0 -14
- data/app/views/shipit/deploys/_checks.html.erb +0 -11
@@ -42,7 +42,7 @@ module Shipit
|
|
42
42
|
teams = Shipit.github_teams
|
43
43
|
unless teams.empty? || current_user.teams.where(id: teams).exists?
|
44
44
|
team_list = teams.map(&:handle).to_sentence(two_words_connector: ' or ', last_word_connector: ', or ')
|
45
|
-
render
|
45
|
+
render plain: "You must be a member of #{team_list} to access this application.", status: :forbidden
|
46
46
|
end
|
47
47
|
else
|
48
48
|
redirect_to Shipit::Engine.routes.url_helpers.github_authentication_path(origin: request.original_url)
|
@@ -45,7 +45,7 @@ module Shipit
|
|
45
45
|
RefreshStatusesJob.perform_later(stack_id: @stack.id)
|
46
46
|
GithubSyncJob.perform_later(stack_id: @stack.id)
|
47
47
|
flash[:success] = 'Refresh scheduled'
|
48
|
-
redirect_to request.referer
|
48
|
+
redirect_to request.referer.presence || stack_path(@stack)
|
49
49
|
end
|
50
50
|
|
51
51
|
def update
|
@@ -53,6 +53,14 @@ module Shipit
|
|
53
53
|
unless @stack.update(update_params)
|
54
54
|
options = {flash: {warning: @stack.errors.full_messages.to_sentence}}
|
55
55
|
end
|
56
|
+
|
57
|
+
reason = params[:stack][:lock_reason]
|
58
|
+
if reason.present?
|
59
|
+
@stack.lock(reason, current_user)
|
60
|
+
elsif @stack.locked?
|
61
|
+
@stack.unlock
|
62
|
+
end
|
63
|
+
|
56
64
|
redirect_to(params[:return_to].presence || stack_settings_path(@stack), options)
|
57
65
|
end
|
58
66
|
|
@@ -77,10 +85,8 @@ module Shipit
|
|
77
85
|
end
|
78
86
|
|
79
87
|
def update_params
|
80
|
-
params.require(:stack).permit(:deploy_url, :
|
81
|
-
:continuous_deployment, :ignore_ci)
|
82
|
-
params[:lock_author_id] = params[:lock_reason].present? ? current_user.id : nil
|
83
|
-
end
|
88
|
+
params.require(:stack).permit(:deploy_url, :environment,
|
89
|
+
:continuous_deployment, :ignore_ci)
|
84
90
|
end
|
85
91
|
end
|
86
92
|
end
|
@@ -9,17 +9,27 @@ module Shipit
|
|
9
9
|
|
10
10
|
if branch == stack.branch
|
11
11
|
GithubSyncJob.perform_later(stack_id: stack.id)
|
12
|
-
GitMirrorUpdateJob.perform_later(stack)
|
13
12
|
end
|
14
13
|
|
15
14
|
head :ok
|
16
15
|
end
|
17
16
|
|
17
|
+
params do
|
18
|
+
requires :sha, String
|
19
|
+
requires :state, String
|
20
|
+
accepts :description, String
|
21
|
+
accepts :target_url, String
|
22
|
+
accepts :context, String
|
23
|
+
accepts :created_at, String
|
24
|
+
|
25
|
+
accepts :branches, Array do
|
26
|
+
requires :name, String
|
27
|
+
end
|
28
|
+
end
|
18
29
|
def state
|
19
|
-
|
20
|
-
|
21
|
-
commit
|
22
|
-
commit.add_status(params.permit(:state, :description, :target_url, :context, :created_at))
|
30
|
+
if params.branches.map(&:name).include?(stack.branch)
|
31
|
+
commit = stack.commits.find_by_sha!(params.sha)
|
32
|
+
commit.create_status_from_github!(params)
|
23
33
|
end
|
24
34
|
head :ok
|
25
35
|
end
|
@@ -36,6 +36,8 @@ module Shipit
|
|
36
36
|
If you haven't created an application on GitHub yet, you can do so in the
|
37
37
|
#{link_to 'Settings', Shipit.github_url('/settings/applications/new'), target: '_blank'}
|
38
38
|
section of your profile. You can also create applications for organizations.
|
39
|
+
When setting up your application in Github, set the Homepage URL to your domain
|
40
|
+
and the Authorization callback URL to '<yourdomain>/github/auth/github/callback'.
|
39
41
|
MESSAGE
|
40
42
|
end
|
41
43
|
|
@@ -53,24 +53,26 @@ module Shipit
|
|
53
53
|
|
54
54
|
def perform_task
|
55
55
|
Bundler.with_clean_env do
|
56
|
-
capture_all @commands.install_dependencies
|
57
|
-
capture_all @commands.perform
|
56
|
+
capture_all! @commands.install_dependencies
|
57
|
+
capture_all! @commands.perform
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
61
|
def checkout_repository
|
62
62
|
@task.acquire_git_cache_lock do
|
63
|
-
capture @commands.
|
64
|
-
|
63
|
+
unless capture @commands.fetched?(@task.until_commit)
|
64
|
+
capture! @commands.fetch
|
65
|
+
end
|
65
66
|
end
|
66
|
-
capture @commands.
|
67
|
+
capture! @commands.clone
|
68
|
+
capture! @commands.checkout(@task.until_commit)
|
67
69
|
end
|
68
70
|
|
69
|
-
def capture_all(commands)
|
70
|
-
commands.map { |c| capture(c) }
|
71
|
+
def capture_all!(commands)
|
72
|
+
commands.map { |c| capture!(c) }
|
71
73
|
end
|
72
74
|
|
73
|
-
def capture(command)
|
75
|
+
def capture!(command)
|
74
76
|
command.start do
|
75
77
|
@task.ping
|
76
78
|
check_for_abort
|
@@ -81,6 +83,14 @@ module Shipit
|
|
81
83
|
@task.write(line)
|
82
84
|
end
|
83
85
|
@task.write("\n")
|
86
|
+
command.success?
|
87
|
+
end
|
88
|
+
|
89
|
+
def capture(command)
|
90
|
+
capture!(command)
|
91
|
+
command.success?
|
92
|
+
rescue Command::Error
|
93
|
+
false
|
84
94
|
end
|
85
95
|
end
|
86
96
|
end
|
data/app/models/shipit/commit.rb
CHANGED
@@ -82,22 +82,14 @@ module Shipit
|
|
82
82
|
def refresh_statuses!
|
83
83
|
github_statuses = stack.handle_github_redirections { Shipit.github_api.statuses(github_repo_name, sha) }
|
84
84
|
github_statuses.each do |status|
|
85
|
-
|
85
|
+
create_status_from_github!(status)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
92
|
-
reload # to get the statuses into the right order (since sorted :desc)
|
93
|
-
new_status = significant_status
|
94
|
-
|
95
|
-
payload = {commit: self, stack: stack, status: new_status.state}
|
96
|
-
Hook.emit(:commit_status, stack, payload.merge(commit_status: new_status)) if previous_status != new_status
|
97
|
-
if previous_status.simple_state != new_status.simple_state && !new_status.pending?
|
98
|
-
Hook.emit(:deployable_status, stack, payload.merge(deployable_status: new_status))
|
89
|
+
def create_status_from_github!(github_status)
|
90
|
+
add_status do
|
91
|
+
statuses.replicate_from_github!(github_status)
|
99
92
|
end
|
100
|
-
new_status
|
101
93
|
end
|
102
94
|
|
103
95
|
def checks
|
@@ -192,8 +184,26 @@ module Shipit
|
|
192
184
|
stack.last_deployed_commit.id >= id
|
193
185
|
end
|
194
186
|
|
187
|
+
def deploy_failed?
|
188
|
+
stack.deploys.unsuccessful.where(until_commit_id: id).any?
|
189
|
+
end
|
190
|
+
|
195
191
|
private
|
196
192
|
|
193
|
+
def add_status
|
194
|
+
previous_status = significant_status
|
195
|
+
yield
|
196
|
+
reload # to get the statuses into the right order (since sorted :desc)
|
197
|
+
new_status = significant_status
|
198
|
+
|
199
|
+
payload = {commit: self, stack: stack, status: new_status.state}
|
200
|
+
Hook.emit(:commit_status, stack, payload.merge(commit_status: new_status)) if previous_status != new_status
|
201
|
+
if previous_status.simple_state != new_status.simple_state && (!new_status.pending? || previous_status.unknown?)
|
202
|
+
Hook.emit(:deployable_status, stack, payload.merge(deployable_status: new_status))
|
203
|
+
end
|
204
|
+
new_status
|
205
|
+
end
|
206
|
+
|
197
207
|
def missing_statuses
|
198
208
|
stack.required_statuses - last_statuses.map(&:context)
|
199
209
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Shipit
|
2
|
-
class CommitChecks
|
2
|
+
class CommitChecks < EphemeralCommitChecks
|
3
3
|
OUTPUT_TTL = 10.minutes.to_i
|
4
4
|
FINAL_STATUSES = %w(failed error success).freeze
|
5
5
|
|
@@ -7,30 +7,28 @@ module Shipit
|
|
7
7
|
@commit = commit
|
8
8
|
end
|
9
9
|
|
10
|
-
def
|
11
|
-
|
12
|
-
|
13
|
-
commands.with_temporary_working_directory(commit: commit) do |directory|
|
14
|
-
deploy_spec = DeploySpec::FileSystem.new(directory, stack.environment)
|
15
|
-
Bundler.with_clean_env do
|
16
|
-
capture_all(build_commands(deploy_spec.dependencies_steps, chdir: directory))
|
17
|
-
capture_all(build_commands(deploy_spec.review_checks, chdir: directory))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
rescue Command::Error
|
21
|
-
self.status = 'failed'
|
22
|
-
rescue
|
23
|
-
self.status = 'error'
|
24
|
-
raise
|
25
|
-
else
|
26
|
-
self.status = 'success'
|
10
|
+
def synchronize(&block)
|
11
|
+
@lock ||= Redis::Lock.new('lock', redis, expiration: 1, timeout: 2)
|
12
|
+
@lock.lock(&block)
|
27
13
|
end
|
28
14
|
|
29
15
|
def schedule
|
30
|
-
if redis.
|
31
|
-
|
32
|
-
|
16
|
+
return false if redis.get('status').present?
|
17
|
+
synchronize do
|
18
|
+
return false if redis.get('status').present?
|
19
|
+
|
20
|
+
initialize_redis_state
|
21
|
+
end
|
22
|
+
PerformCommitChecksJob.perform_later(commit: commit)
|
23
|
+
true
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize_redis_state
|
27
|
+
redis.pipelined do
|
28
|
+
redis.set('output', '', ex: OUTPUT_TTL)
|
29
|
+
redis.set('status', 'scheduled', ex: OUTPUT_TTL)
|
33
30
|
end
|
31
|
+
@status = 'scheduled'
|
34
32
|
end
|
35
33
|
|
36
34
|
def status
|
@@ -38,14 +36,10 @@ module Shipit
|
|
38
36
|
end
|
39
37
|
|
40
38
|
def status=(status)
|
41
|
-
redis.set('status', status
|
39
|
+
redis.set('status', status)
|
42
40
|
@status = status
|
43
41
|
end
|
44
42
|
|
45
|
-
def finished?
|
46
|
-
FINAL_STATUSES.include?(status)
|
47
|
-
end
|
48
|
-
|
49
43
|
def output(since: 0)
|
50
44
|
redis.getrange('output', since, -1)
|
51
45
|
end
|
@@ -56,35 +50,8 @@ module Shipit
|
|
56
50
|
|
57
51
|
private
|
58
52
|
|
59
|
-
def build_commands(commands, chdir:)
|
60
|
-
commands.map { |c| Command.new(c, env: Shipit.env, chdir: chdir) }
|
61
|
-
end
|
62
|
-
|
63
|
-
def capture_all(commands)
|
64
|
-
commands.map { |c| capture(c) }
|
65
|
-
end
|
66
|
-
|
67
|
-
def capture(command)
|
68
|
-
command.start
|
69
|
-
write("$ #{command}\n")
|
70
|
-
command.stream! do |line|
|
71
|
-
write(line)
|
72
|
-
end
|
73
|
-
rescue Command::Error => error
|
74
|
-
write(error.message)
|
75
|
-
raise
|
76
|
-
ensure
|
77
|
-
write("\n")
|
78
|
-
end
|
79
|
-
|
80
|
-
attr_reader :commit
|
81
|
-
|
82
53
|
def redis
|
83
54
|
@redis ||= Shipit.redis("commit:#{commit.id}:checks")
|
84
55
|
end
|
85
|
-
|
86
|
-
def stack
|
87
|
-
@stack ||= commit.stack
|
88
|
-
end
|
89
56
|
end
|
90
57
|
end
|
data/app/models/shipit/deploy.rb
CHANGED
@@ -0,0 +1,76 @@
|
|
1
|
+
module Shipit
|
2
|
+
class EphemeralCommitChecks
|
3
|
+
FINAL_STATUSES = %w(failed error success).freeze
|
4
|
+
|
5
|
+
def initialize(commit)
|
6
|
+
@commit = commit
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :status
|
10
|
+
attr_reader :output
|
11
|
+
|
12
|
+
def run
|
13
|
+
self.status = 'running'
|
14
|
+
commands = StackCommands.new(stack)
|
15
|
+
commands.with_temporary_working_directory(commit: commit) do |directory|
|
16
|
+
deploy_spec = DeploySpec::FileSystem.new(directory, stack.environment)
|
17
|
+
Bundler.with_clean_env do
|
18
|
+
capture_all(build_commands(deploy_spec.dependencies_steps, chdir: directory))
|
19
|
+
capture_all(build_commands(deploy_spec.review_checks, chdir: directory))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
self
|
23
|
+
rescue Command::Error
|
24
|
+
self.status = 'failed'
|
25
|
+
self
|
26
|
+
rescue
|
27
|
+
self.status = 'error'
|
28
|
+
raise
|
29
|
+
else
|
30
|
+
self.status = 'success'
|
31
|
+
self
|
32
|
+
end
|
33
|
+
|
34
|
+
def success?
|
35
|
+
status == 'success'
|
36
|
+
end
|
37
|
+
|
38
|
+
def finished?
|
39
|
+
FINAL_STATUSES.include?(status)
|
40
|
+
end
|
41
|
+
|
42
|
+
def write(output)
|
43
|
+
@output ||= ''
|
44
|
+
@output += output
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def build_commands(commands, chdir:)
|
50
|
+
commands.map { |c| Command.new(c, env: Shipit.env, chdir: chdir) }
|
51
|
+
end
|
52
|
+
|
53
|
+
def capture_all(commands)
|
54
|
+
commands.map { |c| capture(c) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def capture(command)
|
58
|
+
command.start
|
59
|
+
write("$ #{command}\n")
|
60
|
+
command.stream! do |line|
|
61
|
+
write(line)
|
62
|
+
end
|
63
|
+
rescue Command::Error => error
|
64
|
+
write(error.message)
|
65
|
+
raise
|
66
|
+
ensure
|
67
|
+
write("\n")
|
68
|
+
end
|
69
|
+
|
70
|
+
attr_reader :commit
|
71
|
+
|
72
|
+
def stack
|
73
|
+
@stack ||= commit.stack
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/app/models/shipit/stack.rb
CHANGED
@@ -58,6 +58,7 @@ module Shipit
|
|
58
58
|
validates :repo_owner, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: REPO_OWNER_MAX_SIZE}
|
59
59
|
validates :repo_name, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: REPO_NAME_MAX_SIZE}
|
60
60
|
validates :environment, format: {with: /\A[a-z0-9\-_\:]+\z/}, length: {maximum: ENVIRONMENT_MAX_SIZE}
|
61
|
+
validates :deploy_url, format: {with: URI.regexp(%w(http https ssh))}, allow_blank: true
|
61
62
|
|
62
63
|
validates :lock_reason, length: {maximum: 4096}
|
63
64
|
|
@@ -86,7 +87,7 @@ module Shipit
|
|
86
87
|
definition: find_task_definition(definition_id),
|
87
88
|
until_commit_id: commit.id,
|
88
89
|
since_commit_id: commit.id,
|
89
|
-
env: filter_task_envs(definition_id, (env || {})),
|
90
|
+
env: filter_task_envs(definition_id, (env.try!(:to_h) || {})),
|
90
91
|
)
|
91
92
|
task.enqueue
|
92
93
|
task
|
@@ -98,7 +99,7 @@ module Shipit
|
|
98
99
|
user_id: user.id,
|
99
100
|
until_commit: until_commit,
|
100
101
|
since_commit: since_commit,
|
101
|
-
env: filter_deploy_envs(env || {}),
|
102
|
+
env: filter_deploy_envs(env.try!(:to_h) || {}),
|
102
103
|
)
|
103
104
|
end
|
104
105
|
|
@@ -106,17 +107,36 @@ module Shipit
|
|
106
107
|
deploy = build_deploy(*args)
|
107
108
|
deploy.save!
|
108
109
|
deploy.enqueue
|
110
|
+
continuous_delivery_resumed!
|
109
111
|
deploy
|
110
112
|
end
|
111
113
|
|
114
|
+
def continuous_delivery_resumed!
|
115
|
+
update!(continuous_delivery_delayed_since: nil)
|
116
|
+
end
|
117
|
+
|
118
|
+
def continuous_delivery_delayed?
|
119
|
+
continuous_delivery_delayed_since? && continuous_deployment? && checks?
|
120
|
+
end
|
121
|
+
|
122
|
+
def continuous_delivery_delayed!
|
123
|
+
touch(:continuous_delivery_delayed_since, :updated_at) unless continuous_delivery_delayed?
|
124
|
+
end
|
125
|
+
|
112
126
|
def trigger_continuous_delivery
|
113
|
-
|
114
|
-
return if deployed_too_recently?
|
127
|
+
commit = next_commit_to_deploy
|
115
128
|
|
116
|
-
if commit
|
117
|
-
|
118
|
-
|
129
|
+
if !deployable? || deployed_too_recently? || commit.nil? || commit.deployed?
|
130
|
+
continuous_delivery_resumed!
|
131
|
+
return
|
119
132
|
end
|
133
|
+
|
134
|
+
if commit.deploy_failed? || (checks? && !EphemeralCommitChecks.new(commit).run.success?)
|
135
|
+
continuous_delivery_delayed!
|
136
|
+
return
|
137
|
+
end
|
138
|
+
|
139
|
+
trigger_deploy(commit, Shipit.user)
|
120
140
|
end
|
121
141
|
|
122
142
|
def next_commit_to_deploy
|
@@ -183,7 +203,7 @@ module Shipit
|
|
183
203
|
end
|
184
204
|
|
185
205
|
def last_successful_deploy
|
186
|
-
deploys_and_rollbacks.success.
|
206
|
+
deploys_and_rollbacks.success.last
|
187
207
|
end
|
188
208
|
|
189
209
|
def last_active_task
|
@@ -238,12 +258,12 @@ module Shipit
|
|
238
258
|
File.join(base_path, "git")
|
239
259
|
end
|
240
260
|
|
241
|
-
def acquire_git_cache_lock(timeout: 15, &block)
|
261
|
+
def acquire_git_cache_lock(timeout: 15, expiration: 60, &block)
|
242
262
|
Redis::Lock.new(
|
243
263
|
"stack:#{id}:git-cache-lock",
|
244
264
|
Shipit.redis,
|
245
265
|
timeout: timeout,
|
246
|
-
expiration:
|
266
|
+
expiration: expiration,
|
247
267
|
).lock(&block)
|
248
268
|
end
|
249
269
|
|
@@ -298,6 +318,16 @@ module Shipit
|
|
298
318
|
lock_reason.present?
|
299
319
|
end
|
300
320
|
|
321
|
+
def lock(reason, user)
|
322
|
+
params = {lock_reason: reason, lock_author: user}
|
323
|
+
params[:locked_since] = Time.current if locked_since.nil?
|
324
|
+
update!(params)
|
325
|
+
end
|
326
|
+
|
327
|
+
def unlock
|
328
|
+
update!(lock_reason: nil, lock_author: nil, locked_since: nil)
|
329
|
+
end
|
330
|
+
|
301
331
|
def to_param
|
302
332
|
[repo_owner, repo_name, environment].join('/')
|
303
333
|
end
|