shipit-engine 0.10.0 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +33 -11
  3. data/app/assets/javascripts/shipit.js.coffee +7 -1
  4. data/app/assets/stylesheets/_base/_buttons.scss +3 -0
  5. data/app/assets/stylesheets/_base/_colors.scss +1 -1
  6. data/app/assets/stylesheets/_base/_status-items.scss +1 -1
  7. data/app/assets/stylesheets/_pages/_deploy.scss +1 -1
  8. data/app/assets/stylesheets/_structure/_main.scss +1 -1
  9. data/app/controllers/shipit/stacks_controller.rb +1 -5
  10. data/app/helpers/shipit/shipit_helper.rb +7 -9
  11. data/app/helpers/shipit/stacks_helper.rb +14 -28
  12. data/app/jobs/shipit/continuous_delivery_job.rb +1 -1
  13. data/app/jobs/shipit/update_estimated_deploy_duration.rb +9 -0
  14. data/app/models/shipit/commit_checks.rb +1 -1
  15. data/app/models/shipit/deploy.rb +1 -1
  16. data/app/models/shipit/deploy_spec/bundler_discovery.rb +1 -1
  17. data/app/models/shipit/deploy_spec/file_system.rb +6 -1
  18. data/app/models/shipit/deploy_spec.rb +12 -0
  19. data/app/models/shipit/duration.rb +29 -9
  20. data/app/models/shipit/github_hook.rb +0 -2
  21. data/app/models/shipit/stack.rb +48 -11
  22. data/app/models/shipit/task.rb +13 -2
  23. data/app/models/shipit/team.rb +1 -1
  24. data/app/models/shipit/undeployed_commit.rb +36 -0
  25. data/app/views/layouts/shipit.html.erb +6 -4
  26. data/app/views/shipit/deploys/show.html.erb +1 -1
  27. data/app/views/shipit/stacks/_header.html.erb +7 -0
  28. data/app/views/shipit/stacks/show.html.erb +1 -1
  29. data/config/locales/en.yml +9 -3
  30. data/config/secrets.development.example.yml +19 -0
  31. data/config/secrets.development.shopify.yml +19 -0
  32. data/config/secrets.development.yml +16 -0
  33. data/db/migrate/20160502150713_add_estimated_deploy_duration_to_stacks.rb +5 -0
  34. data/db/migrate/20160526192650_reorder_active_tasks_index.rb +7 -0
  35. data/lib/shipit/command.rb +15 -2
  36. data/lib/shipit/engine.rb +2 -1
  37. data/lib/shipit/stat.rb +13 -0
  38. data/lib/shipit/version.rb +1 -1
  39. data/lib/shipit.rb +13 -0
  40. data/lib/tasks/cron.rake +1 -0
  41. data/test/controllers/github_authentication_controller_test.rb +5 -5
  42. data/test/dummy/config/initializers/0_load_development_secrets.rb +9 -0
  43. data/test/dummy/config/secrets.yml +5 -16
  44. data/test/dummy/db/development.sqlite3 +0 -0
  45. data/test/dummy/db/schema.rb +14 -14
  46. data/test/dummy/db/seeds.rb +1 -0
  47. data/test/dummy/db/test.sqlite3 +0 -0
  48. data/test/fixtures/shipit/stacks.yml +2 -2
  49. data/test/fixtures/shipit/tasks.yml +3 -1
  50. data/test/fixtures/shipit/users.yml +5 -0
  51. data/test/helpers/queries_helper.rb +1 -1
  52. data/test/models/deploys_test.rb +7 -0
  53. data/test/models/duration_test.rb +23 -0
  54. data/test/models/stacks_test.rb +93 -4
  55. data/test/models/undeployed_commits_test.rb +100 -0
  56. data/test/test_helper.rb +1 -0
  57. data/test/unit/deploy_spec_test.rb +1 -1
  58. data/test/unit/shipit_test.rb +2 -1
  59. metadata +19 -10
  60. data/db/schema.rb +0 -188
  61. data/test/dummy/config/secrets.example.yml +0 -35
@@ -1,6 +1,6 @@
1
1
  module Shipit
2
2
  class Team < ActiveRecord::Base
3
- REQUIRED_HOOKS = %i(membership)
3
+ REQUIRED_HOOKS = %i(membership).freeze
4
4
 
5
5
  has_many :members, class_name: :User, through: :memberships, source: :user
6
6
  has_many :memberships
@@ -0,0 +1,36 @@
1
+ module Shipit
2
+ class UndeployedCommit < DelegateClass(Commit)
3
+ attr_reader :index
4
+
5
+ def initialize(commit, index)
6
+ super(commit)
7
+ @index = index
8
+ end
9
+
10
+ def deploy_state(bypass_safeties = false)
11
+ state = deployable? ? 'allowed' : status.state
12
+ unless bypass_safeties
13
+ state = 'deploying' if stack.active_task?
14
+ state = 'locked' if stack.locked?
15
+ end
16
+ state
17
+ end
18
+
19
+ def redeploy_state(bypass_safeties = false)
20
+ state = 'allowed'
21
+ unless bypass_safeties
22
+ state = 'locked' if stack.locked?
23
+ state = 'deploying' if stack.active_task?
24
+ end
25
+ state
26
+ end
27
+
28
+ def deploy_disallowed?
29
+ !deployable? || !stack.deployable?
30
+ end
31
+
32
+ def deploy_discouraged?
33
+ stack.maximum_commits_per_deploy && index >= stack.maximum_commits_per_deploy
34
+ end
35
+ end
36
+ end
@@ -13,14 +13,16 @@
13
13
  <%= content_tag :div, msg, class: ["flash-#{name}", :flash] %>
14
14
  <% end %>
15
15
 
16
- <div class="banner notification banner--blue hidden">
16
+ <div class="banner enable-notifications banner--blue hidden">
17
17
  <div class="banner__inner wrapper">
18
18
  <div class="banner__content">
19
19
  <h2 class="banner__title">Do you want to enable desktop notifications?</h2>
20
+ <div class="banner__accessory">
21
+ <button class="banner__btn btn">Enable notifications</button>
22
+ </div>
20
23
  </div>
21
- <div class="banner__accessory">
22
- <button class="banner__btn btn">Enable notifications</button>
23
- </div>
24
+
25
+ <a class="banner__dismiss">&times;</a>
24
26
  </div>
25
27
  </div>
26
28
 
@@ -4,7 +4,7 @@
4
4
  <% else %>
5
5
  deploying
6
6
  <% end %>
7
- <span class="short-sha"><%= render_commit_id_link(@deploy.until_commit) %></span>
7
+ <span class="short-sha"><%= link_to_github_deploy(@deploy) %></span>
8
8
  <%= timeago_tag(@deploy.created_at, force: true) %>
9
9
  <% end %>
10
10
 
@@ -24,6 +24,13 @@
24
24
  </li>
25
25
  </ul>
26
26
  <ul class="nav__list nav__list--secondary">
27
+ <% if stack.links.present? %>
28
+ <% stack.links.each do |name, url| %>
29
+ <li class="nav__list__item">
30
+ <%= link_to name.humanize, url, :target => '_blank', :class => "#{name.dasherize}-url" %>
31
+ </li>
32
+ <% end %>
33
+ <% end %>
27
34
  <li class="nav__list__item">
28
35
  <%= link_to 'View on GitHub', github_repo_url(stack.repo_owner, stack.repo_name) %>
29
36
  </li>
@@ -64,7 +64,7 @@
64
64
  </div>
65
65
  </header>
66
66
  <ul class="commit-list">
67
- <%= render partial: 'shipit/commits/commit', collection: @commits.to_a %>
67
+ <%= render partial: 'shipit/commits/commit', collection: @commits %>
68
68
  </ul>
69
69
  </section>
70
70
 
@@ -21,16 +21,22 @@
21
21
 
22
22
  en:
23
23
  deploy_button:
24
+ hint:
25
+ max_commits: It is recommended not to deploy more than %{maximum} commits at once.
24
26
  caption:
25
27
  pending: CI Pending...
