Skip to content
Snippets Groups Projects
Commit 8cb21e77 authored by Shinya Maeda's avatar Shinya Maeda
Browse files

Specify Environemtn Tier

This commit allows users to specify environment tier.
parent e333158b
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -486,6 +486,10 @@ def environment_action
self.options.fetch(:environment, {}).fetch(:action, 'start') if self.options
end
 
def environment_deployment_tier
self.options.dig(:environment, :deployment_tier) if self.options
end
def outdated_deployment?
success? && !deployment.try(:last?)
end
Loading
Loading
Loading
Loading
@@ -25,11 +25,10 @@ def execute
 
def update_environment(deployment)
ActiveRecord::Base.transaction do
if (url = expanded_environment_url)
environment.external_url = url
end
# Renew attributes at update
renew_external_url
renew_auto_stop_in
renew_deployment_tier
environment.fire_state_event(action)
 
if environment.save && !environment.stopped?
Loading
Loading
@@ -56,11 +55,25 @@ def action
environment_options[:action] || 'start'
end
 
def renew_external_url
if (url = expanded_environment_url)
environment.external_url = url
end
end
def renew_auto_stop_in
return unless deployable
 
environment.auto_stop_in = deployable.environment_auto_stop_in
end
def renew_deployment_tier
return unless deployable && ::Feature.enabled?(:environment_tier, deployable.project, default_enabled: :yaml)
if (tier = deployable.environment_deployment_tier)
environment.tier = tier
end
end
end
end
 
Loading
Loading
Loading
Loading
@@ -10,7 +10,7 @@ module Entry
class Environment < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Configurable
 
ALLOWED_KEYS = %i[name url action on_stop auto_stop_in kubernetes].freeze
ALLOWED_KEYS = %i[name url action on_stop auto_stop_in kubernetes deployment_tier].freeze
 
entry :kubernetes, Entry::Kubernetes, description: 'Kubernetes deployment configuration.'
 
Loading
Loading
@@ -47,6 +47,11 @@ class Environment < ::Gitlab::Config::Entry::Node
inclusion: { in: %w[start stop prepare], message: 'should be start, stop or prepare' },
allow_nil: true
 
validates :deployment_tier,
type: String,
inclusion: { in: ::Environment.tiers.keys, message: "must be one of #{::Environment.tiers.keys.join(', ')}" },
allow_nil: true
validates :on_stop, type: String, allow_nil: true
validates :kubernetes, type: Hash, allow_nil: true
validates :auto_stop_in, duration: true, allow_nil: true
Loading
Loading
@@ -85,6 +90,10 @@ def auto_stop_in
value[:auto_stop_in]
end
 
def deployment_tier
value[:deployment_tier]
end
def value
case @config
when String then { name: @config, action: 'start' }
Loading
Loading
Loading
Loading
@@ -13,7 +13,9 @@ def initialize(job)
 
def to_resource
environments.safe_find_or_create_by(name: expanded_environment_name) do |environment|
# Initialize the attributes at creation
environment.auto_stop_in = auto_stop_in
environment.tier = deployment_tier if ::Feature.enabled?(:environment_tier, job.project, default_enabled: :yaml)
end
end
 
Loading
Loading
@@ -27,6 +29,10 @@ def auto_stop_in
job.environment_auto_stop_in
end
 
def deployment_tier
job.environment_deployment_tier
end
def expanded_environment_name
job.expanded_environment_name
end
Loading
Loading
Loading
Loading
@@ -305,4 +305,37 @@
it { expect(entry).to be_valid }
end
end
describe 'deployment_tier' do
let(:config) do
{ name: 'customer-portal', deployment_tier: deployment_tier }
end
context 'is a string' do
let(:deployment_tier) { 'production' }
it { expect(entry).to be_valid }
end
context 'is a hash' do
let(:deployment_tier) { Hash(tier: 'production') }
it { expect(entry).not_to be_valid }
end
context 'is nil' do
let(:deployment_tier) { nil }
it { expect(entry).to be_valid }
end
context 'is unknown value' do
let(:deployment_tier) { 'unknown' }
it 'is invalid and adds an error' do
expect(entry).not_to be_valid
expect(entry.errors).to include("environment deployment tier must be one of #{::Environment.tiers.keys.join(', ')}")
end
end
end
end
Loading
Loading
@@ -88,6 +88,65 @@
end
end
 
