From be9aa7f19474424991923f128053e2523fa166d8 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Tue, 26 Jul 2016 09:35:47 +0200 Subject: [PATCH] Add an URL field to Environments This MR adds a string (thus max 255 chars) field to the enviroments table to expose it later in other features. --- CHANGELOG | 1 + .../projects/environments_controller.rb | 23 ++++++--- app/models/environment.rb | 4 ++ .../projects/environments/_form.html.haml | 29 ++++++++--- .../projects/environments/edit.html.haml | 6 +++ app/views/projects/environments/new.html.haml | 14 ++---- .../projects/environments/show.html.haml | 2 +- config/routes.rb | 2 +- ...5083350_add_external_url_to_enviroments.rb | 12 +++++ db/schema.rb | 3 +- .../projects/environments_controller_spec.rb | 50 +++++++++++++++++++ spec/factories/environments.rb | 1 + spec/features/environments_spec.rb | 4 +- spec/models/environment_spec.rb | 10 ++++ 14 files changed, 133 insertions(+), 28 deletions(-) create mode 100644 app/views/projects/environments/edit.html.haml create mode 100644 db/migrate/20160725083350_add_external_url_to_enviroments.rb create mode 100644 spec/controllers/projects/environments_controller_spec.rb diff --git a/CHANGELOG b/CHANGELOG index 2b04c15b827..0292df068fa 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -9,6 +9,7 @@ v 8.11.0 (unreleased) - Add support for using RequestStore within Sidekiq tasks via SIDEKIQ_REQUEST_STORE env variable - Optimize maximum user access level lookup in loading of notes - Add "No one can push" as an option for protected branches. !5081 + - Environments have an url to link to - Limit git rev-list output count to one in forced push check - Clean up unused routes (Josef Strzibny) - Add green outline to New Branch button. !5447 (winniehell) diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 4b433796161..1f5c7506212 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -2,8 +2,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController layout 'project' before_action :authorize_read_environment! before_action :authorize_create_environment!, only: [:new, :create] - before_action :authorize_update_environment!, only: [:destroy] - before_action :environment, only: [:show, :destroy] + before_action :authorize_update_environment!, only: [:edit, :destroy] + before_action :environment, only: [:show, :edit, :update, :destroy] def index @environments = project.environments @@ -17,13 +17,24 @@ class Projects::EnvironmentsController < Projects::ApplicationController @environment = project.environments.new end + def edit + end + def create - @environment = project.environments.create(create_params) + @environment = project.environments.create(environment_params) if @environment.persisted? redirect_to namespace_project_environment_path(project.namespace, project, @environment) else - render 'new' + render :new + end + end + + def update + if @environment.update(environment_params) + redirect_to namespace_project_environment_path(project.namespace, project, @environment) + else + render :edit end end @@ -39,8 +50,8 @@ class Projects::EnvironmentsController < Projects::ApplicationController private - def create_params - params.require(:environment).permit(:name) + def environment_params + params.require(:environment).permit(:name, :external_url) end def environment diff --git a/app/models/environment.rb b/app/models/environment.rb index ac3a571a1f3..9eff0fdab03 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -10,6 +10,10 @@ class Environment < ActiveRecord::Base format: { with: Gitlab::Regex.environment_name_regex, message: Gitlab::Regex.environment_name_regex_message } + validates :external_url, + uniqueness: { scope: :project_id }, + length: { maximum: 255 } + def last_deployment deployments.last end diff --git a/app/views/projects/environments/_form.html.haml b/app/views/projects/environments/_form.html.haml index c07f4bd510c..6d040f5cfe6 100644 --- a/app/views/projects/environments/_form.html.haml +++ b/app/views/projects/environments/_form.html.haml @@ -1,7 +1,22 @@ -= form_for @environment, url: namespace_project_environments_path(@project.namespace, @project), html: { class: 'col-lg-9' } do |f| - = form_errors(@environment) - .form-group - = f.label :name, 'Name', class: 'label-light' - = f.text_field :name, required: true, class: 'form-control' - = f.submit 'Create environment', class: 'btn btn-create' - = link_to 'Cancel', namespace_project_environments_path(@project.namespace, @project), class: 'btn btn-cancel' +.row.prepend-top-default.append-bottom-default + .col-lg-3 + %h4.prepend-top-0 + Environments + %p + Environments allow you to track deployments of your application + = succeed "." do + = link_to "Read more about environments", help_page_path("ci/environments") + + = form_for [@project.namespace.becomes(Namespace), @project, @environment], html: { class: 'col-lg-9' } do |f| + = form_errors(@environment) + + .form-group + = f.label :name, 'Name', class: 'label-light' + = f.text_field :name, required: true, class: 'form-control' + .form-group + = f.label :external_url, 'External URL', class: 'label-light' + = f.url_field :external_url, class: 'form-control' + + .form-actions + = f.submit 'Save', class: 'btn btn-save' + = link_to 'Cancel', namespace_project_environments_path(@project.namespace, @project), class: 'btn btn-cancel' diff --git a/app/views/projects/environments/edit.html.haml b/app/views/projects/environments/edit.html.haml new file mode 100644 index 00000000000..6d1bdb9320f --- /dev/null +++ b/app/views/projects/environments/edit.html.haml @@ -0,0 +1,6 @@ +- page_title "Edit", @environment.name, "Environments" + +%h3.page-title + Edit environment +%hr += render 'form' diff --git a/app/views/projects/environments/new.html.haml b/app/views/projects/environments/new.html.haml index 89e06567196..e51667ade2d 100644 --- a/app/views/projects/environments/new.html.haml +++ b/app/views/projects/environments/new.html.haml @@ -1,12 +1,6 @@ - page_title 'New Environment' -.row.prepend-top-default.append-bottom-default - .col-lg-3 - %h4.prepend-top-0 - New Environment - %p - Environments allow you to track deployments of your application - = succeed "." do - = link_to "Read more about environments", help_page_path("ci/environments") - - = render 'form' +%h3.page-title + New environment +%hr += render 'form' diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml index b8b1ce52a91..a07436ad7c9 100644 --- a/app/views/projects/environments/show.html.haml +++ b/app/views/projects/environments/show.html.haml @@ -6,10 +6,10 @@ .top-area .col-md-9 %h3.page-title= @environment.name.capitalize - .col-md-3 .nav-controls - if can?(current_user, :update_environment, @environment) + = link_to 'Edit', edit_namespace_project_environment_path(@project.namespace, @project, @environment), class: 'btn' = link_to 'Destroy', namespace_project_environment_path(@project.namespace, @project, @environment), data: { confirm: 'Are you sure you want to delete this environment?' }, class: 'btn btn-danger', method: :delete - if @deployments.blank? diff --git a/config/routes.rb b/config/routes.rb index 308d83af57e..ced204be7f7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -741,7 +741,7 @@ Rails.application.routes.draw do end end - resources :environments, only: [:index, :show, :new, :create, :destroy] + resources :environments, constraints: { id: /\d+/ } resources :builds, only: [:index, :show], constraints: { id: /\d+/ } do collection do diff --git a/db/migrate/20160725083350_add_external_url_to_enviroments.rb b/db/migrate/20160725083350_add_external_url_to_enviroments.rb new file mode 100644 index 00000000000..e887341159b --- /dev/null +++ b/db/migrate/20160725083350_add_external_url_to_enviroments.rb @@ -0,0 +1,12 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddExternalUrlToEnviroments < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column(:environments, :external_url, :string) + end +end diff --git a/db/schema.rb b/db/schema.rb index 2d2ae5fd840..4365af98962 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -427,9 +427,10 @@ ActiveRecord::Schema.define(version: 20160722221922) do create_table "environments", force: :cascade do |t| t.integer "project_id" - t.string "name", null: false + t.string "name", null: false t.datetime "created_at" t.datetime "updated_at" + t.string "external_url" end add_index "environments", ["project_id", "name"], name: "index_environments_on_project_id_and_name", using: :btree diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb new file mode 100644 index 00000000000..b91a99d6b2e --- /dev/null +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -0,0 +1,50 @@ +require 'spec_helper' + +describe Projects::EnvironmentsController do + let(:environment) { create(:environment) } + let(:project) { environment.project } + let(:user) { create(:user) } + + before do + project.team << [user, :master] + + sign_in(user) + end + + render_views + + describe 'GET show' do + context 'with valid id' do + it 'responds with a status code 200' do + get :show, namespace_id: project.namespace, project_id: project, id: environment.id + + expect(response).to be_ok + end + end + + context 'with invalid id' do + it 'responds with a status code 404' do + get :show, namespace_id: project.namespace, project_id: project, id: 12345 + + expect(response).to be_not_found + end + end + end + + describe 'GET edit' do + it 'responds with a status code 200' do + get :edit, namespace_id: project.namespace, project_id: project, id: environment.id + + expect(response).to be_ok + end + end + + describe 'PATCH #update' do + it 'responds with a 302' do + patch :update, namespace_id: project.namespace, project_id: + project, id: environment.id, environment: { external_url: 'https://git.gitlab.com' } + + expect(response).to have_http_status(302) + end + end +end diff --git a/spec/factories/environments.rb b/spec/factories/environments.rb index 07265c26ca3..846cccfc7fa 100644 --- a/spec/factories/environments.rb +++ b/spec/factories/environments.rb @@ -3,5 +3,6 @@ FactoryGirl.define do sequence(:name) { |n| "environment#{n}" } project factory: :empty_project + sequence(:external_url) { |n| "https://env#{n}.example.gitlab.com" } end end diff --git a/spec/features/environments_spec.rb b/spec/features/environments_spec.rb index a7d9f2a0c72..fcd41b38413 100644 --- a/spec/features/environments_spec.rb +++ b/spec/features/environments_spec.rb @@ -140,7 +140,7 @@ feature 'Environments', feature: true do context 'for valid name' do before do fill_in('Name', with: 'production') - click_on 'Create environment' + click_on 'Save' end scenario 'does create a new pipeline' do @@ -151,7 +151,7 @@ feature 'Environments', feature: true do context 'for invalid name' do before do fill_in('Name', with: 'name with spaces') - click_on 'Create environment' + click_on 'Save' end scenario 'does show errors' do diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb index 7629af6a570..6c11cfc4c9b 100644 --- a/spec/models/environment_spec.rb +++ b/spec/models/environment_spec.rb @@ -11,4 +11,14 @@ describe Environment, models: true do it { is_expected.to validate_presence_of(:name) } it { is_expected.to validate_uniqueness_of(:name).scoped_to(:project_id) } it { is_expected.to validate_length_of(:name).is_within(0..255) } + + it { is_expected.to validate_length_of(:external_url).is_within(0..255) } + + # To circumvent a not null violation of the name column: + # https://github.com/thoughtbot/shoulda-matchers/issues/336 + it 'validates uniqueness of :external_url' do + create(:environment) + + is_expected.to validate_uniqueness_of(:external_url).scoped_to(:project_id) + end end