26
28
  failure: CI Failure
27
29
  error: CI Error
28
30
  unknown: Not Run
29
31
  locked: Locked
30
- deploying: Deploy in progress...
31
- enabled: Deploy
32
+ deploying: A Deploy is in Progress...
33
+ allowed: Deploy
32
34
  missing: Missing CI
33
-
35
+ redeploy_button:
36
+ caption:
37
+ deploying: A Deploy is in Progress...
38
+ allowed: Redeploy
39
+ locked: Locked
34
40
  deploy_spec:
35
41
  hint:
36
42
  deploy: Impossible to detect how to deploy this application. Please define `deploy.override` in your shipit.yml
@@ -0,0 +1,19 @@
1
+ host: 'http://localhost:3000'
2
+ redis_url: 'redis://127.0.0.1:6379/0'
3
+
4
+ github_api:
5
+ # Can be obtained there: https://github.com/settings/tokens/new
6
+ # The required permissions are: `admin:org_hook`, `admin:repo_hook`, `read:org` and `repo`
7
+ access_token:
8
+
9
+ # Can be obtained there: https://github.com/settings/applications/new
10
+ # Set the "Authorization callback URL" as `<host>/github/auth/github/callback`
11
+ github_oauth:
12
+ id:
13
+ secret:
14
+ # teams: # Optional
15
+
16
+ # To work on the beta bootstrap re-write
17
+ # features:
18
+ # - bootstrap
19
+
@@ -0,0 +1,19 @@
1
+ host: 'http://shipit-engine.localhost'
2
+ redis_url: 'redis://shipit-engine.railgun:6379'
3
+
4
+ github_api:
5
+ # Can be obtained there: https://github.com/settings/tokens/new
6
+ # The required permissions are: `admin:org_hook`, `admin:repo_hook`, `read:org` and `repo`
7
+ access_token:
8
+
9
+ # Can be obtained there: https://github.com/settings/applications/new
10
+ # Set the "Authorization callback URL" as `<host>/github/auth/github/callback`
11
+ github_oauth:
12
+ id:
13
+ secret:
14
+ # teams: # Optional
15
+
16
+ # To work on the beta bootstrap re-write
17
+ # features:
18
+ # - bootstrap
19
+
@@ -0,0 +1,16 @@
1
+ host: 'http://shipit-engine.localhost'
2
+ redis_url: 'redis://shipit-engine.railgun:6379'
3
+
4
+ github_api:
5
+ access_token: caa4f8b2bb3d94269291faf9b54b85457db0173b
6
+
7
+ # If you want to test GitHub Authentication
8
+ github_oauth:
9
+ id: d2c8c96f8f226933186e
10
+ secret: e4ca5135bb7052318e8cc4e48f296ee58ad39e61
11
+ # teams:
12
+
13
+ # To work on the beta bootstrap re-write
14
+ # features:
15
+ # - bootstrap
16
+
@@ -0,0 +1,5 @@
1
+ class AddEstimatedDeployDurationToStacks < ActiveRecord::Migration
2
+ def change
3
+ add_column :stacks, :estimated_deploy_duration, :integer, null: false, default: 1
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class ReorderActiveTasksIndex < ActiveRecord::Migration
2
+ def change
3
+ remove_index :tasks, name: :index_active_tasks
4
+ add_index :tasks, %i(stack_id allow_concurrency status), name: :index_active_tasks
5
+ remove_index :tasks, :stack_id # now useless since `index_active_tasks` starts by `stack_id`
6
+ end
7
+ end
@@ -15,7 +15,7 @@ module Shipit
15
15
 
16
16
  attr_reader :out, :code, :chdir, :env, :args, :pid, :timeout
17
17
 
18
- def initialize(*args, default_timeout: 5.minutes.to_i, env: {}, chdir:)
18
+ def initialize(*args, default_timeout: Shipit.default_inactivity_timeout, env: {}, chdir:)
19
19
  @args, options = parse_arguments(args)
20
20
  @timeout = options['timeout'.freeze] || options[:timeout] || default_timeout
21
21
  @env = env