context 'when job has deployment tier attribute' do
let(:attributes) do
{
environment: 'customer-portal',
options: {
environment: {
name: 'customer-portal',
deployment_tier: deployment_tier
}
}
}
end
let(:deployment_tier) { 'production' }
context 'when environment has not been created yet' do
it 'sets the specified deployment tier' do
is_expected.to be_production
end
context 'when deployment tier is staging' do
let(:deployment_tier) { 'staging' }
it 'sets the specified deployment tier' do
is_expected.to be_staging
end
end
context 'when deployment tier is unknown' do
let(:deployment_tier) { 'unknown' }
it 'raises an error' do
expect { subject }.to raise_error(ArgumentError, "'unknown' is not a valid tier")
end
end
context 'when environment_tier feature flag is disabled' do
before do
stub_feature_flags(environment_tier: false)
end
it 'does not set the specified tier' do
expect(subject.tier).to be_nil
end
end
end
context 'when environment has already been created' do
before do
create(:environment, :staging, project: project, name: 'customer-portal')
end
it 'does not overwrite the specified deployment tier' do
# This is to be updated when a deployment succeeded i.e. Deployments::UpdateEnvironmentService.
is_expected.to be_staging
end
end
end
context 'when job starts a review app' do
let(:environment_name) { 'review/$CI_COMMIT_REF_NAME' }
let(:expected_environment_name) { "review/#{job.ref}" }
Loading
Loading
Loading
Loading
@@ -1261,6 +1261,21 @@
end
end
 
describe '#environment_deployment_tier' do
subject { build.environment_deployment_tier }
let(:build) { described_class.new(options: options) }
let(:options) { { environment: { deployment_tier: 'production' } } }
it { is_expected.to eq('production') }
context 'when options does not include deployment_tier' do
let(:options) { { environment: { name: 'production' } } }
it { is_expected.to be_nil }
end
end
describe 'deployment' do
describe '#outdated_deployment?' do
subject { build.outdated_deployment? }
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::CreatePipelineService do
let_it_be(:project) { create(:project, :repository) }
let_it_be(:developer) { create(:user) }
let(:service) { described_class.new(project, user, ref: 'master') }
let(:user) { developer }
before_all do
project.add_developer(developer)
end
describe '#execute' do
subject { service.execute(:push) }
context 'with deployment tier' do
before do
config = YAML.dump(
deploy: {
script: 'ls',
environment: { name: "review/$CI_COMMIT_REF_NAME", deployment_tier: tier }
})
stub_ci_pipeline_yaml_file(config)
end
let(:tier) { 'development' }
it 'creates the environment with the expected tier' do
is_expected.to be_created_successfully
expect(Environment.find_by_name("review/master")).to be_development
end
context 'when tier is testing' do
let(:tier) { 'testing' }
it 'creates the environment with the expected tier' do
is_expected.to be_created_successfully
expect(Environment.find_by_name("review/master")).to be_testing
end
end
end
end
end
Loading
Loading
@@ -5,7 +5,7 @@
RSpec.describe Deployments::UpdateEnvironmentService do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:options) { { name: 'production' } }
let(:options) { { name: environment_name } }
let(:pipeline) do
create(
:ci_pipeline,
Loading
Loading
@@ -20,13 +20,14 @@
pipeline: pipeline,
ref: 'master',
tag: false,
environment: 'production',
environment: environment_name,
options: { environment: options },
project: project)
end
 
let(:deployment) { job.deployment }
let(:environment) { deployment.environment }
let(:environment_name) { 'production' }
 
subject(:service) { described_class.new(deployment) }
 
Loading
Loading
@@ -131,6 +132,66 @@
end
end
end
context 'when deployment tier is specified' do
let(:environment_name) { 'customer-portal' }
let(:options) { { name: environment_name, deployment_tier: 'production' } }
context 'when tier has already been set' do
before do
environment.update_column(:tier, Environment.tiers[:other])
end
it 'overwrites the guessed tier by the specified deployment tier' do
expect { subject.execute }
.to change { environment.reset.tier }.from('other').to('production')
end
end
context 'when tier has not been set' do
before do
environment.update_column(:tier, nil)
end
it 'sets the specified deployment tier' do
expect { subject.execute }
.to change { environment.reset.tier }.from(nil).to('production')
end
context 'when deployment was created by an external CD system' do
before do
deployment.update_column(:deployable_id, nil)
end
it 'guesses the deployment tier' do
expect { subject.execute }
.to change { environment.reset.tier }.from(nil).to('other')
end
end
context 'when environment_tier feature flag is disabled' do
before do
stub_feature_flags(environment_tier: false)
end
it 'does not set the specified deployment tier' do
expect { subject.execute }.not_to change { environment.reset.tier }
end
end
end
end
context 'when deployment tier is not specified' do
let(:environment_name) { 'customer-portal' }
let(:options) { { name: environment_name } }
it 'guesses the deployment tier' do
environment.update_column(:tier, nil)
expect { subject.execute }
.to change { environment.reset.tier }.from(nil).to('other')
end
end
end
 
describe '#expanded_environment_url' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment