shipit-engine 0.10.0 → 0.11.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.
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