@@ -170,12 +170,25 @@ module Shipit
170
170
  end
171
171
 
172
172
  def kill_and_wait(sig, wait, &block)
173
+ retry_count = 5
173
174
  kill(sig, &block)
174
175
  begin
175
176
  with_timeout(wait) do
176
177
  read_stream(@out, &block)
177
178
  end
178
- rescue TimedOut, Errno::EIO # EIO is somewhat expected on Linux: http://stackoverflow.com/a/10306782
179
+ rescue TimedOut
180
+ rescue Errno::EIO # EIO is somewhat expected on Linux: http://stackoverflow.com/a/10306782
181
+ # If we try to read the stream right after sending a signal, we often get an Errno::EIO.
182
+ if status = Process.wait(@pid, Process::WNOHANG)
183
+ return status
184
+ else
185
+ # If we let the child a little bit of time, it solves it.
186
+ retry_count -= 1
187
+ if retry_count > 0
188
+ sleep 0.05
189
+ retry
190
+ end
191
+ end
179
192
  end
180
193
  Process.wait(@pid, Process::WNOHANG)
181
194
  end
data/lib/shipit/engine.rb CHANGED
@@ -9,6 +9,7 @@ module Shipit
9
9
  initializer 'shipit.config' do |app|
10
10
  Rails.application.routes.default_url_options[:host] = Shipit.host
11
11
  Shipit::Engine.routes.default_url_options[:host] = Shipit.host
12
+ Pubsubstub.redis_url = Shipit.redis_url.to_s
12
13
 
13
14
  app.config.assets.paths << Emoji.images_path
14
15
  app.config.assets.precompile += %w(
@@ -20,7 +21,7 @@ module Shipit
20
21
  shipit_bs.css
21
22
  )
22
23
  app.config.assets.precompile << proc do |path|
23
- path =~ /\Aplugins\/[\-\w]+\.(js|css)\Z/
24
+ path =~ %r{\Aplugins/[\-\w]+\.(js|css)\Z}
24
25
  end
25
26
  app.config.assets.precompile << proc do |path|
26
27
  path.start_with?('emoji/') && path.end_with?('.png')
@@ -0,0 +1,13 @@
1
+ module Shipit
2
+ module Stat
3
+ extend self
4
+
5
+ def p90(numbers)
6
+ percentile(90, numbers)
7
+ end
8
+
9
+ def percentile(percentile, numbers)
10
+ numbers.sort[((numbers.size - 1) * percentile / 100.0).floor]
11
+ end
12
+ end
13
+ end
@@ -1,3 +1,3 @@
1
1
  module Shipit
2
- VERSION = '0.10.0'
2
+ VERSION = '0.11.0'.freeze
3
3
  end
data/lib/shipit.rb CHANGED
@@ -45,6 +45,7 @@ require 'shipit/task_commands'
45
45
  require 'shipit/deploy_commands'
46
46
  require 'shipit/rollback_commands'
47
47
  require 'shipit/environment_variables'
48
+ require 'shipit/stat'
48
49
 
49
50
  SafeYAML::OPTIONS[:default_mode] = :safe
50
51
  SafeYAML::OPTIONS[:deserialize_symbols] = false
@@ -85,6 +86,14 @@ module Shipit
85
86
  github_url('/api/v3/') if github_enterprise?
86
87
  end
87
88
 
89
+ def user
90
+ if github_api.login
91
+ User.find_or_create_by_login!(github_api.login)
92
+ else
93
+ AnonymousUser.new
94
+ end
95
+ end
96
+
88
97
  def github_api
89
98
  @github_api ||= begin
90
99
  client = Octokit::Client.new(github_api_credentials)
@@ -184,6 +193,10 @@ module Shipit
184
193
  @bootstrap_view_path ||= Engine.root.join('app/views/bootstrap')
185
194
  end
186
195
 
196
+ def default_inactivity_timeout
197
+ secrets.commands_inactivity_timeout || 5.minutes.to_i
198
+ end
199
+
187
200
  protected
188
201
 
189
202
  def revision_file
