diff options
author | Kamil Trzciński <ayufan@ayufan.eu> | 2018-09-03 11:20:59 +0200 |
---|---|---|
committer | Kamil Trzciński <ayufan@ayufan.eu> | 2018-09-03 11:21:21 +0200 |
commit | c8ea98739f8ebe59e55cd14ecc468d7c66929b6f (patch) | |
tree | 1a13997654391a4004abe0c0fd162e5a957257f7 | |
parent | 553de354044a9abf52ff6c53bfd956cff209c960 (diff) | |
download | gitlab-ce-kamil-refactor-ci-builds-v4.tar.gz |
Config Value storekamil-refactor-ci-builds-v4
-rw-r--r-- | app/models/ci/build.rb | 2 | ||||
-rw-r--r-- | app/models/ci/build_config.rb | 134 | ||||
-rw-r--r-- | app/models/ci/build_config_value.rb | 40 | ||||
-rw-r--r-- | db/migrate/20180831115822_create_ci_builds_config_values.rb | 21 |
4 files changed, 197 insertions, 0 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 2c182b02f36..23218aa2c22 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -35,10 +35,12 @@ module Ci end has_one :config, class_name: 'Ci::BuildConfig' + has_many :config_values, class_name: 'Ci::BuildConfigValue' has_one :metadata, class_name: 'Ci::BuildMetadata' has_one :runner_session, class_name: 'Ci::BuildRunnerSession', validate: true, inverse_of: :build accepts_nested_attributes_for :runner_session + accepts_nested_attributes_for :config_values delegate :timeout, to: :metadata, prefix: true, allow_nil: true delegate :url, to: :runner_session, prefix: true, allow_nil: true diff --git a/app/models/ci/build_config.rb b/app/models/ci/build_config.rb index 2401b8b514b..954e8f6df43 100644 --- a/app/models/ci/build_config.rb +++ b/app/models/ci/build_config.rb @@ -16,5 +16,139 @@ module Ci serialize :yaml_options # rubocop:disable Cop/ActiveRecordSerialize serialize :yaml_variables, Gitlab::Serializer::Ci::Variables # rubocop:disable Cop/ActiveRecordSerialize + + STRUCTURE = { + image: :image, + services: [:service], + artifacts: { + name: :artifacts_name, + untracked: :artifacts_untracked, + path: [:artifacts_path], + reports: { + junit: [:artifacts_report_junit] + }, + when: :artifacts_when, + expire_in: :artifacts_expire_in, + }, + cache: { + key: :cache_key, + untracked: :cache_untracked, + path: [:cache_paths], + policy: :cache_policy + }, + dependencies: [:dependency], + before_script: [:before_script], + script: [:script], + after_script: [:after_script], + environment: { + name: :environment_name, + url: :environment_url, + action: :environment_action + }, + retry: :retry + } + + def options + demap_data(STRUCTURE, nil) + end + + def options=(value) + build.config_values_attributes = map_data(STRUCTURE, value, nil).flatten + end + + public + + def map_data(data_def, value, index) + if data_def.is_a?(Symbol) + map_value(data_def, value, index) + elsif data_def.is_a?(Hash) + map_structure(data_def, value, index) + elsif data_def.is_a?(Array) + map_array(data_def, value, index) + else + raise "Unsupported type for: #{data_def}" + end + end + + def map_structure(data_def, hash, index) + raise 'Invalid data' unless data_def.is_a?(Hash) + raise 'Value needs to be hash' unless hash.is_a?(Hash) + + data_def.map do |key, data| + map_data(data, hash[key], index) if hash[key] + end.compact + end + + def map_value(key, value, index) + { key: key, value_string: value, index: index } + end + + def map_array(data_def, values, index) + raise 'Invalid data' unless data_def.is_a?(Array) + raise 'Array needs exactly one' unless data_def.one? + raise 'Nested arrays are not supported' if index + raise "Value needs to be array: #{values}" unless values.is_a?(Array) + + type = data_def.first + + values.map.with_index do |value, index| + map_data(type, value, index) + end + end + + public + + def demap_data(data_def, index) + if data_def.is_a?(Symbol) + demap_value(data_def, index) + elsif data_def.is_a?(Hash) + demap_structure(data_def, index) + elsif data_def.is_a?(Array) + demap_array(data_def, index) + else + raise "Unsupported type for: #{data_def}" + end + end + + def demap_structure(data_def, index) + raise 'Invalid data' unless data_def.is_a?(Hash) + + data_def = data_def.map do |key, data| + result = demap_data(data, index) + [key, result] + end + + puts "#{data_def}" + + result = data_def.to_h.compact + result if result.present? + end + + def demap_array(data_def, index) + raise 'Invalid data' unless data_def.is_a?(Array) + raise 'Array needs exactly one' unless data_def.one? + raise 'Nested arrays are not supported' if index + + type = data_def.first + + results = [] + + 10000.times do |index| + result = demap_data(type, index) + break unless result.present? + results << result + end + + results if results.present? + end + + def demap_value(key, index) + value = build.config_values.find do |config| + config.key.to_sym == key && config.index == index + end + return unless value + + value.value_string + end end end diff --git a/app/models/ci/build_config_value.rb b/app/models/ci/build_config_value.rb new file mode 100644 index 00000000000..fb270c0550a --- /dev/null +++ b/app/models/ci/build_config_value.rb @@ -0,0 +1,40 @@ +module Ci + class BuildConfigValue < ActiveRecord::Base + extend Gitlab::Ci::Model + + # The version of the schema that first introduced this model/table. + MINIMUM_SCHEMA_VERSION = 20180831115822 + + def self.available? + @available ||= + ActiveRecord::Migrator.current_version >= MINIMUM_SCHEMA_VERSION + end + + self.table_name = 'ci_builds_config_values' + + belongs_to :build + + enum key: [ + :image, + :service, + :artifacts_name, + :artifacts_untracked, + :artifacts_path, + :artifacts_report_junit, + :artifacts_when, + :artifacts_expire_in, + :cache_key, + :cache_untracked, + :cache_paths, + :cache_policy, + :dependency, + :before_script, + :script, + :after_script, + :environment_name, + :environment_url, + :environment_action, + :retry, + ] + end +end diff --git a/db/migrate/20180831115822_create_ci_builds_config_values.rb b/db/migrate/20180831115822_create_ci_builds_config_values.rb new file mode 100644 index 00000000000..b1e75881ae1 --- /dev/null +++ b/db/migrate/20180831115822_create_ci_builds_config_values.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class CreateCiBuildsConfigValues < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + create_table :ci_builds_config_values, id: :bigserial do |t| + t.integer :build_id, null: false + t.foreign_key :ci_builds, column: :build_id, on_delete: :cascade + + t.integer :key, null: false + t.integer :index + t.text :value_string + end + end +end |