shipit-engine 0.8.9 → 0.9.0
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 +4 -4
- data/app/assets/javascripts/shipit_bs.js.coffee +2 -0
- data/app/assets/javascripts/task.js.coffee +14 -5
- data/app/assets/javascripts/task/search_bar.js.coffee +52 -0
- data/app/assets/javascripts/task/stream.js.coffee +9 -2
- data/app/assets/javascripts/task/tty.js.coffee +75 -28
- data/app/assets/stylesheets/_base/_forms.scss +5 -0
- data/app/assets/stylesheets/_pages/_commits.scss +1 -1
- data/app/assets/stylesheets/_pages/_deploy.scss +56 -24
- data/app/assets/stylesheets/_pages/_settings.scss +5 -0
- data/app/assets/stylesheets/_structure/_layout.scss +1 -0
- data/app/assets/stylesheets/_structure/_main.scss +4 -0
- data/app/assets/stylesheets/shipit.scss +2 -0
- data/app/assets/stylesheets/shipit_bs.scss +22 -0
- data/app/controllers/shipit/deploys_controller.rb +5 -1
- data/app/controllers/shipit/shipit_controller.rb +10 -3
- data/app/controllers/shipit/stacks_controller.rb +12 -3
- data/app/controllers/shipit/tasks_controller.rb +4 -0
- data/app/helpers/shipit/shipit_helper.rb +18 -0
- data/app/helpers/shipit/stacks_helper.rb +1 -1
- data/app/jobs/shipit/cache_deploy_spec_job.rb +2 -0
- data/app/jobs/shipit/fetch_deployed_revision_job.rb +1 -0
- data/app/jobs/shipit/git_mirror_update_job.rb +2 -0
- data/app/jobs/shipit/perform_task_job.rb +1 -0
- data/app/models/shipit/commit.rb +2 -2
- data/app/models/shipit/deploy.rb +1 -1
- data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -1
- data/app/models/shipit/duration.rb +28 -0
- data/app/models/shipit/stack.rb +33 -11
- data/app/models/shipit/task.rb +26 -3
- data/app/serializers/shipit/task_serializer.rb +14 -1
- data/app/views/bootstrap/shipit/missing_settings.html.erb +97 -0
- data/app/views/bootstrap/shipit/stacks/new.html.erb +44 -0
- data/app/views/layouts/shipit.html.erb +1 -1
- data/app/views/layouts/shipit_bootstrap.html.erb +44 -0
- data/app/views/shipit/commits/_commit.html.erb +3 -2
- data/app/views/shipit/deploys/_deploy.html.erb +11 -2
- data/app/views/shipit/deploys/show.html.erb +1 -1
- data/app/views/shipit/stacks/new.html.erb +12 -12
- data/app/views/shipit/stacks/settings.html.erb +5 -0
- data/app/views/shipit/stacks/show.html.erb +1 -1
- data/app/views/shipit/tasks/_task.html.erb +10 -2
- data/app/views/shipit/tasks/_task_output.html.erb +11 -1
- data/app/views/shipit/tasks/show.html.erb +1 -1
- data/config/routes.rb +1 -0
- data/db/migrate/20160324155046_add_started_at_and_ended_at_on_tasks.rb +25 -0
- data/lib/shipit.rb +13 -0
- data/lib/shipit/command.rb +13 -9
- data/lib/shipit/engine.rb +8 -0
- data/lib/shipit/template_renderer_extension.rb +16 -0
- data/lib/shipit/version.rb +1 -1
- data/test/controllers/deploys_controller_test.rb +11 -0
- data/test/controllers/stacks_controller_test.rb +5 -0
- data/test/controllers/tasks_controller_test.rb +6 -0
- data/test/dummy/config/secrets.example.yml +4 -0
- data/test/dummy/config/secrets.yml +2 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/bar.txt +2 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dkfdsf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dskjfsd +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/dslkjfjsdf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/plopfizz +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sd +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdkfjsdf +1 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdlfjsdfdsfj +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/sdlkfjsdlkfjsdlkfjdsfsdfksdfjsldkfjsdlkfjsdf +0 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/shipit.yml +32 -0
- data/test/dummy/data/stacks/byroot/junk/production/deploys/83/toto.txt +2 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/bar.txt +1 -0
- data/test/dummy/data/stacks/byroot/junk/production/git/shipit.yml +6 -1
- data/test/dummy/data/stacks/byroot/test/production/git/README.md +1 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +3 -1
- data/test/dummy/db/seeds.rb +6 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/db/test.sqlite3-journal +0 -0
- data/test/fixtures/shipit/tasks.yml +11 -0
- data/test/models/commits_test.rb +1 -1
- data/test/models/deploys_test.rb +40 -0
- data/test/models/duration_test.rb +13 -0
- data/test/models/stacks_test.rb +3 -4
- data/test/unit/command_test.rb +14 -0
- data/vendor/assets/javascripts/clusterize.js +327 -0
- data/vendor/assets/javascripts/mousetrap-global-bind.js +43 -0
- data/vendor/assets/javascripts/mousetrap.js +1021 -0
- data/vendor/assets/javascripts/string_includes.js +14 -0
- data/vendor/assets/stylesheets/clusterize.css +27 -0
- metadata +100 -3
- data/app/assets/javascripts/task/sticky_element.js.coffee +0 -16
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Custom bootstrap variables must be set or import before bootstrap itself.
|
|
2
|
+
@import "bootstrap";
|
|
3
|
+
|
|
4
|
+
body {
|
|
5
|
+
padding-top: 5rem;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.navbar-brand {
|
|
9
|
+
background: asset-data-url('anchor.svg') center center no-repeat;
|
|
10
|
+
display: block;
|
|
11
|
+
width: 40px;
|
|
12
|
+
height: 40px;
|
|
13
|
+
transition: transform .3s ease-in-out;
|
|
14
|
+
text-indent: -9999px;
|
|
15
|
+
top: 50%;
|
|
16
|
+
right: 100%;
|
|
17
|
+
margin-right: 1em;
|
|
18
|
+
|
|
19
|
+
&:hover {
|
|
20
|
+
transform: rotate(-25deg);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -9,10 +9,14 @@ module Shipit
|
|
|
9
9
|
def new
|
|
10
10
|
@commit = @stack.commits.by_sha!(params[:sha])
|
|
11
11
|
@commit.checks.schedule if @stack.checks?
|
|
12
|
-
@deploy = @stack.
|
|
12
|
+
@deploy = @stack.build_deploy(@commit, current_user)
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def show
|
|
16
|
+
respond_to do |format|
|
|
17
|
+
format.html
|
|
18
|
+
format.text { render plain: @deploy.chunk_output }
|
|
19
|
+
end
|
|
16
20
|
end
|
|
17
21
|
|
|
18
22
|
def create
|
|
@@ -11,9 +11,12 @@ module Shipit
|
|
|
11
11
|
helper Shipit::Engine.routes.url_helpers
|
|
12
12
|
include Shipit::Engine.routes.url_helpers
|
|
13
13
|
|
|
14
|
-
before_action
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
before_action(
|
|
15
|
+
:toogle_bootstrap_feature,
|
|
16
|
+
:ensure_required_settings,
|
|
17
|
+
:force_github_authentication,
|
|
18
|
+
:set_variant,
|
|
19
|
+
)
|
|
17
20
|
|
|
18
21
|
# Respond to HTML by default
|
|
19
22
|
respond_to :html
|
|
@@ -24,6 +27,10 @@ module Shipit
|
|
|
24
27
|
|
|
25
28
|
private
|
|
26
29
|
|
|
30
|
+
def toogle_bootstrap_feature
|
|
31
|
+
prepend_view_path(Shipit.bootstrap_view_path) if Shipit.feature_bootstrap?
|
|
32
|
+
end
|
|
33
|
+
|
|
27
34
|
def ensure_required_settings
|
|
28
35
|
return if Shipit.all_settings_present?
|
|
29
36
|
|
|
@@ -24,8 +24,16 @@ module Shipit
|
|
|
24
24
|
@commits = @commits.to_a
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
+
def lookup
|
|
28
|
+
@stack = Stack.find(params[:id])
|
|
29
|
+
redirect_to stack_url(@stack)
|
|
30
|
+
end
|
|
31
|
+
|
|
27
32
|
def create
|
|
28
|
-
@stack = Stack.
|
|
33
|
+
@stack = Stack.new(create_params)
|
|
34
|
+
unless @stack.save
|
|
35
|
+
flash[:warning] = @stack.errors.full_messages.to_sentence
|
|
36
|
+
end
|
|
29
37
|
respond_with(@stack)
|
|
30
38
|
end
|
|
31
39
|
|
|
@@ -41,7 +49,7 @@ module Shipit
|
|
|
41
49
|
RefreshStatusesJob.perform_later(stack_id: @stack.id)
|
|
42
50
|
GithubSyncJob.perform_later(stack_id: @stack.id)
|
|
43
51
|
flash[:success] = 'Refresh scheduled'
|
|
44
|
-
redirect_to :back
|
|
52
|
+
redirect_to request.referer ? :back : stack_path(@stack)
|
|
45
53
|
end
|
|
46
54
|
|
|
47
55
|
def update
|
|
@@ -73,7 +81,8 @@ module Shipit
|
|
|
73
81
|
end
|
|
74
82
|
|
|
75
83
|
def update_params
|
|
76
|
-
params.require(:stack).permit(:deploy_url, :lock_reason, :
|
|
84
|
+
params.require(:stack).permit(:deploy_url, :lock_reason, :environment,
|
|
85
|
+
:continuous_deployment, :ignore_ci).tap do |params|
|
|
77
86
|
params[:lock_author_id] = params[:lock_reason].present? ? current_user.id : nil
|
|
78
87
|
end
|
|
79
88
|
end
|
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
module Shipit
|
|
2
2
|
module ShipitHelper
|
|
3
|
+
def emojify(content)
|
|
4
|
+
h(content).to_str.gsub(/:([\w+-]+):/) do |match|
|
|
5
|
+
if emoji = Emoji.find_by_alias($1)
|
|
6
|
+
%(
|
|
7
|
+
<img
|
|
8
|
+
alt="##{$1}"
|
|
9
|
+
src="#{image_path("emoji/#{emoji.image_filename}")}"
|
|
10
|
+
style="vertical-align:middle"
|
|
11
|
+
width="20"
|
|
12
|
+
height="20"
|
|
13
|
+
/>
|
|
14
|
+
)
|
|
15
|
+
else
|
|
16
|
+
match
|
|
17
|
+
end
|
|
18
|
+
end.html_safe if content.present?
|
|
19
|
+
end
|
|
20
|
+
|
|
3
21
|
def include_plugins(stack)
|
|
4
22
|
stack.plugins.flat_map do |plugin, config|
|
|
5
23
|
plugin_tags(plugin, config)
|
|
@@ -37,7 +37,7 @@ module Shipit
|
|
|
37
37
|
|
|
38
38
|
def render_commit_message(commit)
|
|
39
39
|
message = commit.pull_request_title || commit.message
|
|
40
|
-
content_tag(:span, message.truncate(COMMIT_TITLE_LENGTH), class: 'event-message')
|
|
40
|
+
content_tag(:span, emojify(message.truncate(COMMIT_TITLE_LENGTH)), class: 'event-message')
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def render_commit_message_with_link(commit)
|
|
@@ -3,6 +3,8 @@ module Shipit
|
|
|
3
3
|
include BackgroundJob::Unique
|
|
4
4
|
|
|
5
5
|
def perform(stack)
|
|
6
|
+
return if stack.inaccessible?
|
|
7
|
+
|
|
6
8
|
commands = Commands.for(stack)
|
|
7
9
|
commands.with_temporary_working_directory(commit: stack.commits.last) do |path|
|
|
8
10
|
stack.update!(cached_deploy_spec: DeploySpec::FileSystem.new(path, stack.environment))
|
data/app/models/shipit/commit.rb
CHANGED
|
@@ -23,12 +23,12 @@ module Shipit
|
|
|
23
23
|
|
|
24
24
|
def self.newer_than(commit)
|
|
25
25
|
return all unless commit
|
|
26
|
-
where('id > ?', commit.
|
|
26
|
+
where('id > ?', commit.try(:id) || commit)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def self.until(commit)
|
|
30
30
|
return all unless commit
|
|
31
|
-
where('id <= ?', commit.
|
|
31
|
+
where('id <= ?', commit.try(:id) || commit)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
34
|
def self.successful
|
data/app/models/shipit/deploy.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Shipit
|
|
|
26
26
|
# Heroku apps often specify a ruby version.
|
|
27
27
|
if /darwin/ =~ RUBY_PLATFORM
|
|
28
28
|
# OSX is nitpicky about the -i.
|
|
29
|
-
%q(sed -i '' '/^ruby\s/d' Gemfile)
|
|
29
|
+
%q(/usr/bin/sed -i '' '/^ruby\s/d' Gemfile)
|
|
30
30
|
else
|
|
31
31
|
%q(sed -i '/^ruby\s/d' Gemfile)
|
|
32
32
|
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Shipit
|
|
2
|
+
class Duration
|
|
3
|
+
UNITS = {
|
|
4
|
+
's' => :seconds,
|
|
5
|
+
'm' => :minutes,
|
|
6
|
+
'h' => :hours,
|
|
7
|
+
'd' => :days,
|
|
8
|
+
}.freeze
|
|
9
|
+
|
|
10
|
+
def initialize(seconds)
|
|
11
|
+
@seconds = seconds
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def to_i
|
|
15
|
+
@seconds.to_i
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
seconds = to_i
|
|
20
|
+
days, seconds = seconds.divmod(1.day.to_i)
|
|
21
|
+
if days > 0
|
|
22
|
+
"#{days}d#{Time.at(seconds).utc.strftime('%Hh%Mm%Ss')}"
|
|
23
|
+
else
|
|
24
|
+
Time.at(seconds).utc.strftime('%Hh%Mm%Ss')[/[^0a-z]\w+/] || '0s'
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
data/app/models/shipit/stack.rb
CHANGED
|
@@ -2,6 +2,22 @@ require 'fileutils'
|
|
|
2
2
|
|
|
3
3
|
module Shipit
|
|
4
4
|
class Stack < ActiveRecord::Base
|
|
5
|
+
module NoDeployedCommit
|
|
6
|
+
extend self
|
|
7
|
+
|
|
8
|
+
def id
|
|
9
|
+
-1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def sha
|
|
13
|
+
''
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def blank?
|
|
17
|
+
true
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
5
21
|
REPO_OWNER_MAX_SIZE = 39
|
|
6
22
|
REPO_NAME_MAX_SIZE = 100
|
|
7
23
|
ENVIRONMENT_MAX_SIZE = 50
|
|
@@ -36,7 +52,8 @@ module Shipit
|
|
|
36
52
|
after_commit :setup_hooks, :sync_github, on: :create
|
|
37
53
|
after_touch :clear_cache
|
|
38
54
|
|
|
39
|
-
validates :repo_name, uniqueness: {scope: %i(repo_owner environment)
|
|
55
|
+
validates :repo_name, uniqueness: {scope: %i(repo_owner environment),
|
|
56
|
+
message: 'cannot be used more than once with this environment'}
|
|
40
57
|
validates :repo_owner, :repo_name, :environment, presence: true, ascii_only: true
|
|
41
58
|
validates :repo_owner, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: REPO_OWNER_MAX_SIZE}
|
|
42
59
|
validates :repo_name, format: {with: /\A[a-z0-9_\-\.]+\z/}, length: {maximum: REPO_NAME_MAX_SIZE}
|
|
@@ -57,7 +74,7 @@ module Shipit
|
|
|
57
74
|
end
|
|
58
75
|
|
|
59
76
|
def trigger_task(definition_id, user, env: nil)
|
|
60
|
-
commit = last_deployed_commit
|
|
77
|
+
commit = last_deployed_commit.presence || commits.first
|
|
61
78
|
task = tasks.create(
|
|
62
79
|
user_id: user.id,
|
|
63
80
|
definition: find_task_definition(definition_id),
|
|
@@ -69,15 +86,19 @@ module Shipit
|
|
|
69
86
|
task
|
|
70
87
|
end
|
|
71
88
|
|
|
72
|
-
def
|
|
73
|
-
since_commit = last_deployed_commit
|
|
74
|
-
|
|
75
|
-
deploy = deploys.create(
|
|
89
|
+
def build_deploy(until_commit, user, env: nil)
|
|
90
|
+
since_commit = last_deployed_commit.presence || commits.first
|
|
91
|
+
deploys.build(
|
|
76
92
|
user_id: user.id,
|
|
77
93
|
until_commit: until_commit,
|
|
78
94
|
since_commit: since_commit,
|
|
79
95
|
env: filter_deploy_envs(env || {}),
|
|
80
96
|
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def trigger_deploy(*args)
|
|
100
|
+
deploy = build_deploy(*args)
|
|
101
|
+
deploy.save!
|
|
81
102
|
deploy.enqueue
|
|
82
103
|
deploy
|
|
83
104
|
end
|
|
@@ -95,10 +116,11 @@ module Shipit
|
|
|
95
116
|
end
|
|
96
117
|
|
|
97
118
|
def update_deployed_revision(sha)
|
|
98
|
-
return if active_task?
|
|
99
|
-
|
|
100
119
|
last_deploy = deploys_and_rollbacks.last
|
|
101
|
-
|
|
120
|
+
return if last_deploy.try!(:active?)
|
|
121
|
+
|
|
122
|
+
actual_deployed_commit = commits.reachable.by_sha(sha)
|
|
123
|
+
return unless actual_deployed_commit
|
|
102
124
|
|
|
103
125
|
if last_deploy && actual_deployed_commit == last_deploy.until_commit
|
|
104
126
|
last_deploy.accept!
|
|
@@ -107,7 +129,7 @@ module Shipit
|
|
|
107
129
|
else
|
|
108
130
|
deploys.create!(
|
|
109
131
|
until_commit: actual_deployed_commit,
|
|
110
|
-
since_commit: last_deployed_commit,
|
|
132
|
+
since_commit: last_deployed_commit.presence || commits.first,
|
|
111
133
|
status: 'success',
|
|
112
134
|
)
|
|
113
135
|
end
|
|
@@ -144,7 +166,7 @@ module Shipit
|
|
|
144
166
|
if deploy = last_successful_deploy
|
|
145
167
|
deploy.until_commit
|
|
146
168
|
else
|
|
147
|
-
|
|
169
|
+
NoDeployedCommit
|
|
148
170
|
end
|
|
149
171
|
end
|
|
150
172
|
|
data/app/models/shipit/task.rb
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
module Shipit
|
|
2
2
|
class Task < ActiveRecord::Base
|
|
3
|
+
ACTIVE_STATUSES = %w(pending running aborting).freeze
|
|
4
|
+
COMPLETED_STATUSES = %w(success error failed flapping aborted).freeze
|
|
5
|
+
|
|
3
6
|
belongs_to :deploy, foreign_key: :parent_id, required: false # required for fixtures
|
|
4
7
|
|
|
5
8
|
belongs_to :user
|
|
@@ -13,8 +16,8 @@ module Shipit
|
|
|
13
16
|
serialize :env, Hash
|
|
14
17
|
|
|
15
18
|
scope :success, -> { where(status: 'success') }
|
|
16
|
-
scope :completed, -> { where(status:
|
|
17
|
-
scope :active, -> { where(status:
|
|
19
|
+
scope :completed, -> { where(status: COMPLETED_STATUSES) }
|
|
20
|
+
scope :active, -> { where(status: ACTIVE_STATUSES) }
|
|
18
21
|
scope :exclusive, -> { where(allow_concurrency: false) }
|
|
19
22
|
|
|
20
23
|
scope :due_for_rollup, -> { completed.where(rolled_up: false).where('created_at <= ?', 1.hour.ago) }
|
|
@@ -23,6 +26,14 @@ module Shipit
|
|
|
23
26
|
after_commit :emit_hooks
|
|
24
27
|
|
|
25
28
|
state_machine :status, initial: :pending do
|
|
29
|
+
before_transition any => :running do |task|
|
|
30
|
+
task.started_at ||= Time.now.utc
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
before_transition any => %i(success failed error) do |task|
|
|
34
|
+
task.ended_at ||= Time.now.utc
|
|
35
|
+
end
|
|
36
|
+
|
|
26
37
|
after_transition any => %i(success failed error) do |task|
|
|
27
38
|
task.async_refresh_deployed_revision
|
|
28
39
|
end
|
|
@@ -69,6 +80,10 @@ module Shipit
|
|
|
69
80
|
state :flapping
|
|
70
81
|
end
|
|
71
82
|
|
|
83
|
+
def active?
|
|
84
|
+
status.in?(ACTIVE_STATUSES)
|
|
85
|
+
end
|
|
86
|
+
|
|
72
87
|
def report_failure!(_error)
|
|
73
88
|
reload
|
|
74
89
|
if aborting?
|
|
@@ -79,7 +94,7 @@ module Shipit
|
|
|
79
94
|
end
|
|
80
95
|
|
|
81
96
|
def report_error!(error)
|
|
82
|
-
write("#{error.class}: #{error.message}\n\t#{error.backtrace.join("\t")}\n")
|
|
97
|
+
write("#{error.class}: #{error.message}\n\t#{error.backtrace.join("\n\t")}\n")
|
|
83
98
|
error!
|
|
84
99
|
end
|
|
85
100
|
|
|
@@ -87,6 +102,14 @@ module Shipit
|
|
|
87
102
|
|
|
88
103
|
delegate :checklist, to: :definition
|
|
89
104
|
|
|
105
|
+
def duration?
|
|
106
|
+
started_at? && ended_at?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def duration
|
|
110
|
+
Duration.new(ended_at - started_at) if duration?
|
|
111
|
+
end
|
|
112
|
+
|
|
90
113
|
def spec
|
|
91
114
|
@spec ||= DeploySpec::FileSystem.new(working_directory, stack.environment)
|
|
92
115
|
end
|
|
@@ -5,7 +5,20 @@ module Shipit
|
|
|
5
5
|
has_one :author
|
|
6
6
|
has_one :revision, serializer: ShortCommitSerializer
|
|
7
7
|
|
|
8
|
-
attributes
|
|
8
|
+
attributes(*%i(
|
|
9
|
+
id
|
|
10
|
+
url
|
|
11
|
+
html_url
|
|
12
|
+
output_url
|
|
13
|
+
type
|
|
14
|
+
status
|
|
15
|
+
action
|
|
16
|
+
description
|
|
17
|
+
started_at
|
|
18
|
+
ended_at
|
|
19
|
+
updated_at
|
|
20
|
+
created_at
|
|
21
|
+
))
|
|
9
22
|
|
|
10
23
|
def revision
|
|
11
24
|
object.until_commit
|