data/lib/tasks/cron.rake CHANGED
@@ -2,6 +2,7 @@ namespace :cron do
2
2
  desc "Updates deployed revisions"
3
3
  task minutely: :environment do
4
4
  Shipit::Stack.refresh_deployed_revisions
5
+ Shipit::Stack.schedule_continuous_delivery
5
6
  end
6
7
 
7
8
  desc "Rolls-up output chunks for completed deploys older than an hour"
@@ -10,11 +10,11 @@ module Shipit
10
10
  extra: OmniAuth::AuthHash.new(
11
11
  raw_info: OmniAuth::AuthHash.new(
12
12
  id: 44,
13
- name: 'Shipit',
14
- email: 'shipit@example.com',
15
- login: 'shipit',
13
+ name: 'Shipit User',
14
+ email: 'shipit-user@example.com',
15
+ login: 'shipit-user',
16
16
  avatar_url: 'https://example.com',
17
- api_url: 'https://github.com/api/v3/users/shipit',
17
+ api_url: 'https://github.com/api/v3/users/shipit-user',
18
18
  ),
19
19
  ),
20
20
  )
@@ -24,7 +24,7 @@ module Shipit
24
24
  get :callback
25
25
  end
26
26
 
27
- user = User.find_by_login('shipit')
27
+ user = User.find_by_login('shipit-user')
28
28
  assert_equal 's3cr3t', user.github_access_token
29
29
  assert_equal 44, user.github_id
30
30
  end
@@ -0,0 +1,9 @@
1
+ local_secrets = Shipit::Engine.root.join('config/secrets.development.yml')
2
+ if local_secrets.exist?
3
+ secrets = YAML.load(local_secrets.read)
4
+ if Rails.env.development?
5
+ Rails.application.secrets.deep_merge!(secrets)
6
+ elsif Rails.env.test?
7
+ Rails.application.secrets.merge!(redis_url: secrets['redis_url'])
8
+ end
9
+ end
@@ -1,20 +1,5 @@
1
1
  development:
2
- features:
3
- - bootstrap
4
2
  secret_key_base: s3cr3ts3cr3ts3cr3ts3cr3ts3cr3ts3cr3t
5
- # github_domain: github.shopify.com
6
- github_oauth:
7
- id: 29f6c9084a8837f337ff
8
- secret: 3f5d2c3bb35d4ff905189401c3a2c8f249800554
9
- # team:
10
- github_api:
11
- access_token: d5a01c65f69d86ecc55dccdf347b19d6f9a16b3b
12
- # login:
13
- # password:
14
- # api_endpoint:
15
- host: 'http://localhost:3000'
16
- redis_url: "redis://127.0.0.1:6379/7"
17
-
18
3
  test:
19
4
  secret_key_base: s3cr3ts3cr3ts3cr3ts3cr3ts3cr3ts3cr3t
20
5
  host: shipit.com
@@ -26,5 +11,9 @@ test:
26
11
  github_oauth:
27
12
  id: 1d
28
13
  secret: s3cr37
29
- # team:
14
+ # teams:
15
+ # -
16
+ # -
30
17
  redis_url: "redis://127.0.0.1:6379/7"
18
+ # features:
19
+ # - bootstrap
Binary file
@@ -11,7 +11,7 @@
11
11
  #
12
12
  # It's strongly recommended that you check this file into your version control system.
13
13
 
14
- ActiveRecord::Schema.define(version: 20160426155146) do
14
+ ActiveRecord::Schema.define(version: 20160526192650) do
15
15
 
16
16
  create_table "api_clients", force: :cascade do |t|
17
17
  t.text "permissions", limit: 65535
@@ -130,21 +130,22 @@ ActiveRecord::Schema.define(version: 20160426155146) do
130
130
  add_index "output_chunks", ["task_id"], name: "index_output_chunks_on_task_id"
131
131
 
132
132
  create_table "stacks", force: :cascade do |t|
133
- t.string "repo_name", limit: 100, null: false
134
- t.string "repo_owner", limit: 39, null: false
135
- t.string "environment", limit: 50, default: "production", null: false
133
+ t.string "repo_name", limit: 100, null: false
134
+ t.string "repo_owner", limit: 39, null: false
135
+ t.string "environment", limit: 50, default: "production", null: false
136
136
  t.datetime "created_at"
