Add support for dynamic environments

Environments that can have a URL with predefined CI variables.
This commit is contained in:
Kamil Trzcinski 2016-09-13 14:14:55 +02:00
parent 1d51bc7dfd
commit a4638dddf2
8 changed files with 139 additions and 5 deletions

View file

@ -83,7 +83,9 @@ module Ci
environment: build.environment,
sha: build.sha,
ref: build.ref,
tag: build.tag)
tag: build.tag,
options: build.options[:environment],
variables: variables)
service.execute(build)
end
end

View file

@ -4,6 +4,7 @@ class Environment < ActiveRecord::Base
has_many :deployments
before_validation :nullify_external_url
before_save :set_environment_type
validates :name,
presence: true,
@ -26,6 +27,17 @@ class Environment < ActiveRecord::Base
self.external_url = nil if self.external_url.blank?
end
def set_environment_type
names = name.split('/')
self.environment_type =
if names.many?
names.first
else
nil
end
end
def includes_commit?(commit)
return false unless last_deployment

View file

@ -744,10 +744,21 @@ class MergeRequest < ActiveRecord::Base
@pipeline ||= source_project.pipeline_for(source_branch, diff_head_sha)
end
def all_commits_sha
merge_request_diffs.map(&:commits).flatten.map(&:sha).sort.uniq
end
def latest_pipelines
@latest_pipelines ||=
if diff_head_sha && source_project
source_project.pipelines.order(id: :desc).where(sha: commits_sha, ref: source_branch)
end
end
def all_pipelines
@all_pipelines ||=
if diff_head_sha && source_project
source_project.pipelines.order(id: :desc).where(sha: commits_sha, ref: source_branch)
source_project.pipelines.order(id: :desc).where(sha: all_commits_sha, ref: source_branch)
end
end

View file

@ -3,9 +3,13 @@ require_relative 'base_service'
class CreateDeploymentService < BaseService
def execute(deployable = nil)
environment = project.environments.find_or_create_by(
name: params[:environment]
name: expanded_name
)
if expanded_url
environment.external_url = expanded_url
end
project.deployments.create(
environment: environment,
ref: params[:ref],
@ -15,4 +19,32 @@ class CreateDeploymentService < BaseService
deployable: deployable
)
end
private
def expanded_name
name.expand_variables(variables)
end
def expanded_url
return unless url
@expanded_url ||= url.expand_variables(variables)
end
def name
params[:environment]
end
def url
options[:url]
end
def options
params[:environment] || {}
end
def variables
params[:variables] || []
end
end

View file

@ -0,0 +1,29 @@
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddEnvironmentTypeToEnvironments < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# When a migration requires downtime you **must** uncomment the following
# constant and define a short and easy to understand explanation as to why the
# migration requires downtime.
# DOWNTIME_REASON = ''
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def change
add_column :environments, :environment_type, :string
end
end

15
lib/expand_variables.rb Normal file
View file

@ -0,0 +1,15 @@
String.instance_eval
def expand_variables(variables)
# Convert hash array to variables
if variables.is_a?(Array)
variables = variables.reduce({}) do |hash, variable|
hash[variable[:key]] = variable[:value]
hash
end
end
self.gsub(/\$([a-zA-Z_][a-zA-Z0-9_]*)|\${\g<1>}|%\g<1>%/) do
variables[$1 || $2]
end
end
end

View file

@ -0,0 +1,33 @@
module Gitlab
module Ci
class Config
module Node
##
# Entry that represents environment variables.
#
class Environment < Entry
include Validatable
validations do
include LegacyValidationHelpers
validate do
unless string_or_array_of_strings?(config)
errors.add(:config,
'should be a string or an array of strings')
end
end
def string_or_array_of_strings?(field)
validate_string(field) || validate_array_of_strings(field)
end
end
def value
Array(@config)
end
end
end
end
end
end

View file

@ -96,11 +96,11 @@ module Gitlab
end
def environment_name_regex
@environment_name_regex ||= /\A[a-zA-Z0-9_-]+\z/.freeze
git_reference_regex
end
def environment_name_regex_message
"can contain only letters, digits, '-' and '_'."
"be a valid git reference name"
end
end
end