shipit-engine 0.18.1 → 0.19.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 164e72e212fa74b62ae7adab49efea057f1d983a
4
- data.tar.gz: c5fbe8b529b76c20298ea2394b79358cb3dd22be
3
+ metadata.gz: fd2a6119dc0214d91ad2bfddf344a9cc898d94f1
4
+ data.tar.gz: a96e8b153d800ce1cea2a1d22e4f5f51671206d7
5
5
  SHA512:
6
- metadata.gz: 2929a4f676679ea715b527c0ab62c22d63222cab8902c005a507ddd1e30d32246532039e7784c674af9daaf52c6ccdbab02488ca22ea847b59c2514f943499a9
7
- data.tar.gz: 16fc66870a734dd2e2be52e3868417d32302a4ffb817064ac4d54334e152533e1021ab6b50e20f7dbb700f368dbbf3573258706d9618c27a97584c9d18be37de
6
+ metadata.gz: 4f69396b6035b1bf6a84371b882c091de91b70f0c1ed24881028f2836f1230abd64f7bac6406aeaaa71eb110ade52206dacd3953d799db18a8d1da427fef10e0
7
+ data.tar.gz: 6aa40d715e8aa4e52a16c60c9ad12b15978d88758c188370436806b458f716dbc13ec4d53276df4a727b0a97bd5b84eef3c8e5550bab77fc579beb390a0d137c
data/README.md CHANGED
@@ -16,6 +16,7 @@ This guide aims to help you [set up](#installation-and-setup), [use](#using-ship
16
16
 
17
17
  * * *
18
18
  <h2 id="toc">Table of contents</h2>
19
+
19
20
  **I. INSTALLATION & SETUP**
20
21
 
21
22
  * [Installation](#installation)
@@ -46,8 +47,8 @@ This guide aims to help you [set up](#installation-and-setup), [use](#using-ship
46
47
 
47
48
  Shipit provides you with a Rails template. To bootstrap your Shipit installation:
48
49
 
49
- 1. If you don't have Rails installed, run this command: `gem install rails -v 5.0.0.1`
50
- 2. Run this command: `rails _5.0.0.1_ new shipit --skip-action-cable --skip-turbolinks --skip-action-mailer -m https://raw.githubusercontent.com/Shopify/shipit-engine/master/template.rb`
50
+ 1. If you don't have Rails installed, run this command: `gem install rails -v 5.1`
51
+ 2. Run this command: `rails _5.1_ new shipit --skip-action-cable --skip-turbolinks --skip-action-mailer -m https://raw.githubusercontent.com/Shopify/shipit-engine/master/template.rb`
51
52
  3. Enter your **Client ID**, **Client Secret**, and **GitHub API access token** when prompted. These can be found on your application's GitHub page.
52
53
  4. To setup the database, run this command: `rake db:setup`
53
54
 
@@ -367,6 +368,7 @@ machine:
367
368
  ```
368
369
 
369
370
  <h3 id="ci">CI</h3>
371
+
370
372
  **<code>ci.require</code>** contains an array of the [statuses context](https://developer.github.com/v3/repos/statuses/) you want Shipit to disallow deploys if any of them is missing.
371
373
 
372
374
  For example:
@@ -3,7 +3,7 @@ module Shipit
3
3
  InsufficientPermission = Class.new(StandardError)
4
4
 
5
5
  belongs_to :creator, class_name: 'User'
6
- belongs_to :stack
6
+ belongs_to :stack, optional: true
7
7
 
8
8
  validates :creator, :name, presence: true
9
9
 
@@ -8,7 +8,7 @@ module Shipit
8
8
  has_many :deploys
9
9
  has_many :statuses, -> { order(created_at: :desc) }, dependent: :destroy
10
10
  has_many :commit_deployments, dependent: :destroy
11
- belongs_to :pull_request, inverse_of: :merge_commit
11
+ belongs_to :pull_request, inverse_of: :merge_commit, optional: true
12
12
 
13
13
  deferred_touch stack: :updated_at
14
14
 
@@ -1,6 +1,6 @@
1
1
  module Shipit
2
2
  class CommitMessage
3
- GITHUB_MERGE_COMMIT_PATTERN = %r{\AMerge pull request #(?<pr_id>\d+) from [\w\-./]+\n\n(?<pr_title>.*)}
3
+ GITHUB_MERGE_COMMIT_PATTERN = /\AMerge pull request #(?<pr_id>\d+) from \S+\n\n(?<pr_title>.*)/
4
4
 
5
5
  def initialize(text)
6
6
  @text = text
@@ -36,8 +36,8 @@ module Shipit
36
36
  end
37
37
 
38
38
  belongs_to :stack
39
- belongs_to :head, class_name: 'Shipit::Commit'
40
- belongs_to :merge_requested_by, class_name: 'Shipit::User'
39
+ belongs_to :head, class_name: 'Shipit::Commit', optional: true
40
+ belongs_to :merge_requested_by, class_name: 'Shipit::User', optional: true
41
41
  has_one :merge_commit, class_name: 'Shipit::Commit'
42
42
 
43
43
  deferred_touch stack: :updated_at
@@ -32,7 +32,7 @@ module Shipit
32
32
  has_many :github_hooks, dependent: :destroy, class_name: 'Shipit::GithubHook::Repo'
33
33
  has_many :hooks, dependent: :destroy
34
34
  has_many :api_clients, dependent: :destroy
35
- belongs_to :lock_author, class_name: :User
35
+ belongs_to :lock_author, class_name: :User, optional: true
36
36
 
37
37
  def lock_author(*)
38
38
  super || AnonymousUser.new
@@ -226,7 +226,7 @@ module Shipit
226
226
  end
227
227
 
228
228
  def last_successful_deploy
229
- deploys_and_rollbacks.success.last
229
+ deploys_and_rollbacks.last_successful
230
230
  end
231
231
 
232
232
  def last_active_task
@@ -332,7 +332,7 @@ module Shipit
332
332
 
333
333
  def active_task
334
334
  return @active_task if defined?(@active_task)
335
- @active_task ||= tasks.active.exclusive.last
335
+ @active_task ||= tasks.current
336
336
  end
337
337
 
338
338
  def locked?
@@ -13,7 +13,7 @@ module Shipit
13
13
 
14
14
  belongs_to :deploy, foreign_key: :parent_id, required: false # required for fixtures
15
15
 
16
- belongs_to :user
16
+ belongs_to :user, optional: true
17
17
  belongs_to :stack, counter_cache: true
18
18
  belongs_to :until_commit, class_name: 'Commit'
19
19
  belongs_to :since_commit, class_name: 'Commit'
@@ -41,6 +41,14 @@ module Shipit
41
41
  def durations
42
42
  pluck(:started_at, :ended_at).select { |s, e| s && e }.map { |s, e| e - s }
43
43
  end
44
+
45
+ def last_successful
46
+ success.last
47
+ end
48
+
49
+ def current
50
+ active.exclusive.last
51
+ end
44
52
  end
45
53
 
46
54
  state_machine :status, initial: :pending do
@@ -5,7 +5,7 @@ module Shipit
5
5
  has_one :lock_author
6
6
  attributes :id, :repo_owner, :repo_name, :environment, :html_url, :url, :tasks_url, :deploy_url, :pull_requests_url,
7
7
  :deploy_spec, :undeployed_commits_count, :is_locked, :lock_reason, :continuous_deployment, :created_at,
8
- :updated_at, :locked_since, :last_deployed_at
8
+ :updated_at, :locked_since, :last_deployed_at, :branch
9
9
 
10
10
  def url
11
11
  api_stack_url(object)
@@ -1,27 +1,32 @@
1
1
  <li class="commit <%= 'locked' if commit.locked? %>" id="commit-<%= commit.id %>">
2
- <%= render 'shipit/shared/author', author: commit.author %>
3
- <%= render commit.status %>
4
- <div class="commit-details">
5
- <span class="commit-title"><%= render_commit_message_with_link commit %></span>
6
- <p class="commit-meta">
7
- <span class="sha"><%= render_commit_id_link(commit) %></span>
8
- <% if commit.additions? && commit.deletions? %>
9
- <span class="code-additions">+<%= commit.additions %></span>
10
- <span class="code-deletions">-<%= commit.deletions %></span>
11
- <% end %>
12
- </p>
13
- <p class="commit-meta">
14
- <%= timeago_tag(commit.committed_at, force: true) %>
15
- </p>
16
- </div>
17
- <div class="commit-lock" >
18
- <%= link_to stack_commit_path(commit.stack, commit), class: 'action-lock-commit', data: {tooltip: t('commit.lock')} do %>
19
- <i class="icon icon--lock"></i>
20
- <% end %>
21
- <%= link_to stack_commit_path(commit.stack, commit), class: 'action-unlock-commit', data: {tooltip: t('commit.unlock'), confirm: t('commit.confirm_unlock')} do %>
22
- <i class="icon icon--lock"></i>
2
+ <% cache commit do %>
3
+ <% cache commit.author do %>
4
+ <%= render 'shipit/shared/author', author: commit.author %>
23
5
  <% end %>
24
- </div>
6
+
7
+ <%= render commit.status %>
8
+ <div class="commit-details">
9
+ <span class="commit-title"><%= render_commit_message_with_link commit %></span>
10
+ <p class="commit-meta">
11
+ <span class="sha"><%= render_commit_id_link(commit) %></span>
12
+ <% if commit.additions? && commit.deletions? %>
13
+ <span class="code-additions">+<%= commit.additions %></span>
14
+ <span class="code-deletions">-<%= commit.deletions %></span>
15
+ <% end %>
16
+ </p>
17
+ <p class="commit-meta">
18
+ <%= timeago_tag(commit.committed_at, force: true) %>
19
+ </p>
20
+ </div>
21
+ <div class="commit-lock" >
22
+ <%= link_to stack_commit_path(commit.stack, commit), class: 'action-lock-commit', data: {tooltip: t('commit.lock')} do %>
23
+ <i class="icon icon--lock"></i>
24
+ <% end %>
25
+ <%= link_to stack_commit_path(commit.stack, commit), class: 'action-unlock-commit', data: {tooltip: t('commit.unlock'), confirm: t('commit.confirm_unlock')} do %>
26
+ <i class="icon icon--lock"></i>
27
+ <% end %>
28
+ </div>
29
+ <% end %>
25
30
  <div class="commit-actions">
26
31
  <%= deploy_button(commit) %>
27
32
  </div>
@@ -1,34 +1,39 @@
1
1
  <%- read_only ||= false -%>
2
2
 
3
3
  <li class="task deploy" id="task-<%= deploy.id %>" data-status="<%= deploy.status %>">
4
- <%= render 'shipit/shared/author', author: deploy.author %>
5
- <a href="<%= stack_deploy_path(@stack, deploy) %>" class="status status--<%= deploy.status %>" data-tooltip="<%= deploy.status.capitalize %>">
6
- <i class="status__icon"></i>
7
- <span class="visually-hidden"><%= deploy.status %></span>
8
- </a>
9
- <div class="commit-details">
10
- <span class="commit-title">
11
- <a href="<%= stack_deploy_path(@stack, deploy) %>">
12
- <%= render_commit_message deploy.until_commit %>
13
- </a>
14
- </span>
15
- <p class="commit-meta">
16
- <%= deploy.rollback? ? 'rolled back' : 'deployed' %>
17
- <span class="sha"><%= link_to_github_deploy(deploy) %></span>
18
- <span class="code-additions">+<%= deploy.additions %></span>
19
- <span class="code-deletions">-<%= deploy.deletions %></span>
20
- </p>
21
- <p class="commit-meta">
22
- <% if read_only %>
23
- <span class="utc-timecode">on <%= deploy.created_at.strftime('%Y-%m-%d %H:%M:%S') %> UTC</span>
24
- <% else %>
25
- <%= timeago_tag(deploy.created_at, force: true) %>
26
- <% end %>
27
- <% if deploy.duration? %>
28
- in <%= deploy.duration %>
29
- <% end %>
30
- </p>
31
- </div>
4
+ <% cache deploy do %>
5
+ <% cache deploy.author do %>
6
+ <%= render 'shipit/shared/author', author: deploy.author %>
7
+ <% end %>
8
+ <a href="<%= stack_deploy_path(@stack, deploy) %>" class="status status--<%= deploy.status %>" data-tooltip="<%= deploy.status.capitalize %>">
9
+ <i class="status__icon"></i>
10
+ <span class="visually-hidden"><%= deploy.status %></span>
11
+ </a>
12
+ <div class="commit-details">
13
+ <span class="commit-title">
14
+ <a href="<%= stack_deploy_path(@stack, deploy) %>">
15
+ <%= render_commit_message deploy.until_commit %>
16
+ </a>
17
+ </span>
18
+ <p class="commit-meta">
19
+ <%= deploy.rollback? ? 'rolled back' : 'deployed' %>
20
+ <span class="sha"><%= link_to_github_deploy(deploy) %></span>
21
+ <span class="code-additions">+<%= deploy.additions %></span>
22
+ <span class="code-deletions">-<%= deploy.deletions %></span>
23
+ </p>
24
+ <p class="commit-meta">
25
+ <% if read_only %>
26
+ <span class="utc-timecode">on <%= deploy.created_at.strftime('%Y-%m-%d %H:%M:%S') %> UTC</span>
27
+ <% else %>
28
+ <%= timeago_tag(deploy.created_at, force: true) %>
29
+ <% end %>
30
+ <% if deploy.duration? %>
31
+ in <%= deploy.duration %>
32
+ <% end %>
33
+ </p>
34
+ </div>
35
+ <% end %>
36
+
32
37
  <% unless read_only %>
33
38
  <div class="commit-actions">
34
39
  <% if deploy.rollbackable? %>
@@ -0,0 +1,62 @@
1
+ <% if !stack.ignore_ci && !stack.ci_enabled? %>
2
+ <div class="banner">
3
+ <div class="banner__inner wrapper">
4
+ <div class="banner__content">
5
+ <h2 class="banner__title">Heads Up!</h2>
6
+ <p class="banner__text">
7
+ This stack is not configured for CI, but it currently requires a passing build to be able to deploy a commit.<br>
8
+ You can either <a href="https://developer.github.com/v3/repos/statuses/">configure your CI to push statuses to GitHub</a>,
9
+ or ignore CI and deploy any commits you want.
10
+ </p>
11
+ <%= button_to "Ignore CI", stack_path(stack, stack: {ignore_ci: true}, return_to: stack_path(stack)), method: :patch, class: 'banner__btn btn' %>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ <% end %>
16
+
17
+ <% if stack.inaccessible? %>
18
+ <div class="banner banner--red">
19
+ <div class="banner__inner wrapper">
20
+ <div class="banner__content">
21
+ <h2 class="banner__title">This repository or branch seems to be missing!</h2>
22
+ <p class="banner__text">
23
+ <%= link_to stack.github_repo_name, github_repo_url(stack.repo_owner, stack.repo_name) %>
24
+ has been inaccessible for <%= time_ago_in_words(stack.inaccessible_since) %>.
25
+
26
+ This could be a permission issue, or the repository have been deleted on GitHub.
27
+ </p>
28
+ </div>
29
+ </div>
30
+ </div>
31
+ <% end %>
32
+
33
+ <% if stack.locked? %>
34
+ <div class="banner banner--orange">
35
+ <div class="banner__inner wrapper">
36
+ <div class="banner__content">
37
+ <h2 class="banner__title">
38
+ <i class="icon icon--lock"></i>
39
+ Deploys are locked by <%= stack.lock_author.name %>
40
+ </h2>
41
+ <p class="banner__text">
42
+ <%= auto_link emojify(stack.lock_reason) %>
43
+ </p>
44
+ </div>
45
+ </div>
46
+ </div>
47
+ <% end %>
48
+
49
+ <% if stack.continuous_delivery_delayed? %>
50
+ <div class="banner">
51
+ <div class="banner__inner wrapper">
52
+ <div class="banner__content">
53
+ <h2 class="banner__title">Continuous Delivery Delayed!</h2>
54
+ <p class="banner__text">
55
+ Continuous Delivery for this stack is currently paused because
56
+ <%= link_to 'the pre-deploy checks failed', stack_commit_checks_path(stack, sha: stack.next_commit_to_deploy.sha) %>.
57
+ You can either wait for them to pass, or trigger a deploy manually.
58
+ </p>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ <% end %>
@@ -1,69 +1,7 @@
1
1
  <% subscribe events_path(channels: ["stack.#{@stack.id}"]), '#layout-content' %>
2
2
 
3
- <%= render partial: 'shipit/stacks/header', locals: { stack: @stack } %>
4
-
5
- <% if !@stack.ignore_ci && !@stack.ci_enabled? %>
6
- <div class="banner">
7
- <div class="banner__inner wrapper">
8
- <div class="banner__content">
9
- <h2 class="banner__title">Heads Up!</h2>
10
- <p class="banner__text">
11
- This stack is not configured for CI, but it currently requires a passing build to be able to deploy a commit.<br>
12
- You can either <a href="https://developer.github.com/v3/repos/statuses/">configure your CI to push statuses to GitHub</a>,
13
- or ignore CI and deploy any commits you want.
14
- </p>
15
- <%= button_to "Ignore CI", stack_path(@stack, stack: {ignore_ci: true}, return_to: stack_path(@stack)), method: :patch, class: 'banner__btn btn' %>
16
- </div>
17
- </div>
18
- </div>
19
- <% end %>
20
-
21
- <% if @stack.inaccessible? %>
22
- <div class="banner banner--red">
23
- <div class="banner__inner wrapper">
24
- <div class="banner__content">
25
- <h2 class="banner__title">This repository seems to be missing!</h2>
26
- <p class="banner__text">
27
- <%= link_to @stack.github_repo_name, github_repo_url(@stack.repo_owner, @stack.repo_name) %>
28
- has been inaccessible for <%= time_ago_in_words(@stack.inaccessible_since) %>.
29
-
30
- This could be a permission issue, or the repository have been deleted on GitHub.
31
- </p>
32
- </div>
33
- </div>
34
- </div>
35
- <% end %>
36
-
37
- <% if @stack.locked? %>
38
- <div class="banner banner--orange">
39
- <div class="banner__inner wrapper">
40
- <div class="banner__content">
41
- <h2 class="banner__title">
42
- <i class="icon icon--lock"></i>
43
- Deploys are locked by <%= @stack.lock_author.name %>
44
- </h2>
45
- <p class="banner__text">
46
- <%= auto_link emojify(@stack.lock_reason) %>
47
- </p>
48
- </div>
49
- </div>
50
- </div>
51
- <% end %>
52
-
53
- <% if @stack.continuous_delivery_delayed? %>
54
- <div class="banner">
55
- <div class="banner__inner wrapper">
56
- <div class="banner__content">
57
- <h2 class="banner__title">Continuous Delivery Delayed!</h2>
58
- <p class="banner__text">
59
- Continuous Delivery for this stack is currently paused because
60
- <%= link_to 'the pre-deploy checks failed', stack_commit_checks_path(@stack, sha: @stack.next_commit_to_deploy.sha) %>.
61
- You can either wait for them to pass, or trigger a deploy manually.
62
- </p>
63
- </div>
64
- </div>
65
- </div>
66
- <% end %>
3
+ <%= render partial: 'shipit/stacks/header', locals: {stack: @stack} %>
4
+ <%= render partial: 'shipit/stacks/banners', locals: {stack: @stack} %>
67
5
 
68
6
  <div class="wrapper">
69
7
  <section>
@@ -83,10 +21,14 @@
83
21
  </ul>
84
22
  </section>
85
23
 
86
- <section>
87
- <header class="section-header">
88
- <h2>Previous Deploys</h2>
89
- </header>
90
- <ul class="commit-list"><%= render @tasks %></ul>
91
- </section>
24
+ <% cache @stack do %>
25
+ <section>
26
+ <header class="section-header">
27
+ <h2>Previous Deploys</h2>
28
+ </header>
29
+ <ul class="commit-list">
30
+ <%= render @tasks %>
31
+ </ul>
32
+ </section>
33
+ <% end %>
92
34
  </div>
@@ -1,27 +1,31 @@
1
- <%- read_only ||= false -%>
1
+ <% cache task do %>
2
+ <%- read_only ||= false -%>
2
3
 
3
- <li class="task" id="task-<%= task.id %>" data-status="<%= task.status %>">
4
- <%= render 'shipit/shared/author', author: task.author %>
5
- <a href="<%= stack_task_path(@stack, task) %>" class="status status--<%= task.status %>" data-tooltip="<%= task.status.capitalize %>">
6
- <i class="status__icon"></i>
7
- <span class="visually-hidden"><%= task.status %></span>
8
- </a>
4
+ <li class="task" id="task-<%= task.id %>" data-status="<%= task.status %>">
5
+ <% cache task.author do %>
6
+ <%= render 'shipit/shared/author', author: task.author %>
7
+ <% end %>
8
+ <a href="<%= stack_task_path(@stack, task) %>" class="status status--<%= task.status %>" data-tooltip="<%= task.status.capitalize %>">
9
+ <i class="status__icon"></i>
10
+ <span class="visually-hidden"><%= task.status %></span>
11
+ </a>
9
12
 
10
- <div class="commit-details">
11
- <span class="commit-title">
12
- <a href="<%= stack_task_path(@stack, task) %>">
13
- <%= task.definition.action %>
14
- </a>
15
- </span>
16
- <p class="commit-meta">
17
- ran a command
18
- </p>
19
- <p class="commit-meta">
20
- <% if read_only %>
21
- <span class="utc-timecode">on <%= task.created_at.strftime('%Y-%m-%d %H:%M:%S') %> UTC</span>
22
- <% else %>
23
- <%= timeago_tag(task.created_at, force: true) %>
24
- <% end %>
25
- </p>
26
- </div>
27
- </li>
13
+ <div class="commit-details">
14
+ <span class="commit-title">
15
+ <a href="<%= stack_task_path(@stack, task) %>">
16
+ <%= task.definition.action %>
17
+ </a>
18
+ </span>
19
+ <p class="commit-meta">
20
+ ran a command
21
+ </p>
22
+ <p class="commit-meta">
23
+ <% if read_only %>
24
+ <span class="utc-timecode">on <%= task.created_at.strftime('%Y-%m-%d %H:%M:%S') %> UTC</span>
25
+ <% else %>
26
+ <%= timeago_tag(task.created_at, force: true) %>
27
+ <% end %>
28
+ </p>
29
+ </div>
30
+ </li>
31
+ <% end %>
@@ -0,0 +1,5 @@
1
+ class IndexPullRequestsOnMergeStatus < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_index :pull_requests, :merge_status
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class IndexCommitsOnStackIdAndSha < ActiveRecord::Migration[5.1]
2
+ def change
3
+ add_index :commits, %i(sha stack_id), unique: true
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ class FixTasksIndexByStatus < ActiveRecord::Migration[5.1]
2
+ def up
3
+ remove_index :tasks, name: :index_tasks_by_stack_and_status
4
+ add_index :tasks, [:stack_id, :status, :type], name: :index_tasks_by_stack_and_status
5
+ end
6
+
7
+ def down
8
+ remove_index :tasks, name: :index_tasks_by_stack_and_status
9
+ add_index :tasks, [:type, :stack_id, :status], name: :index_tasks_by_stack_and_status
10
+ end
11
+ end
data/lib/shipit.rb CHANGED
@@ -130,7 +130,7 @@ module Shipit
130
130
  end
131
131
 
132
132
  def user_access_tokens_key
133
- secrets.user_access_tokens_key.presence || secrets.secret_key_base
133
+ (secrets.user_access_tokens_key.presence || secrets.secret_key_base).byteslice(0, 32)
134
134
  end
135
135
 
136
136
  def host
@@ -1,3 +1,3 @@
1
1
  module Shipit
2
- VERSION = '0.18.1'.freeze
2
+ VERSION = '0.19.0'.freeze
3
3
  end
@@ -23,6 +23,8 @@ module Shipit
23
23
  # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
24
24
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
25
25
  # config.i18n.default_locale = :de
26
+
27
+ Rails.application.config.active_record.belongs_to_required_by_default = true
26
28
  end
27
29
  end
28
30
 
Binary file
@@ -10,33 +10,33 @@
10
10
  #
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
- ActiveRecord::Schema.define(version: 20170320124156) do
13
+ ActiveRecord::Schema.define(version: 20170524125249) do
14
14
 
15
15
  create_table "api_clients", force: :cascade do |t|
16
- t.text "permissions", limit: 65535
17
- t.integer "creator_id", limit: 4
18
- t.datetime "created_at", null: false
19
- t.datetime "updated_at", null: false
20
- t.string "name", limit: 255, default: ""
21
- t.integer "stack_id", limit: 4
16
+ t.text "permissions", limit: 65535
17
+ t.integer "creator_id", limit: 4
18
+ t.datetime "created_at", null: false
19
+ t.datetime "updated_at", null: false
20
+ t.string "name", limit: 255, default: ""
21
+ t.integer "stack_id", limit: 4
22
22
  t.index ["creator_id"], name: "index_api_clients_on_creator_id"
23
23
  end
24
24
 
25
25
  create_table "commit_deployment_statuses", force: :cascade do |t|
26
- t.integer "commit_deployment_id"
27
- t.string "status"
28
- t.integer "github_id"
29
- t.string "api_url"
30
- t.datetime "created_at", null: false
31
- t.datetime "updated_at", null: false
26
+ t.integer "commit_deployment_id"
27
+ t.string "status"
28
+ t.integer "github_id"
29
+ t.string "api_url"
30
+ t.datetime "created_at", null: false
31
+ t.datetime "updated_at", null: false
32
32
  t.index ["commit_deployment_id"], name: "index_commit_deployment_statuses_on_commit_deployment_id"
33
33
  end
34
34
 
35
35
  create_table "commit_deployments", force: :cascade do |t|
36
- t.integer "commit_id"
37
- t.integer "task_id"
38
- t.integer "github_id"
39
- t.string "api_url"
36
+ t.integer "commit_id"
37
+ t.integer "task_id"
38
+ t.integer "github_id"
39
+ t.string "api_url"
40
40
  t.datetime "created_at", null: false
41
41
  t.datetime "updated_at", null: false
42
42
  t.index ["commit_id", "task_id"], name: "index_commit_deployments_on_commit_id_and_task_id", unique: true
@@ -44,111 +44,113 @@ ActiveRecord::Schema.define(version: 20170320124156) do
44
44
  end
45
45
 
46
46
  create_table "commits", force: :cascade do |t|
47
- t.integer "stack_id", limit: 4, null: false
48
- t.integer "author_id", limit: 4, null: false
49
- t.integer "committer_id", limit: 4, null: false
50
- t.string "sha", limit: 40, null: false
51
- t.text "message", limit: 65535, null: false
47
+ t.integer "stack_id", limit: 4, null: false
48
+ t.integer "author_id", limit: 4, null: false
49
+ t.integer "committer_id", limit: 4, null: false
50
+ t.string "sha", limit: 40, null: false
51
+ t.text "message", limit: 65535, null: false
52
52
  t.datetime "created_at"
53
53
  t.datetime "updated_at"
54
- t.boolean "detached", default: false, null: false
55
- t.datetime "authored_at", null: false
56
- t.datetime "committed_at", null: false
57
- t.integer "additions", limit: 4
58
- t.integer "deletions", limit: 4
59
- t.integer "pull_request_number"
60
- t.string "pull_request_title", limit: 1024
61
- t.integer "pull_request_id"
62
- t.boolean "locked", default: false, null: false
54
+ t.boolean "detached", default: false, null: false
55
+ t.datetime "authored_at", null: false
56
+ t.datetime "committed_at", null: false
57
+ t.integer "additions", limit: 4
58
+ t.integer "deletions", limit: 4
59
+ t.integer "pull_request_number"
60
+ t.string "pull_request_title", limit: 1024
61
+ t.integer "pull_request_id"
62
+ t.boolean "locked", default: false, null: false
63
63
  t.index ["author_id"], name: "index_commits_on_author_id"
64
64
  t.index ["committer_id"], name: "index_commits_on_committer_id"
65
65
  t.index ["created_at"], name: "index_commits_on_created_at"
66
+ t.index ["sha", "stack_id"], name: "index_commits_on_sha_and_stack_id", unique: true
66
67
  t.index ["stack_id"], name: "index_commits_on_stack_id"
67
68
  end
68
69
 
69
70
  create_table "deliveries", force: :cascade do |t|
70
- t.integer "hook_id", limit: 4, null: false
71
- t.string "status", limit: 50, default: "pending", null: false
72
- t.string "url", limit: 4096, null: false
73
- t.string "content_type", limit: 255, null: false
74
- t.string "event", limit: 50, null: false
75
- t.text "payload", limit: 16777215, null: false
76
- t.integer "response_code", limit: 4
77
- t.text "response_headers", limit: 65535
78
- t.text "response_body", limit: 65535
71
+ t.integer "hook_id", limit: 4, null: false
72
+ t.string "status", limit: 50, default: "pending", null: false
73
+ t.string "url", limit: 4096, null: false
74
+ t.string "content_type", limit: 255, null: false
75
+ t.string "event", limit: 50, null: false
76
+ t.text "payload", limit: 16777215, null: false
77
+ t.integer "response_code", limit: 4
78
+ t.text "response_headers", limit: 65535
79
+ t.text "response_body", limit: 65535
79
80
  t.datetime "delivered_at"
80
- t.datetime "created_at", null: false
81
- t.datetime "updated_at", null: false
81
+ t.datetime "created_at", null: false
82
+ t.datetime "updated_at", null: false
82
83
  t.index ["created_at"], name: "index_deliveries_on_created_at"
83
84
  t.index ["hook_id", "event", "status"], name: "index_deliveries_on_hook_id_and_event_and_status"
84
85
  t.index ["status", "event"], name: "index_deliveries_on_status_and_event"
85
86
  end
86
87
 
87
88
  create_table "github_hooks", force: :cascade do |t|
88
- t.integer "stack_id", limit: 4
89
- t.integer "github_id", limit: 4
90
- t.string "event", limit: 50, null: false
89
+ t.integer "stack_id", limit: 4
90
+ t.integer "github_id", limit: 4
91
+ t.string "event", limit: 50, null: false
91
92
  t.datetime "created_at"
92
93
  t.datetime "updated_at"
93
- t.string "secret", limit: 255
94
- t.string "api_url", limit: 255
95
- t.string "type", limit: 255
96
- t.string "organization", limit: 39
94
+ t.string "secret", limit: 255
95
+ t.string "api_url", limit: 255
96
+ t.string "type", limit: 255
97
+ t.string "organization", limit: 39
97
98
  t.index ["organization", "event"], name: "index_github_hooks_on_organization_and_event", unique: true
98
99
  t.index ["stack_id", "event"], name: "index_github_hooks_on_stack_id_and_event", unique: true
99
100
  end
100
101
 
101
102
  create_table "hooks", force: :cascade do |t|
102
- t.integer "stack_id", limit: 4
103
- t.string "delivery_url", limit: 4096, null: false
104
- t.string "content_type", limit: 4, default: "json", null: false
105
- t.string "secret", limit: 255
106
- t.string "events", limit: 255, default: "", null: false
107
- t.boolean "insecure_ssl", default: false, null: false
108
- t.datetime "created_at", null: false
109
- t.datetime "updated_at", null: false
103
+ t.integer "stack_id", limit: 4
104
+ t.string "delivery_url", limit: 4096, null: false
105
+ t.string "content_type", limit: 4, default: "json", null: false
106
+ t.string "secret", limit: 255
107
+ t.string "events", limit: 255, default: "", null: false
108
+ t.boolean "insecure_ssl", default: false, null: false
109
+ t.datetime "created_at", null: false
110
+ t.datetime "updated_at", null: false
110
111
  t.index ["stack_id"], name: "index_hooks_on_stack_id"
111
112
  end
112
113
 
113
114
  create_table "memberships", force: :cascade do |t|
114
- t.integer "team_id", limit: 4
115
- t.integer "user_id", limit: 4
116
- t.datetime "created_at", null: false
117
- t.datetime "updated_at", null: false
115
+ t.integer "team_id", limit: 4
116
+ t.integer "user_id", limit: 4
117
+ t.datetime "created_at", null: false
118
+ t.datetime "updated_at", null: false
118
119
  t.index ["team_id", "user_id"], name: "index_memberships_on_team_id_and_user_id", unique: true
119
120
  t.index ["user_id"], name: "index_memberships_on_user_id"
120
121
  end
121
122
 
122
123
  create_table "output_chunks", force: :cascade do |t|
123
- t.integer "task_id", limit: 4
124
- t.text "text", limit: 16777215
124
+ t.integer "task_id", limit: 4
125
+ t.text "text", limit: 16777215
125
126
  t.datetime "created_at"
126
127
  t.datetime "updated_at"
127
128
  t.index ["task_id"], name: "index_output_chunks_on_task_id"
128
129
  end
129
130
 
130
131
  create_table "pull_requests", force: :cascade do |t|
131
- t.integer "stack_id", null: false
132
- t.integer "number", null: false
133
- t.string "title", limit: 256
134
- t.integer "github_id", limit: 8
135
- t.string "api_url", limit: 1024
136
- t.string "state"
137
- t.integer "head_id"
138
- t.boolean "mergeable"
139
- t.integer "additions", default: 0, null: false
140
- t.integer "deletions", default: 0, null: false
141
- t.string "merge_status", limit: 30, null: false
142
- t.string "rejection_reason"
143
- t.datetime "merge_requested_at", null: false
144
- t.integer "merge_requested_by_id"
145
- t.datetime "created_at", null: false
146
- t.datetime "updated_at", null: false
147
- t.string "branch"
132
+ t.integer "stack_id", null: false
133
+ t.integer "number", null: false
134
+ t.string "title", limit: 256
135
+ t.integer "github_id", limit: 8
136
+ t.string "api_url", limit: 1024
137
+ t.string "state"
138
+ t.integer "head_id"
139
+ t.boolean "mergeable"
140
+ t.integer "additions", default: 0, null: false
141
+ t.integer "deletions", default: 0, null: false
142
+ t.string "merge_status", limit: 30, null: false
143
+ t.string "rejection_reason"
144
+ t.datetime "merge_requested_at", null: false
145
+ t.integer "merge_requested_by_id"
146
+ t.datetime "created_at", null: false
147
+ t.datetime "updated_at", null: false
148
+ t.string "branch"
148
149
  t.datetime "revalidated_at"
149
150
  t.datetime "merged_at"
150
151
  t.index ["head_id"], name: "index_pull_requests_on_head_id"
151
152
  t.index ["merge_requested_by_id"], name: "index_pull_requests_on_merge_requested_by_id"
153
+ t.index ["merge_status"], name: "index_pull_requests_on_merge_status"
152
154
  t.index ["stack_id", "github_id"], name: "index_pull_requests_on_stack_id_and_github_id", unique: true
153
155
  t.index ["stack_id", "merge_status"], name: "index_pull_requests_on_stack_id_and_merge_status"
154
156
  t.index ["stack_id", "number"], name: "index_pull_requests_on_stack_id_and_number", unique: true
@@ -156,94 +158,94 @@ ActiveRecord::Schema.define(version: 20170320124156) do
156
158
  end
157
159
 
158
160
  create_table "stacks", force: :cascade do |t|
159
- t.string "repo_name", limit: 100, null: false
160
- t.string "repo_owner", limit: 39, null: false
161
- t.string "environment", limit: 50, default: "production", null: false
161
+ t.string "repo_name", limit: 100, null: false
162
+ t.string "repo_owner", limit: 39, null: false
163
+ t.string "environment", limit: 50, default: "production", null: false
162
164
  t.datetime "created_at"
163
165
  t.datetime "updated_at"
164
- t.string "branch", limit: 255, default: "master", null: false
165
- t.string "deploy_url", limit: 255
166
- t.string "lock_reason", limit: 4096
167
- t.integer "tasks_count", limit: 4, default: 0, null: false
168
- t.boolean "continuous_deployment", default: false, null: false
169
- t.integer "undeployed_commits_count", limit: 4, default: 0, null: false
170
- t.text "cached_deploy_spec", limit: 65535
171
- t.integer "lock_author_id", limit: 4
172
- t.boolean "ignore_ci"
166
+ t.string "branch", limit: 255, default: "master", null: false
167
+ t.string "deploy_url", limit: 255
168
+ t.string "lock_reason", limit: 4096
169
+ t.integer "tasks_count", limit: 4, default: 0, null: false
170
+ t.boolean "continuous_deployment", default: false, null: false
171
+ t.integer "undeployed_commits_count", limit: 4, default: 0, null: false
172
+ t.text "cached_deploy_spec", limit: 65535
173
+ t.integer "lock_author_id", limit: 4
174
+ t.boolean "ignore_ci"
173
175
  t.datetime "inaccessible_since"
174
- t.integer "estimated_deploy_duration", default: 1, null: false
176
+ t.integer "estimated_deploy_duration", default: 1, null: false
175
177
  t.datetime "continuous_delivery_delayed_since"
176
178
  t.datetime "locked_since"
177
- t.boolean "merge_queue_enabled", default: false, null: false
179
+ t.boolean "merge_queue_enabled", default: false, null: false
178
180
  t.datetime "last_deployed_at"
179
181
  t.index ["repo_owner", "repo_name", "environment"], name: "stack_unicity", unique: true
180
182
  end
181
183
 
182
184
  create_table "statuses", force: :cascade do |t|
183
- t.string "state", limit: 255
184
- t.string "target_url", limit: 255
185
- t.text "description", limit: 65535
186
- t.string "context", limit: 255, default: "default", null: false
187
- t.integer "commit_id", limit: 4
185
+ t.string "state", limit: 255
186
+ t.string "target_url", limit: 255
187
+ t.text "description", limit: 65535
188
+ t.string "context", limit: 255, default: "default", null: false
189
+ t.integer "commit_id", limit: 4
188
190
  t.datetime "created_at"
189
191
  t.datetime "updated_at"
190
- t.integer "stack_id", null: false
192
+ t.integer "stack_id", null: false
191
193
  t.index ["commit_id"], name: "index_statuses_on_commit_id"
192
194
  end
193
195
 
194
196
  create_table "tasks", force: :cascade do |t|
195
- t.integer "stack_id", limit: 4, null: false
196
- t.integer "since_commit_id", limit: 4, null: false
197
- t.integer "until_commit_id", limit: 4, null: false
198
- t.string "status", limit: 10, default: "pending", null: false
197
+ t.integer "stack_id", limit: 4, null: false
198
+ t.integer "since_commit_id", limit: 4, null: false
199
+ t.integer "until_commit_id", limit: 4, null: false
200
+ t.string "status", limit: 10, default: "pending", null: false
199
201
  t.datetime "created_at"
200
202
  t.datetime "updated_at"
201
- t.integer "user_id", limit: 4
202
- t.boolean "rolled_up", default: false, null: false
203
- t.string "type", limit: 20
204
- t.integer "parent_id", limit: 4
205
- t.integer "additions", limit: 4, default: 0
206
- t.integer "deletions", limit: 4, default: 0
207
- t.text "definition", limit: 65535
208
- t.binary "gzip_output"
209
- t.boolean "rollback_once_aborted", default: false, null: false
210
- t.text "env"
211
- t.integer "confirmations", default: 0, null: false
212
- t.boolean "allow_concurrency", default: false, null: false
203
+ t.integer "user_id", limit: 4
204
+ t.boolean "rolled_up", default: false, null: false
205
+ t.string "type", limit: 20
206
+ t.integer "parent_id", limit: 4
207
+ t.integer "additions", limit: 4, default: 0
208
+ t.integer "deletions", limit: 4, default: 0
209
+ t.text "definition", limit: 65535
210
+ t.binary "gzip_output"
211
+ t.boolean "rollback_once_aborted", default: false, null: false
212
+ t.text "env"
213
+ t.integer "confirmations", default: 0, null: false
214
+ t.boolean "allow_concurrency", default: false, null: false
213
215
  t.datetime "started_at"
214
216
  t.datetime "ended_at"
215
217
  t.index ["rolled_up", "created_at", "status"], name: "index_tasks_on_rolled_up_and_created_at_and_status"
216
218
  t.index ["since_commit_id"], name: "index_tasks_on_since_commit_id"
217
219
  t.index ["stack_id", "allow_concurrency", "status"], name: "index_active_tasks"
218
220
  t.index ["stack_id", "allow_concurrency"], name: "index_tasks_on_stack_id_and_allow_concurrency"
221
+ t.index ["stack_id", "status", "type"], name: "index_tasks_by_stack_and_status"
219
222
  t.index ["type", "stack_id", "parent_id"], name: "index_tasks_by_stack_and_parent"
220
- t.index ["type", "stack_id", "status"], name: "index_tasks_by_stack_and_status"
221
223
  t.index ["until_commit_id"], name: "index_tasks_on_until_commit_id"
222
224
  t.index ["user_id"], name: "index_tasks_on_user_id"
223
225
  end
224
226
 
225
227
  create_table "teams", force: :cascade do |t|
226
- t.integer "github_id", limit: 4
227
- t.string "api_url", limit: 255
228
- t.string "slug", limit: 50
229
- t.string "name", limit: 255
230
- t.string "organization", limit: 39
231
- t.datetime "created_at", null: false
232
- t.datetime "updated_at", null: false
228
+ t.integer "github_id", limit: 4
229
+ t.string "api_url", limit: 255
230
+ t.string "slug", limit: 50
231
+ t.string "name", limit: 255
232
+ t.string "organization", limit: 39
233
+ t.datetime "created_at", null: false
234
+ t.datetime "updated_at", null: false
233
235
  t.index ["organization", "slug"], name: "index_teams_on_organization_and_slug", unique: true
234
236
  end
235
237
 
236
238
  create_table "users", force: :cascade do |t|
237
- t.integer "github_id", limit: 4
238
- t.string "name", limit: 255, null: false
239
- t.string "email", limit: 255
240
- t.string "login", limit: 39
241
- t.string "api_url", limit: 255
239
+ t.integer "github_id", limit: 4
240
+ t.string "name", limit: 255, null: false
241
+ t.string "email", limit: 255
242
+ t.string "login", limit: 39
243
+ t.string "api_url", limit: 255
242
244
  t.datetime "created_at"
243
245
  t.datetime "updated_at"
244
- t.string "avatar_url", limit: 255
245
- t.string "encrypted_github_access_token"
246
- t.string "encrypted_github_access_token_iv"
246
+ t.string "avatar_url", limit: 255
247
+ t.string "encrypted_github_access_token"
248
+ t.string "encrypted_github_access_token_iv"
247
249
  t.index ["github_id"], name: "index_users_on_github_id"
248
250
  t.index ["login"], name: "index_users_on_login"
249
251
  t.index ["updated_at"], name: "index_users_on_updated_at"
@@ -152,10 +152,10 @@ module Shipit
152
152
  )
153
153
  end
154
154
 
155
- def create_chunks
156
- 100.times.map do
155
+ def write_output(task)
156
+ 100.times do
157
157
  status = "\x1b[%s;1m[ %s ]\x1b[0m" % [["31", "error"], ["32", "success"]].sample
158
- OutputChunk.new(text: "[ #{Faker::Date.backward} ] #{status} #{Faker::Lorem.paragraph}\n")
158
+ task.write("[ #{Faker::Date.backward} ] #{status} #{Faker::Lorem.paragraph}\n")
159
159
  end
160
160
  end
161
161
 
@@ -165,28 +165,29 @@ module Shipit
165
165
  since_commit_id: commits.first.id,
166
166
  until_commit_id: commits.last.id,
167
167
  status: "success",
168
- chunks: create_chunks,
169
168
  additions: Faker::Number.number(3),
170
169
  deletions: Faker::Number.number(3),
171
170
  started_at: Random.rand(15.minutes.to_i).seconds.ago,
172
171
  ended_at: Time.now.utc,
173
172
  user: users.sample,
174
173
  )
174
+ write_output(deploy)
175
175
  deploy.write("$ cap production deploy SHA=yolo")
176
176
  end
177
177
 
178
178
  last_deploy = stack.deploys.last
179
- stack.rollbacks.create!(
179
+ rollback = stack.rollbacks.create!(
180
+ deploy: last_deploy,
180
181
  since_commit_id: last_deploy.until_commit_id,
181
182
  until_commit_id: last_deploy.since_commit_id,
182
183
  status: 'success',
183
184
  user: users.sample,
184
- chunks: create_chunks,
185
185
  started_at: Random.rand(15.minutes.to_i).seconds.ago,
186
186
  ended_at: Time.now.utc,
187
187
  )
188
+ write_output(rollback)
188
189
 
189
- stack.tasks.create!(
190
+ task = stack.tasks.create!(
190
191
  since_commit_id: stack.last_deployed_commit.id,
191
192
  until_commit_id: stack.last_deployed_commit.id,
192
193
  status: "success",
@@ -196,9 +197,9 @@ module Shipit
196
197
  'description' => 'Restart unicorns and resques',
197
198
  'steps' => ['cap $ENVIRONMENT restart'],
198
199
  ),
199
- chunks: create_chunks,
200
200
  started_at: Random.rand(15.minutes.to_i).seconds.ago,
201
201
  ended_at: Time.now.utc,
202
202
  )
203
+ write_output(rollback)
203
204
  end
204
205
  end
Binary file
@@ -16,9 +16,9 @@ module Shipit
16
16
  end
17
17
 
18
18
  test "#pull_request? detects pull requests with unusual branch names" do
19
- @pr.message = "Merge pull request #7 from Shopify/bump-to-v1.0.1\n\nBump to v1.0.1"
19
+ @pr.message = "Merge pull request #7 from Shopify/bump-👉-v1.0.1\n\nBump 👉 v1.0.1"
20
20
  assert @pr.pull_request?
21
- assert_equal "Bump to v1.0.1", @pr.pull_request_title
21
+ assert_equal "Bump 👉 v1.0.1", @pr.pull_request_title
22
22
  end
23
23
 
24
24
  test "#pull_request_number extract the pull request id from the message" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shipit-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.18.1
4
+ version: 0.19.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jean Boussier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-09 00:00:00.000000000 Z
11
+ date: 2017-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -612,6 +612,7 @@ files:
612
612
  - app/views/shipit/pull_requests/_pull_request.html.erb
613
613
  - app/views/shipit/pull_requests/index.html.erb
614
614
  - app/views/shipit/shared/_author.html.erb
615
+ - app/views/shipit/stacks/_banners.html.erb
615
616
  - app/views/shipit/stacks/_header.html.erb
616
617
  - app/views/shipit/stacks/index.html.erb
617
618
  - app/views/shipit/stacks/new.html.erb
@@ -671,6 +672,9 @@ files:
671
672
  - db/migrate/20170310164315_add_merged_at_on_pull_requests.rb
672
673
  - db/migrate/20170314145604_add_last_deployed_at_to_stack.rb
673
674
  - db/migrate/20170320124156_add_locked_to_commits.rb
675
+ - db/migrate/20170524084548_index_pull_requests_on_merge_status.rb
676
+ - db/migrate/20170524104615_index_commits_on_stack_id_and_sha.rb
677
+ - db/migrate/20170524125249_fix_tasks_index_by_status.rb
674
678
  - lib/shipit-engine.rb
675
679
  - lib/shipit.rb
676
680
  - lib/shipit/command.rb