137
137
  t.datetime "updated_at"
138
- t.string "branch", limit: 255, default: "master", null: false
139
- t.string "deploy_url", limit: 255
140
- t.string "lock_reason", limit: 4096
141
- t.integer "tasks_count", limit: 4, default: 0, null: false
142
- t.boolean "continuous_deployment", default: false, null: false
143
- t.integer "undeployed_commits_count", limit: 4, default: 0, null: false
144
- t.text "cached_deploy_spec", limit: 65535
145
- t.integer "lock_author_id", limit: 4
138
+ t.string "branch", limit: 255, default: "master", null: false
139
+ t.string "deploy_url", limit: 255
140
+ t.string "lock_reason", limit: 4096
141
+ t.integer "tasks_count", limit: 4, default: 0, null: false
142
+ t.boolean "continuous_deployment", default: false, null: false
143
+ t.integer "undeployed_commits_count", limit: 4, default: 0, null: false
144
+ t.text "cached_deploy_spec", limit: 65535
145
+ t.integer "lock_author_id", limit: 4
146
146
  t.boolean "ignore_ci"
147
147
  t.datetime "inaccessible_since"
148
+ t.integer "estimated_deploy_duration", default: 1, null: false
148
149
  end
149
150
 
150
151
  add_index "stacks", ["repo_owner", "repo_name", "environment"], name: "stack_unicity", unique: true
@@ -186,8 +187,7 @@ ActiveRecord::Schema.define(version: 20160426155146) do
186
187
 
187
188
  add_index "tasks", ["rolled_up", "created_at", "status"], name: "index_tasks_on_rolled_up_and_created_at_and_status"
188
189
  add_index "tasks", ["since_commit_id"], name: "index_tasks_on_since_commit_id"
189
- add_index "tasks", ["stack_id"], name: "index_tasks_on_stack_id"
190
- add_index "tasks", ["status", "stack_id", "allow_concurrency"], name: "index_active_tasks"
190
+ add_index "tasks", ["stack_id", "allow_concurrency", "status"], name: "index_active_tasks"
191
191
  add_index "tasks", ["type", "stack_id", "parent_id"], name: "index_tasks_by_stack_and_parent"
192
192
  add_index "tasks", ["type", "stack_id", "status"], name: "index_tasks_by_stack_and_status"
193
193
  add_index "tasks", ["until_commit_id"], name: "index_tasks_on_until_commit_id"
@@ -72,6 +72,7 @@ module Shipit
72
72
  ]
73
73
  },
74
74
  "deploy": {
75
+ "max_commits": 3,
75
76
  "override": [
76
77
  "bundle exec cap $ENVIRONMENT deploy"
77
78
  ]
Binary file
@@ -16,7 +16,7 @@ shipit:
16
16
  ]
17
17
  },
18
18
  "dependencies": {"override": []},
19
- "deploy": {"override": null, "variables": [{"name": "SAFETY_DISABLED", "title": "Set to 1 to do dangerous things", "default": 0}]},
19
+ "deploy": {"override": null, "interval": 60, "variables": [{"name": "SAFETY_DISABLED", "title": "Set to 1 to do dangerous things", "default": 0}]},
20
20
  "rollback": {"override": ["echo 'Rollback!'"]},
21
21
  "fetch": ["echo '42'"],
22
22
  "tasks": {
@@ -65,7 +65,7 @@ cyclimse:
65
65
  ]
66
66
  },
67
67
  "dependencies": {"override": []},
68
- "deploy": {"override": null},
68
+ "deploy": {"max_commits": 2, "interval": 60, "override": null},
69
69
  "rollback": {"override": ["echo 'Rollback!'"]},
70
70
  "fetch": ["echo '42'"],
