shipit-engine 0.18.1 → 0.19.0

Sign up to get free protection for your applications and to get access to all the features.
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