Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/controllers/shipit/api/locks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@ class LocksController < BaseController

params do
requires :reason, String, presence: true
accepts :lock_level, String
Comment thread
mdeloupy marked this conversation as resolved.
end
def create
if stack.locked?
render json: {message: 'Already locked'}, status: :conflict
else
stack.lock(params.reason, current_user)
stack.lock(params.reason, current_user, lock_level: params.lock_level)
render_resource stack
end
end

params do
requires :reason, String, presence: true
accepts :lock_level, String
end
def update
stack.lock(params.reason, current_user)
stack.lock(params.reason, current_user, lock_level: params.lock_level)
render_resource stack
end

Expand Down
14 changes: 11 additions & 3 deletions app/models/shipit/stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ def blank?
ENVIRONMENT_MAX_SIZE = 50
REQUIRED_HOOKS = %i(push status).freeze

LOCK_LEVELS = %w(enforced advisory).freeze
enum lock_level: LOCK_LEVELS.zip(LOCK_LEVELS).to_h

has_many :commits, dependent: :destroy
has_many :pull_requests, dependent: :destroy
has_many :tasks, dependent: :destroy
Expand Down Expand Up @@ -386,16 +389,21 @@ def active_task
end

def locked?
lock_reason.present? && lock_level != 'advisory'
Comment thread
mdeloupy marked this conversation as resolved.
Outdated
end

def soft_locked?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me without looking at the implementation whether soft_locked? means "locked, and level == advisory", or just "locked, and level is at least advisory".

lock_reason.present?
end

def lock(reason, user)
params = {lock_reason: reason, lock_author: user}
def lock(reason, user, lock_level: 'enforced')
lock_level ||= 'enforced'
Comment thread
mdeloupy marked this conversation as resolved.
Outdated
params = {lock_reason: reason, lock_author: user, lock_level: lock_level}
update!(params)
end

def unlock
update!(lock_reason: nil, lock_author: nil, locked_since: nil)
update!(lock_reason: nil, lock_author: nil, locked_since: nil, lock_level: nil)
end

def to_param
Expand Down
8 changes: 4 additions & 4 deletions app/serializers/shipit/stack_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class StackSerializer < ActiveModel::Serializer
has_one :lock_author
attributes :id, :repo_owner, :repo_name, :environment, :html_url, :url, :tasks_url, :deploy_url, :pull_requests_url,
:deploy_spec, :undeployed_commits_count, :is_locked, :lock_reason, :continuous_deployment, :created_at,
:updated_at, :locked_since, :last_deployed_at, :branch, :merge_queue_enabled
:updated_at, :locked_since, :last_deployed_at, :branch, :merge_queue_enabled, :lock_level

def url
api_stack_url(object)
Expand All @@ -28,15 +28,15 @@ def is_locked
end

def include_lock_reason?
object.locked?
object.soft_locked?
end

def include_lock_author?
object.locked?
object.soft_locked?
end

def include_locked_since?
object.locked?
object.soft_locked?
end

def deploy_spec
Expand Down
16 changes: 16 additions & 0 deletions app/views/shipit/stacks/_banners.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,22 @@
</div>
</div>
</div>
<% elsif stack.soft_locked? %>
<div class="banner banner--orange">
<div class="banner__inner wrapper">
<div class="banner__content">
<h2 class="banner__title">
<%= stack.lock_author.name %> posted the following warning message
<% unless stack.locked_since.nil? %>
<%= timeago_tag(stack.locked_since, force: true) %>
<% end %>
</h2>
<p class="banner__text">
<%= auto_link emojify(stack.lock_reason) %>
</p>
</div>
</div>
</div>
<% end %>

<% if stack.continuous_delivery_delayed? %>
Expand Down
5 changes: 5 additions & 0 deletions db/migrate/20190611152822_add_lock_level_to_stacks.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddLockLevelToStacks < ActiveRecord::Migration[5.2]
def change
add_column :stacks, :lock_level, :string
end
end
Binary file added dump.rdb
Binary file not shown.
21 changes: 21 additions & 0 deletions test/controllers/api/locks_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ class LocksControllerTest < ActionController::TestCase
assert_response :ok
assert_json 'is_locked', true
assert_json 'lock_reason', 'Just for fun!'
assert_json 'lock_level', 'enforced'
assert_json { |json| assert_not_nil json['locked_since'] }
end

test "#create sets a lock message if lock_level is advisory" do
post :create, params: {stack_id: @stack.to_param, reason: 'Just for fun!', lock_level: 'advisory'}
assert_response :ok
assert_json 'is_locked', false
assert_json 'lock_reason', 'Just for fun!'
assert_json 'lock_level', 'advisory'
assert_json { |json| assert_not_nil json['locked_since'] }
end

Expand All @@ -27,6 +37,7 @@ class LocksControllerTest < ActionController::TestCase
assert_response :ok
assert_json 'is_locked', true
assert_json 'lock_reason', 'Just for fun!'
assert_json 'lock_level', 'enforced'
end

test "#update can override a previous lock" do
Expand All @@ -35,6 +46,15 @@ class LocksControllerTest < ActionController::TestCase
assert_response :ok
assert_json 'is_locked', true
assert_json 'lock_reason', 'Just for fun!'
assert_json 'lock_level', 'enforced'
end

test "#update sets a lock with a lock_level if passed as a param" do
put :update, params: {stack_id: @stack.to_param, reason: 'Just for fun!', lock_level: 'advisory'}
assert_response :ok
assert_json 'is_locked', false
assert_json 'lock_reason', 'Just for fun!'
assert_json 'lock_level', 'advisory'
end

test "#update does not override previous locked_since" do
Expand All @@ -50,6 +70,7 @@ class LocksControllerTest < ActionController::TestCase
delete :destroy, params: {stack_id: @stack.to_param}
assert_response :ok
assert_json 'is_locked', false
assert_json 'lock_level', nil
assert_json { |json| assert_nil json['locked_since'] }
end
end
Expand Down
11 changes: 6 additions & 5 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 2019_05_02_020249) do
ActiveRecord::Schema.define(version: 2019_06_11_152822) do

create_table "api_clients", force: :cascade do |t|
t.text "permissions", limit: 65535
Expand Down Expand Up @@ -185,9 +185,9 @@
t.bigint "github_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["commit_id", "github_id"], name: "index_deploy_statuses_on_commit_id_and_github_id"
t.index ["stack_id", "commit_id"], name: "index_deploy_statuses_on_stack_id_and_commit_id"
t.index ["user_id"], name: "index_deploy_statuses_on_user_id"
t.index ["commit_id", "github_id"], name: "index_release_statuses_on_commit_id_and_github_id"
t.index ["stack_id", "commit_id"], name: "index_release_statuses_on_stack_id_and_commit_id"
t.index ["user_id"], name: "index_release_statuses_on_user_id"
Comment thread
mdeloupy marked this conversation as resolved.
end

create_table "stacks", force: :cascade do |t|
Expand All @@ -211,6 +211,7 @@
t.datetime "locked_since"
t.boolean "merge_queue_enabled", default: false, null: false
t.datetime "last_deployed_at"
t.string "lock_level"
t.index ["repo_owner", "repo_name", "environment"], name: "stack_unicity", unique: true
end

Expand Down Expand Up @@ -240,7 +241,7 @@
t.integer "additions", limit: 4, default: 0
t.integer "deletions", limit: 4, default: 0
t.text "definition", limit: 65535
t.binary "gzip_output"
t.binary "gzip_output", limit: 16777215
t.boolean "rollback_once_aborted", default: false, null: false
t.text "env"
t.integer "confirmations", default: 0, null: false
Expand Down