71
71
  "tasks": {
@@ -8,6 +8,8 @@ shipit:
8
8
  additions: 1
9
9
  deletions: 1
10
10
  created_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
11
+ started_at: <%= (60 - 1).minutes.ago.to_s(:db) %>
12
+ ended_at: <%= (60 - 3).minutes.ago.to_s(:db) %>
11
13
 
12
14
  shipit2:
13
15
  user: walrus
@@ -79,7 +81,7 @@ shipit_complete:
79
81
  deletions: 342
80
82
  created_at: <%= (60 - 6).minutes.ago.to_s(:db) %>
81
83
  started_at: <%= (60 - 6).minutes.ago.to_s(:db) %>
82
- ended_at: <%= (60 - 2).minutes.ago.to_s(:db) %>
84
+ ended_at: <%= (60 - 8).minutes.ago.to_s(:db) %>
83
85
 
84
86
  shipit_aborted:
85
87
  user: bob
@@ -15,3 +15,8 @@ anonymous:
15
15
  name: Anonymous Legion
16
16
  email: anonymous@example.com
17
17
  # no Github info
18
+
19
+ shipit:
20
+ name: Shipit
21
+ email: shipit@example.com
22
+ login: shipit
@@ -7,7 +7,7 @@ module QueriesHelper
7
7
  counter = SQLCounter.new(ignored_sql)
8
8
  subscriber = ActiveSupport::Notifications.subscribe('sql.active_record', counter)
9
9
  yield counter
10
- queries = counter.log.size == 0 ? '' : "\nQueries:\n#{counter.log.join("\n")}"
10
+ queries = counter.log.empty? ? '' : "\nQueries:\n#{counter.log.join("\n")}"
11
11
  assert_equal num, counter.log.size, "#{counter.log.size} instead of #{num} queries were executed.#{queries}"
12
12
  ensure
13
13
  ActiveSupport::Notifications.unsubscribe(subscriber)
@@ -218,6 +218,13 @@ module Shipit
218
218
  end
219
219
  end
220
220
 
221
+ test "transitioning to success schedule an update of the estimated deploy duration" do
222
+ @deploy = shipit_deploys(:shipit_running)
223
+ assert_enqueued_with(job: UpdateEstimatedDeployDurationJob, args: [@deploy.stack]) do
224
+ @deploy.complete!
225
+ end
226
+ end
227
+
221
228
  test "transitioning to success schedule a fetch of the deployed revision" do
222
229
  @deploy = shipit_deploys(:shipit_running)
223
230
  assert_enqueued_with(job: FetchDeployedRevisionJob, args: [@deploy.stack]) do
@@ -2,6 +2,17 @@ require 'test_helper'
2
2
 
3
3
  module Shipit
4
4
  class DurationTest < ActiveSupport::TestCase
5
+ test "#<=> allow comparisons" do
6
+ assert_equal Duration.new(1), Duration.new(1)
7
+ assert Duration.new(2) > Duration.new(1)
8
+ assert Duration.new(2) > 1
9
+ assert 1 < Duration.new(2)
10
+ end
11
+
12
+ test "can be added to a Time instance" do
13
+ assert_equal Time.at(42), Time.at(40) + Duration.new(2)
14
+ end
15
+
5
16
  test "#to_s is precise and readable for humans" do
6
17
  assert_equal '1m01s', Duration.new(61).to_s
7
18
  assert_equal '1m00s', Duration.new(60).to_s
@@ -9,5 +20,17 @@ module Shipit
9
20
  assert_equal '2d00h00m00s', Duration.new(2.days).to_s
10
21
  assert_equal '0s', Duration.new(0).to_s
11
22
  end
23
+
24
+ test ".parse can read human format" do
25
+ assert_equal Duration.new(61), Duration.parse('1m01s')
26
+ assert_equal Duration.new(60), Duration.parse('1m00s')
27
+ assert_equal Duration.new(59), Duration.parse('59s')
28
+ assert_equal Duration.new(2.days), Duration.parse('2d00h00m00s')
29
+ assert_equal Duration.new(0), Duration.parse('0s')
30
+ end
31
+
32
+ test ".parse accepts integers as seconds" do
33
+ assert_equal Duration.new(42), Duration.parse(42)
34
+ end
12
35
  end
13
36
  end