diff options
-rw-r--r-- | app/models/deployment.rb | 2 | ||||
-rw-r--r-- | app/models/environment.rb | 4 | ||||
-rw-r--r-- | app/services/create_deployment_service.rb | 40 | ||||
-rw-r--r-- | db/migrate/20160610204157_add_deployments.rb | 4 | ||||
-rw-r--r-- | db/schema.rb | 4 | ||||
-rw-r--r-- | doc/permissions/permissions.md | 2 | ||||
-rw-r--r-- | spec/factories/deployments.rb | 12 | ||||
-rw-r--r-- | spec/factories/environments.rb | 7 | ||||
-rw-r--r-- | spec/models/deployment_spec.rb | 17 | ||||
-rw-r--r-- | spec/models/environment_spec.rb | 14 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/create_deployment_service_spec.rb | 59 |
12 files changed, 139 insertions, 28 deletions
diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 7cdfc740441..44a0a7fdd10 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -8,6 +8,8 @@ class Deployment < ActiveRecord::Base validates_presence_of :sha validates_presence_of :ref + validates_associated :project + validates_associated :environment delegate :name, to: :environment, prefix: true diff --git a/app/models/environment.rb b/app/models/environment.rb index b29cca8fbe2..3eab137718e 100644 --- a/app/models/environment.rb +++ b/app/models/environment.rb @@ -9,6 +9,10 @@ class Environment < ActiveRecord::Base format: { with: Gitlab::Regex.environment_name_regex, message: Gitlab::Regex.environment_name_regex_message } + validates_uniqueness_of :name, scope: :project_id + + validates_associated :project + def last_deployment deployments.last end diff --git a/app/services/create_deployment_service.rb b/app/services/create_deployment_service.rb index 7408ec367f6..eec1773073e 100644 --- a/app/services/create_deployment_service.rb +++ b/app/services/create_deployment_service.rb @@ -1,38 +1,30 @@ require_relative 'base_service' class CreateDeploymentService < BaseService - def execute(deployable) - environment = find_environment(params[:environment]) - return error('no environment') unless environmnet + def execute(deployable = nil) + environment = create_or_find_environment(params[:environment]) - deployment = create_deployment(environment, deployable) - if deployment.persisted? - success(deployment) - else - error(deployment.errors) - end + project.deployments.create( + environment: environment, + ref: params[:ref], + tag: params[:tag], + sha: params[:sha], + user: current_user, + deployable: deployable, + ) end private - def find_environment(environment) - project.environments.find_by(name: environment) + def create_or_find_environment(environment) + find_environment(environment) || create_environment(environment) end - def create_deployment(environment, deployable) - environment.deployments.create( - project: project, - ref: build.ref, - tag: build.tag, - sha: build.sha, - user: current_user, - deployable: deployable, - ) + def create_environment(environment) + project.environments.create(name: environment) end - def success(deployment) - out = super() - out[:deployment] = deployment - out + def find_environment(environment) + project.environments.find_by(name: environment) end end diff --git a/db/migrate/20160610204157_add_deployments.rb b/db/migrate/20160610204157_add_deployments.rb index c93d3bf64d3..557b78f91e1 100644 --- a/db/migrate/20160610204157_add_deployments.rb +++ b/db/migrate/20160610204157_add_deployments.rb @@ -13,8 +13,8 @@ class AddDeployments < ActiveRecord::Migration t.boolean :tag t.string :sha t.integer :user_id - t.integer :deployable_id, null: false - t.string :deployable_type, null: false + t.integer :deployable_id + t.string :deployable_type t.datetime :created_at t.datetime :updated_at end diff --git a/db/schema.rb b/db/schema.rb index cd6c087c847..51a6044f99c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -390,8 +390,8 @@ ActiveRecord::Schema.define(version: 20160610301627) do t.boolean "tag" t.string "sha" t.integer "user_id" - t.integer "deployable_id", null: false - t.string "deployable_type", null: false + t.integer "deployable_id" + t.string "deployable_type" t.datetime "created_at" t.datetime "updated_at" end diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md index b76ce31cbad..666dcfafd03 100644 --- a/doc/permissions/permissions.md +++ b/doc/permissions/permissions.md @@ -28,6 +28,7 @@ documentation](../workflow/add-user/add-user.md). | Manage labels | | ✓ | ✓ | ✓ | ✓ | | See a commit status | | ✓ | ✓ | ✓ | ✓ | | See a container registry | | ✓ | ✓ | ✓ | ✓ | +| See a environments | | ✓ | ✓ | ✓ | ✓ | | Manage merge requests | | | ✓ | ✓ | ✓ | | Create new merge request | | | ✓ | ✓ | ✓ | | Create new branches | | | ✓ | ✓ | ✓ | @@ -40,6 +41,7 @@ documentation](../workflow/add-user/add-user.md). | Create or update commit status | | | ✓ | ✓ | ✓ | | Update a container registry | | | ✓ | ✓ | ✓ | | Remove a container registry image | | | ✓ | ✓ | ✓ | +| Manage environments | | | ✓ | ✓ | ✓ | | Create new milestones | | | | ✓ | ✓ | | Add new team members | | | | ✓ | ✓ | | Push to protected branches | | | | ✓ | ✓ | diff --git a/spec/factories/deployments.rb b/spec/factories/deployments.rb new file mode 100644 index 00000000000..f335a111a7d --- /dev/null +++ b/spec/factories/deployments.rb @@ -0,0 +1,12 @@ +FactoryGirl.define do + factory :deployment, class: Deployment do + sha '97de212e80737a608d939f648d959671fb0a0142' + ref 'master' + + environment factory: :environment + + after(:build) do |deployment, evaluator| + deployment.project = deployment.environment.project + end + end +end diff --git a/spec/factories/environments.rb b/spec/factories/environments.rb new file mode 100644 index 00000000000..07265c26ca3 --- /dev/null +++ b/spec/factories/environments.rb @@ -0,0 +1,7 @@ +FactoryGirl.define do + factory :environment, class: Environment do + sequence(:name) { |n| "environment#{n}" } + + project factory: :empty_project + end +end diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb new file mode 100644 index 00000000000..b273018707f --- /dev/null +++ b/spec/models/deployment_spec.rb @@ -0,0 +1,17 @@ +require 'spec_helper' + +describe Deployment, models: true do + subject { build(:deployment) } + + it { is_expected.to belong_to(:project) } + it { is_expected.to belong_to(:environment) } + it { is_expected.to belong_to(:user) } + it { is_expected.to belong_to(:deployable) } + + it { is_expected.to delegate_method(:name).to(:environment).with_prefix } + it { is_expected.to delegate_method(:commit).to(:project) } + it { is_expected.to delegate_method(:commit_title).to(:commit).as(:try) } + + it { is_expected.to validate_presence_of(:ref) } + it { is_expected.to validate_presence_of(:sha) } +end diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb new file mode 100644 index 00000000000..7629af6a570 --- /dev/null +++ b/spec/models/environment_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe Environment, models: true do + let(:environment) { create(:environment) } + + it { is_expected.to belong_to(:project) } + it { is_expected.to have_many(:deployments) } + + it { is_expected.to delegate_method(:last_deployment).to(:deployments).as(:last) } + + 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) } +end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index de8815f5a38..1f626ff2647 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -28,6 +28,8 @@ describe Project, models: true do it { is_expected.to have_many(:runners) } it { is_expected.to have_many(:variables) } it { is_expected.to have_many(:triggers) } + it { is_expected.to have_many(:environments).dependent(:destroy) } + it { is_expected.to have_many(:deployments).dependent(:destroy) } it { is_expected.to have_many(:todos).dependent(:destroy) } end diff --git a/spec/services/create_deployment_service_spec.rb b/spec/services/create_deployment_service_spec.rb new file mode 100644 index 00000000000..76f3e0ac9ff --- /dev/null +++ b/spec/services/create_deployment_service_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' + +describe CreateDeploymentService, services: true do + let(:build) { create(:ci_build) } + let(:project) { build.project } + let(:user) { create(:user) } + + let(:service) { described_class.new(project, user, params) } + + describe '#execute' do + let(:params) do + { environment: 'production', + ref: 'master', + sha: build.sha, + } + end + + subject { service.execute } + + context 'when no environments exist' do + it 'does create a new environment' do + expect { subject }.to change { Environment.count }.by(1) + end + + it 'does create a deployment' do + expect(subject).to be_persisted + end + end + + context 'when environment exist' do + before { create(:environment, project: project, name: 'production') } + + it 'does not create a new environment' do + expect { subject }.not_to change { Environment.count } + end + + it 'does create a deployment' do + expect(subject).to be_persisted + end + end + + context 'for environment with invalid name' do + let(:params) do + { environment: 'name with spaces', + ref: 'master', + sha: build.sha, + } + end + + it 'does not create a new environment' do + expect { subject }.not_to change { Environment.count } + end + + it 'does not create a deployment' do + expect(subject).not_to be_persisted + end + end + end +end |