summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/deployment.rb2
-rw-r--r--app/models/environment.rb4
-rw-r--r--app/services/create_deployment_service.rb40
-rw-r--r--db/migrate/20160610204157_add_deployments.rb4
-rw-r--r--db/schema.rb4
-rw-r--r--doc/permissions/permissions.md2
-rw-r--r--spec/factories/deployments.rb12
-rw-r--r--spec/factories/environments.rb7
-rw-r--r--spec/models/deployment_spec.rb17
-rw-r--r--spec/models/environment_spec.rb14
-rw-r--r--spec/models/project_spec.rb2
-rw-r--r--spec/services/create_deployment_service_spec.rb59
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