Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 10:08:36 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-21 10:08:36 +0300
commit48aff82709769b098321c738f3444b9bdaa694c6 (patch)
treee00c7c43e2d9b603a5a6af576b1685e400410dee /lib/gitlab/ci
parent879f5329ee916a948223f8f43d77fba4da6cd028 (diff)
Add latest changes from gitlab-org/gitlab@13-5-stable-eev13.5.0-rc42
Diffstat (limited to 'lib/gitlab/ci')
-rw-r--r--lib/gitlab/ci/ansi2json/converter.rb23
-rw-r--r--lib/gitlab/ci/ansi2json/line.rb7
-rw-r--r--lib/gitlab/ci/ansi2json/state.rb3
-rw-r--r--lib/gitlab/ci/artifact_file_reader.rb27
-rw-r--r--lib/gitlab/ci/config.rb4
-rw-r--r--lib/gitlab/ci/config/entry/bridge.rb19
-rw-r--r--lib/gitlab/ci/config/entry/cache.rb24
-rw-r--r--lib/gitlab/ci/config/entry/include.rb6
-rw-r--r--lib/gitlab/ci/config/entry/jobs.rb29
-rw-r--r--lib/gitlab/ci/config/entry/needs.rb23
-rw-r--r--lib/gitlab/ci/config/entry/ports.rb26
-rw-r--r--lib/gitlab/ci/config/entry/product/matrix.rb2
-rw-r--r--lib/gitlab/ci/config/entry/product/variables.rb6
-rw-r--r--lib/gitlab/ci/config/entry/reports.rb3
-rw-r--r--lib/gitlab/ci/config/entry/rules.rb21
-rw-r--r--lib/gitlab/ci/config/entry/services.rb26
-rw-r--r--lib/gitlab/ci/config/entry/variables.rb22
-rw-r--r--lib/gitlab/ci/features.rb30
-rw-r--r--lib/gitlab/ci/lint.rb7
-rw-r--r--lib/gitlab/ci/parsers/test/junit.rb34
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/process.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/create.rb2
-rw-r--r--lib/gitlab/ci/pipeline/seed/build/cache.rb4
-rw-r--r--lib/gitlab/ci/reports/test_case.rb9
-rw-r--r--lib/gitlab/ci/reports/test_suite.rb16
-rw-r--r--lib/gitlab/ci/runner/backoff.rb75
-rw-r--r--lib/gitlab/ci/status/bridge/action.rb12
-rw-r--r--lib/gitlab/ci/status/bridge/common.rb1
-rw-r--r--lib/gitlab/ci/status/bridge/factory.rb5
-rw-r--r--lib/gitlab/ci/status/bridge/manual.rb12
-rw-r--r--lib/gitlab/ci/status/bridge/play.rb19
-rw-r--r--lib/gitlab/ci/status/canceled.rb4
-rw-r--r--lib/gitlab/ci/status/created.rb4
-rw-r--r--lib/gitlab/ci/status/failed.rb4
-rw-r--r--lib/gitlab/ci/status/manual.rb4
-rw-r--r--lib/gitlab/ci/status/pending.rb4
-rw-r--r--lib/gitlab/ci/status/preparing.rb4
-rw-r--r--lib/gitlab/ci/status/running.rb4
-rw-r--r--lib/gitlab/ci/status/scheduled.rb4
-rw-r--r--lib/gitlab/ci/status/skipped.rb4
-rw-r--r--lib/gitlab/ci/status/success.rb4
-rw-r--r--lib/gitlab/ci/status/waiting_for_resource.rb4
-rw-r--r--lib/gitlab/ci/templates/AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml11
-rw-r--r--lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Bash.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Clojure.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Crystal.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Django.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Elixir.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/CF-Provision.gitlab-ci.yml14
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Intelligence.gitlab-ci.yml16
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml9
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy/EC2.gitlab-ci.yml39
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml1
-rw-r--r--lib/gitlab/ci/templates/Laravel.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/PHP.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Ruby.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Rust.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml1
-rw-r--r--lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml43
-rw-r--r--lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml22
-rw-r--r--lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml53
-rw-r--r--lib/gitlab/ci/trace.rb13
-rw-r--r--lib/gitlab/ci/trace/checksum.rb83
-rw-r--r--lib/gitlab/ci/trace/metrics.rb33
-rw-r--r--lib/gitlab/ci/variables/collection/item.rb4
-rw-r--r--lib/gitlab/ci/yaml_processor/result.rb8
77 files changed, 705 insertions, 237 deletions
diff --git a/lib/gitlab/ci/ansi2json/converter.rb b/lib/gitlab/ci/ansi2json/converter.rb
index 0373a12ab69..6d152c052dc 100644
--- a/lib/gitlab/ci/ansi2json/converter.rb
+++ b/lib/gitlab/ci/ansi2json/converter.rb
@@ -104,23 +104,24 @@ module Gitlab
action = scanner[1]
timestamp = scanner[2]
section = scanner[3]
+ options = parse_section_options(scanner[4])
section_name = sanitize_section_name(section)
- if action == "start"
- handle_section_start(scanner, section_name, timestamp)
- elsif action == "end"
+ if action == 'start'
+ handle_section_start(scanner, section_name, timestamp, options)
+ elsif action == 'end'
handle_section_end(scanner, section_name, timestamp)
else
raise 'unsupported action'
end
end
- def handle_section_start(scanner, section, timestamp)
+ def handle_section_start(scanner, section, timestamp, options)
# We make a new line for new section
flush_current_line
- @state.open_section(section, timestamp)
+ @state.open_section(section, timestamp, options)
# we need to consume match after handling
# the open of section, as we want the section
@@ -157,6 +158,18 @@ module Gitlab
def sanitize_section_name(section)
section.to_s.downcase.gsub(/[^a-z0-9]/, '-')
end
+
+ def parse_section_options(raw_options)
+ return unless raw_options
+
+ # We need to remove the square brackets and split
+ # by comma to get a list of the options
+ options = raw_options[1...-1].split ','
+
+ # Now split each option by equals to separate
+ # each in the format [key, value]
+ options.to_h { |option| option.split '=' }
+ end
end
end
end
diff --git a/lib/gitlab/ci/ansi2json/line.rb b/lib/gitlab/ci/ansi2json/line.rb
index 21aa1f84353..b1dee0e1ecc 100644
--- a/lib/gitlab/ci/ansi2json/line.rb
+++ b/lib/gitlab/ci/ansi2json/line.rb
@@ -32,7 +32,7 @@ module Gitlab
end
attr_reader :offset, :sections, :segments, :current_segment,
- :section_header, :section_duration
+ :section_header, :section_duration, :section_options
def initialize(offset:, style:, sections: [])
@offset = offset
@@ -68,6 +68,10 @@ module Gitlab
@sections << section
end
+ def set_section_options(options)
+ @section_options = options
+ end
+
def set_as_section_header
@section_header = true
end
@@ -90,6 +94,7 @@ module Gitlab
result[:section] = sections.last if sections.any?
result[:section_header] = true if @section_header
result[:section_duration] = @section_duration if @section_duration
+ result[:section_options] = @section_options if @section_options
end
end
end
diff --git a/lib/gitlab/ci/ansi2json/state.rb b/lib/gitlab/ci/ansi2json/state.rb
index 38d36e6950c..b2b6ce649ed 100644
--- a/lib/gitlab/ci/ansi2json/state.rb
+++ b/lib/gitlab/ci/ansi2json/state.rb
@@ -26,10 +26,11 @@ module Gitlab
Base64.urlsafe_encode64(state.to_json)
end
- def open_section(section, timestamp)
+ def open_section(section, timestamp, options)
@open_sections[section] = timestamp
@current_line.add_section(section)
+ @current_line.set_section_options(options)
@current_line.set_as_section_header
end
diff --git a/lib/gitlab/ci/artifact_file_reader.rb b/lib/gitlab/ci/artifact_file_reader.rb
index 6395a20ca99..b0fad026ec5 100644
--- a/lib/gitlab/ci/artifact_file_reader.rb
+++ b/lib/gitlab/ci/artifact_file_reader.rb
@@ -45,14 +45,6 @@ module Gitlab
end
def read_zip_file!(file_path)
- if ::Gitlab::Ci::Features.new_artifact_file_reader_enabled?(job.project)
- read_with_new_artifact_file_reader(file_path)
- else
- read_with_legacy_artifact_file_reader(file_path)
- end
- end
-
- def read_with_new_artifact_file_reader(file_path)
job.artifacts_file.use_open_file do |file|
zip_file = Zip::File.new(file, false, true)
entry = zip_file.find_entry(file_path)
@@ -69,25 +61,6 @@ module Gitlab
end
end
- def read_with_legacy_artifact_file_reader(file_path)
- job.artifacts_file.use_file do |archive_path|
- Zip::File.open(archive_path) do |zip_file|
- entry = zip_file.find_entry(file_path)
- unless entry
- raise Error, "Path `#{file_path}` does not exist inside the `#{job.name}` artifacts archive!"
- end
-
- if entry.name_is_directory?
- raise Error, "Path `#{file_path}` was expected to be a file but it was a directory!"
- end
-
- zip_file.get_input_stream(entry) do |is|
- is.read
- end
- end
- end
- end
-
def max_archive_size_in_mb
ActiveSupport::NumberHelper.number_to_human_size(MAX_ARCHIVE_SIZE)
end
diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb
index 9d269831679..071a8ef830f 100644
--- a/lib/gitlab/ci/config.rb
+++ b/lib/gitlab/ci/config.rb
@@ -54,6 +54,10 @@ module Gitlab
root.variables_value
end
+ def variables_with_data
+ root.variables_entry.value_with_data
+ end
+
def stages
root.stages_value
end
diff --git a/lib/gitlab/ci/config/entry/bridge.rb b/lib/gitlab/ci/config/entry/bridge.rb
index a8b67a1db4f..1740032e5c7 100644
--- a/lib/gitlab/ci/config/entry/bridge.rb
+++ b/lib/gitlab/ci/config/entry/bridge.rb
@@ -11,15 +11,18 @@ module Gitlab
class Bridge < ::Gitlab::Config::Entry::Node
include ::Gitlab::Ci::Config::Entry::Processable
+ ALLOWED_WHEN = %w[on_success on_failure always manual].freeze
ALLOWED_KEYS = %i[trigger].freeze
validations do
validates :config, allowed_keys: ALLOWED_KEYS + PROCESSABLE_ALLOWED_KEYS
with_options allow_nil: true do
- validates :when,
- inclusion: { in: %w[on_success on_failure always],
- message: 'should be on_success, on_failure or always' }
+ validates :allow_failure, boolean: true
+ validates :when, inclusion: {
+ in: ALLOWED_WHEN,
+ message: "should be one of: #{ALLOWED_WHEN.join(', ')}"
+ }
end
validate on: :composed do
@@ -57,11 +60,19 @@ module Gitlab
true
end
+ def manual_action?
+ self.when == 'manual'
+ end
+
+ def ignored?
+ allow_failure.nil? ? manual_action? : allow_failure
+ end
+
def value
super.merge(
trigger: (trigger_value if trigger_defined?),
needs: (needs_value if needs_defined?),
- ignore: !!allow_failure,
+ ignore: ignored?,
when: self.when,
scheduling_type: needs_defined? && !bridge_needs ? :dag : :stage
).compact
diff --git a/lib/gitlab/ci/config/entry/cache.rb b/lib/gitlab/ci/config/entry/cache.rb
index a304d9b724f..6b036182706 100644
--- a/lib/gitlab/ci/config/entry/cache.rb
+++ b/lib/gitlab/ci/config/entry/cache.rb
@@ -9,14 +9,28 @@ module Gitlab
#
class Cache < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Configurable
+ include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
- ALLOWED_KEYS = %i[key untracked paths policy].freeze
+ ALLOWED_KEYS = %i[key untracked paths when policy].freeze
+ ALLOWED_POLICY = %w[pull-push push pull].freeze
DEFAULT_POLICY = 'pull-push'
+ ALLOWED_WHEN = %w[on_success on_failure always].freeze
+ DEFAULT_WHEN = 'on_success'
validations do
- validates :config, allowed_keys: ALLOWED_KEYS
- validates :policy, inclusion: { in: %w[pull-push push pull], message: 'should be pull-push, push, or pull' }, allow_blank: true
+ validates :config, type: Hash, allowed_keys: ALLOWED_KEYS
+ validates :policy,
+ inclusion: { in: ALLOWED_POLICY, message: 'should be pull-push, push, or pull' },
+ allow_blank: true
+
+ with_options allow_nil: true do
+ validates :when,
+ inclusion: {
+ in: ALLOWED_WHEN,
+ message: 'should be on_success, on_failure or always'
+ }
+ end
end
entry :key, Entry::Key,
@@ -28,13 +42,15 @@ module Gitlab
entry :paths, Entry::Paths,
description: 'Specify which paths should be cached across builds.'
- attributes :policy
+ attributes :policy, :when
def value
result = super
result[:key] = key_value
result[:policy] = policy || DEFAULT_POLICY
+ # Use self.when to avoid conflict with reserved word
+ result[:when] = self.when || DEFAULT_WHEN
result
end
diff --git a/lib/gitlab/ci/config/entry/include.rb b/lib/gitlab/ci/config/entry/include.rb
index 9c2e5f641d0..ad0ed00aa6f 100644
--- a/lib/gitlab/ci/config/entry/include.rb
+++ b/lib/gitlab/ci/config/entry/include.rb
@@ -10,7 +10,7 @@ module Gitlab
class Include < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
- ALLOWED_KEYS = %i[local file remote template artifact job].freeze
+ ALLOWED_KEYS = %i[local file remote template artifact job project ref].freeze
validations do
validates :config, hash_or_string: true
@@ -22,6 +22,10 @@ module Gitlab
if config[:artifact] && config[:job].blank?
errors.add(:config, "must specify the job where to fetch the artifact from")
end
+
+ if config[:project] && config[:file].blank?
+ errors.add(:config, "must specify the file where to fetch the config from")
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/jobs.rb b/lib/gitlab/ci/config/entry/jobs.rb
index b5ce42969a5..b0fd9cef10b 100644
--- a/lib/gitlab/ci/config/entry/jobs.rb
+++ b/lib/gitlab/ci/config/entry/jobs.rb
@@ -7,7 +7,7 @@ module Gitlab
##
# Entry that represents a set of jobs.
#
- class Jobs < ::Gitlab::Config::Entry::Node
+ class Jobs < ::Gitlab::Config::Entry::ComposableHash
include ::Gitlab::Config::Entry::Validatable
validations do
@@ -36,6 +36,10 @@ module Gitlab
end
end
+ def composable_class(name, config)
+ self.class.find_type(name, config)
+ end
+
TYPES = [Entry::Hidden, Entry::Job, Entry::Bridge].freeze
private_constant :TYPES
@@ -49,29 +53,6 @@ module Gitlab
type.matching?(name, config)
end
end
-
- # rubocop: disable CodeReuse/ActiveRecord
- def compose!(deps = nil)
- super do
- @config.each do |name, config|
- node = self.class.find_type(name, config)
- next unless node
-
- factory = ::Gitlab::Config::Entry::Factory.new(node)
- .value(config || {})
- .metadata(name: name)
- .with(key: name, parent: self,
- description: "#{name} job definition.")
-
- @entries[name] = factory.create!
- end
-
- @entries.each_value do |entry|
- entry.compose!(deps)
- end
- end
- end
- # rubocop: enable CodeReuse/ActiveRecord
end
end
end
diff --git a/lib/gitlab/ci/config/entry/needs.rb b/lib/gitlab/ci/config/entry/needs.rb
index d7ba8624882..66cd57b8cf3 100644
--- a/lib/gitlab/ci/config/entry/needs.rb
+++ b/lib/gitlab/ci/config/entry/needs.rb
@@ -7,7 +7,7 @@ module Gitlab
##
# Entry that represents a set of needs dependencies.
#
- class Needs < ::Gitlab::Config::Entry::Node
+ class Needs < ::Gitlab::Config::Entry::ComposableArray
include ::Gitlab::Config::Entry::Validatable
validations do
@@ -29,27 +29,16 @@ module Gitlab
end
end
- def compose!(deps = nil)
- super(deps) do
- [@config].flatten.each_with_index do |need, index|
- @entries[index] = ::Gitlab::Config::Entry::Factory.new(Entry::Need)
- .value(need)
- .with(key: "need", parent: self, description: "need definition.") # rubocop:disable CodeReuse/ActiveRecord
- .create!
- end
-
- @entries.each_value do |entry|
- entry.compose!(deps)
- end
- end
- end
-
def value
- values = @entries.values.select(&:type)
+ values = @entries.select(&:type)
values.group_by(&:type).transform_values do |values|
values.map(&:value)
end
end
+
+ def composable_class
+ Entry::Need
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/ports.rb b/lib/gitlab/ci/config/entry/ports.rb
index 01ffcc7dd87..d26b31deca8 100644
--- a/lib/gitlab/ci/config/entry/ports.rb
+++ b/lib/gitlab/ci/config/entry/ports.rb
@@ -7,7 +7,7 @@ module Gitlab
##
# Entry that represents a configuration of the ports of a Docker service.
#
- class Ports < ::Gitlab::Config::Entry::Node
+ class Ports < ::Gitlab::Config::Entry::ComposableArray
include ::Gitlab::Config::Entry::Validatable
validations do
@@ -16,28 +16,8 @@ module Gitlab
validates :config, port_unique: true
end
- def compose!(deps = nil)
- super do
- @entries = []
- @config.each do |config|
- @entries << ::Gitlab::Config::Entry::Factory.new(Entry::Port)
- .value(config || {})
- .with(key: "port", parent: self, description: "port definition.") # rubocop:disable CodeReuse/ActiveRecord
- .create!
- end
-
- @entries.each do |entry|
- entry.compose!(deps)
- end
- end
- end
-
- def value
- @entries.map(&:value)
- end
-
- def descendants
- @entries
+ def composable_class
+ Entry::Port
end
end
end
diff --git a/lib/gitlab/ci/config/entry/product/matrix.rb b/lib/gitlab/ci/config/entry/product/matrix.rb
index 6af809d46c1..d4ee0978e1b 100644
--- a/lib/gitlab/ci/config/entry/product/matrix.rb
+++ b/lib/gitlab/ci/config/entry/product/matrix.rb
@@ -46,13 +46,11 @@ module Gitlab
end
end
- # rubocop:disable CodeReuse/ActiveRecord
def number_of_generated_jobs
value.sum do |config|
config.values.reduce(1) { |acc, values| acc * values.size }
end
end
- # rubocop:enable CodeReuse/ActiveRecord
end
end
end
diff --git a/lib/gitlab/ci/config/entry/product/variables.rb b/lib/gitlab/ci/config/entry/product/variables.rb
index ac4f70fb69e..2481989060e 100644
--- a/lib/gitlab/ci/config/entry/product/variables.rb
+++ b/lib/gitlab/ci/config/entry/product/variables.rb
@@ -14,7 +14,7 @@ module Gitlab
validations do
validates :config, variables: { array_values: true }
validates :config, length: {
- minimum: 2,
+ minimum: :minimum,
too_short: 'requires at least %{count} items'
}
end
@@ -28,6 +28,10 @@ module Gitlab
.map { |key, value| [key.to_s, Array(value).map(&:to_s)] }
.to_h
end
+
+ def minimum
+ ::Gitlab::Ci::Features.one_dimensional_matrix_enabled? ? 1 : 2
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/reports.rb b/lib/gitlab/ci/config/entry/reports.rb
index 0ae65f43723..f2fd8ac7fd9 100644
--- a/lib/gitlab/ci/config/entry/reports.rb
+++ b/lib/gitlab/ci/config/entry/reports.rb
@@ -15,7 +15,7 @@ module Gitlab
%i[junit codequality sast secret_detection dependency_scanning container_scanning
dast performance browser_performance load_performance license_management license_scanning metrics lsif
dotenv cobertura terraform accessibility cluster_applications
- requirements coverage_fuzzing].freeze
+ requirements coverage_fuzzing api_fuzzing].freeze
attributes ALLOWED_KEYS
@@ -25,6 +25,7 @@ module Gitlab
with_options allow_nil: true do
validates :junit, array_of_strings_or_string: true
+ validates :api_fuzzing, array_of_strings_or_string: true
validates :coverage_fuzzing, array_of_strings_or_string: true
validates :sast, array_of_strings_or_string: true
validates :sast, array_of_strings_or_string: true
diff --git a/lib/gitlab/ci/config/entry/rules.rb b/lib/gitlab/ci/config/entry/rules.rb
index 2fbc3d9e367..bf74f995e80 100644
--- a/lib/gitlab/ci/config/entry/rules.rb
+++ b/lib/gitlab/ci/config/entry/rules.rb
@@ -4,7 +4,7 @@ module Gitlab
module Ci
class Config
module Entry
- class Rules < ::Gitlab::Config::Entry::Node
+ class Rules < ::Gitlab::Config::Entry::ComposableArray
include ::Gitlab::Config::Entry::Validatable
validations do
@@ -12,24 +12,13 @@ module Gitlab
validates :config, type: Array
end
- def compose!(deps = nil)
- super(deps) do
- @config.each_with_index do |rule, index|
- @entries[index] = ::Gitlab::Config::Entry::Factory.new(Entry::Rules::Rule)
- .value(rule)
- .with(key: "rule", parent: self, description: "rule definition.") # rubocop:disable CodeReuse/ActiveRecord
- .create!
- end
-
- @entries.each_value do |entry|
- entry.compose!(deps)
- end
- end
- end
-
def value
@config
end
+
+ def composable_class
+ Entry::Rules::Rule
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/services.rb b/lib/gitlab/ci/config/entry/services.rb
index 83baa83711f..44e2903a300 100644
--- a/lib/gitlab/ci/config/entry/services.rb
+++ b/lib/gitlab/ci/config/entry/services.rb
@@ -7,7 +7,7 @@ module Gitlab
##
# Entry that represents a configuration of Docker services.
#
- class Services < ::Gitlab::Config::Entry::Node
+ class Services < ::Gitlab::Config::Entry::ComposableArray
include ::Gitlab::Config::Entry::Validatable
validations do
@@ -15,28 +15,8 @@ module Gitlab
validates :config, services_with_ports_alias_unique: true, if: ->(record) { record.opt(:with_image_ports) }
end
- def compose!(deps = nil)
- super do
- @entries = []
- @config.each do |config|
- @entries << ::Gitlab::Config::Entry::Factory.new(Entry::Service)
- .value(config || {})
- .with(key: "service", parent: self, description: "service definition.") # rubocop:disable CodeReuse/ActiveRecord
- .create!
- end
-
- @entries.each do |entry|
- entry.compose!(deps)
- end
- end
- end
-
- def value
- @entries.map(&:value)
- end
-
- def descendants
- @entries
+ def composable_class
+ Entry::Service
end
end
end
diff --git a/lib/gitlab/ci/config/entry/variables.rb b/lib/gitlab/ci/config/entry/variables.rb
index c9d0c7cb568..e258f7128fc 100644
--- a/lib/gitlab/ci/config/entry/variables.rb
+++ b/lib/gitlab/ci/config/entry/variables.rb
@@ -10,16 +10,32 @@ module Gitlab
class Variables < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Validatable
+ ALLOWED_VALUE_DATA = %i[value description].freeze
+
validations do
- validates :config, variables: true
+ validates :config, variables: { allowed_value_data: ALLOWED_VALUE_DATA }
+ end
+
+ def value
+ Hash[@config.map { |key, value| [key.to_s, expand_value(value)[:value]] }]
end
def self.default(**)
{}
end
- def value
- Hash[@config.map { |key, value| [key.to_s, value.to_s] }]
+ def value_with_data
+ Hash[@config.map { |key, value| [key.to_s, expand_value(value)] }]
+ end
+
+ private
+
+ def expand_value(value)
+ if value.is_a?(Hash)
+ { value: value[:value].to_s, description: value[:description] }
+ else
+ { value: value.to_s, description: nil }
+ end
end
end
end
diff --git a/lib/gitlab/ci/features.rb b/lib/gitlab/ci/features.rb
index e770187b124..1b58e3ec71a 100644
--- a/lib/gitlab/ci/features.rb
+++ b/lib/gitlab/ci/features.rb
@@ -10,10 +10,6 @@ module Gitlab
::Feature.enabled?(:ci_artifacts_exclude, default_enabled: true)
end
- def self.job_heartbeats_runner?(project)
- ::Feature.enabled?(:ci_job_heartbeats_runner, project, default_enabled: true)
- end
-
def self.instance_variables_ui_enabled?
::Feature.enabled?(:ci_instance_variables_ui, default_enabled: true)
end
@@ -35,10 +31,6 @@ module Gitlab
::Feature.enabled?(:ci_raise_job_rules_without_workflow_rules_warning, default_enabled: true)
end
- def self.bulk_insert_on_create?(project)
- ::Feature.enabled?(:ci_bulk_insert_on_create, project, default_enabled: true)
- end
-
# NOTE: The feature flag `disallow_to_create_merge_request_pipelines_in_target_project`
# is a safe switch to disable the feature for a parituclar project when something went wrong,
# therefore it's not supposed to be enabled by default.
@@ -54,25 +46,25 @@ module Gitlab
Feature.enabled?(:project_transactionless_destroy, project, default_enabled: false)
end
- def self.coverage_report_view?(project)
- ::Feature.enabled?(:coverage_report_view, project, default_enabled: true)
- end
-
- def self.child_of_child_pipeline_enabled?(project)
- ::Feature.enabled?(:ci_child_of_child_pipeline, project, default_enabled: true)
- end
-
def self.trace_overwrite?
::Feature.enabled?(:ci_trace_overwrite, type: :ops, default_enabled: false)
end
def self.accept_trace?(project)
::Feature.enabled?(:ci_enable_live_trace, project) &&
- ::Feature.enabled?(:ci_accept_trace, project, type: :ops, default_enabled: false)
+ ::Feature.enabled?(:ci_accept_trace, project, type: :ops, default_enabled: true)
+ end
+
+ def self.log_invalid_trace_chunks?(project)
+ ::Feature.enabled?(:ci_trace_log_invalid_chunks, project, type: :ops, default_enabled: false)
+ end
+
+ def self.one_dimensional_matrix_enabled?
+ ::Feature.enabled?(:one_dimensional_matrix, default_enabled: true)
end
- def self.new_artifact_file_reader_enabled?(project)
- ::Feature.enabled?(:ci_new_artifact_file_reader, project, default_enabled: false)
+ def self.manual_bridges_enabled?(project)
+ ::Feature.enabled?(:ci_manual_bridges, project, default_enabled: true)
end
end
end
diff --git a/lib/gitlab/ci/lint.rb b/lib/gitlab/ci/lint.rb
index 86a9ebfa451..44f2ac23ce3 100644
--- a/lib/gitlab/ci/lint.rb
+++ b/lib/gitlab/ci/lint.rb
@@ -4,10 +4,11 @@ module Gitlab
module Ci
class Lint
class Result
- attr_reader :jobs, :errors, :warnings
+ attr_reader :jobs, :merged_yaml, :errors, :warnings
- def initialize(jobs:, errors:, warnings:)
+ def initialize(jobs:, merged_yaml:, errors:, warnings:)
@jobs = jobs
+ @merged_yaml = merged_yaml
@errors = errors
@warnings = warnings
end
@@ -39,6 +40,7 @@ module Gitlab
Result.new(
jobs: dry_run_convert_to_jobs(pipeline.stages),
+ merged_yaml: pipeline.merged_yaml,
errors: pipeline.error_messages.map(&:content),
warnings: pipeline.warning_messages(limit: ::Gitlab::Ci::Warnings::MAX_LIMIT).map(&:content)
)
@@ -54,6 +56,7 @@ module Gitlab
Result.new(
jobs: static_validation_convert_to_jobs(result),
+ merged_yaml: result.merged_yaml,
errors: result.errors,
warnings: result.warnings.take(::Gitlab::Ci::Warnings::MAX_LIMIT) # rubocop: disable CodeReuse/ActiveRecord
)
diff --git a/lib/gitlab/ci/parsers/test/junit.rb b/lib/gitlab/ci/parsers/test/junit.rb
index 5746f38ae5b..50cd703da4a 100644
--- a/lib/gitlab/ci/parsers/test/junit.rb
+++ b/lib/gitlab/ci/parsers/test/junit.rb
@@ -8,12 +8,17 @@ module Gitlab
JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
ATTACHMENT_TAG_REGEX = /\[\[ATTACHMENT\|(?<path>.+?)\]\]/.freeze
- def parse!(xml_data, test_suite, **args)
+ def parse!(xml_data, test_suite, job:)
root = Hash.from_xml(xml_data)
+ total_parsed = 0
+ max_test_cases = job.max_test_cases_per_report
all_cases(root) do |test_case|
- test_case = create_test_case(test_case, args)
+ test_case = create_test_case(test_case, test_suite, job)
test_suite.add_test_case(test_case)
+ total_parsed += 1
+
+ ensure_test_cases_limited!(total_parsed, max_test_cases)
end
rescue Nokogiri::XML::SyntaxError => e
test_suite.set_suite_error("JUnit XML parsing failed: #{e}")
@@ -23,6 +28,12 @@ module Gitlab
private
+ def ensure_test_cases_limited!(total_parsed, limit)
+ return unless limit > 0 && total_parsed > limit
+
+ raise JunitParserError.new("number of test cases exceeded the limit of #{limit}")
+ end
+
def all_cases(root, parent = nil, &blk)
return unless root.present?
@@ -33,20 +44,24 @@ module Gitlab
all_cases(node['testsuites'], root, &blk) unless parent
# we require at least one level of testsuites or testsuite
- each_case(node['testcase'], &blk) if parent
+ each_case(node['testcase'], node['name'], &blk) if parent
# we allow multiple nested 'testsuite' (eg. PHPUnit)
all_cases(node['testsuite'], root, &blk)
end
end
- def each_case(testcase, &blk)
+ def each_case(testcase, testsuite_name, &blk)
return unless testcase.present?
- [testcase].flatten.compact.map(&blk)
+ [testcase].flatten.compact.each do |tc|
+ tc['suite_name'] = testsuite_name
+
+ yield(tc)
+ end
end
- def create_test_case(data, args)
+ def create_test_case(data, test_suite, job)
if data.key?('failure')
status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED
system_output = data['failure']
@@ -63,6 +78,7 @@ module Gitlab
end
::Gitlab::Ci::Reports::TestCase.new(
+ suite_name: data['suite_name'] || test_suite.name,
classname: data['classname'],
name: data['name'],
file: data['file'],
@@ -70,10 +86,14 @@ module Gitlab
status: status,
system_output: system_output,
attachment: attachment,
- job: args.fetch(:job)
+ job: job
)
end
+ def suite_name(parent, test_suite)
+ parent.dig('testsuite', 'name') || test_suite.name
+ end
+
def attachment_path(data)
return unless data
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index d1882059dd8..06096a33f27 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -16,7 +16,7 @@ module Gitlab
) do
include Gitlab::Utils::StrongMemoize
- def initialize(**params)
+ def initialize(params = {})
params.each do |key, value|
self[key] = value
end
diff --git a/lib/gitlab/ci/pipeline/chain/config/process.rb b/lib/gitlab/ci/pipeline/chain/config/process.rb
index 8ccb33ffd34..c3fbd0c9e24 100644
--- a/lib/gitlab/ci/pipeline/chain/config/process.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/process.rb
@@ -28,6 +28,8 @@ module Gitlab
error(result.errors.first, config_error: true)
end
+ @pipeline.merged_yaml = result.merged_yaml
+
rescue => ex
Gitlab::ErrorTracking.track_exception(ex,
project_id: project.id,
diff --git a/lib/gitlab/ci/pipeline/chain/create.rb b/lib/gitlab/ci/pipeline/chain/create.rb
index 34649fe16f3..81ef3bb074d 100644
--- a/lib/gitlab/ci/pipeline/chain/create.rb
+++ b/lib/gitlab/ci/pipeline/chain/create.rb
@@ -8,7 +8,7 @@ module Gitlab
include Chain::Helpers
def perform!
- BulkInsertableAssociations.with_bulk_insert(enabled: ::Gitlab::Ci::Features.bulk_insert_on_create?(project)) do
+ BulkInsertableAssociations.with_bulk_insert do
pipeline.save!
end
rescue ActiveRecord::RecordInvalid => e
diff --git a/lib/gitlab/ci/pipeline/seed/build/cache.rb b/lib/gitlab/ci/pipeline/seed/build/cache.rb
index a4127ea0be2..8d6fe13c3b9 100644
--- a/lib/gitlab/ci/pipeline/seed/build/cache.rb
+++ b/lib/gitlab/ci/pipeline/seed/build/cache.rb
@@ -13,6 +13,7 @@ module Gitlab
@paths = local_cache.delete(:paths)
@policy = local_cache.delete(:policy)
@untracked = local_cache.delete(:untracked)
+ @when = local_cache.delete(:when)
raise ArgumentError, "unknown cache keys: #{local_cache.keys}" if local_cache.any?
end
@@ -24,7 +25,8 @@ module Gitlab
key: key_string,
paths: @paths,
policy: @policy,
- untracked: @untracked
+ untracked: @untracked,
+ when: @when
}.compact.presence
}.compact
}
diff --git a/lib/gitlab/ci/reports/test_case.rb b/lib/gitlab/ci/reports/test_case.rb
index 15a3c862c9e..8c70dbb6931 100644
--- a/lib/gitlab/ci/reports/test_case.rb
+++ b/lib/gitlab/ci/reports/test_case.rb
@@ -10,9 +10,10 @@ module Gitlab
STATUS_ERROR = 'error'
STATUS_TYPES = [STATUS_ERROR, STATUS_FAILED, STATUS_SUCCESS, STATUS_SKIPPED].freeze
- attr_reader :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment, :job
+ attr_reader :suite_name, :name, :classname, :execution_time, :status, :file, :system_output, :stack_trace, :key, :attachment, :job
def initialize(params)
+ @suite_name = params.fetch(:suite_name)
@name = params.fetch(:name)
@classname = params.fetch(:classname)
@file = params.fetch(:file, nil)
@@ -23,7 +24,7 @@ module Gitlab
@attachment = params.fetch(:attachment, nil)
@job = params.fetch(:job, nil)
- @key = sanitize_key_name("#{classname}_#{name}")
+ @key = hash_key("#{suite_name}_#{classname}_#{name}")
end
def has_attachment?
@@ -42,8 +43,8 @@ module Gitlab
private
- def sanitize_key_name(key)
- key.gsub(/[^0-9A-Za-z]/, '-')
+ def hash_key(key)
+ Digest::SHA256.hexdigest(key)
end
end
end
diff --git a/lib/gitlab/ci/reports/test_suite.rb b/lib/gitlab/ci/reports/test_suite.rb
index e9b78b841e4..00920dfbd54 100644
--- a/lib/gitlab/ci/reports/test_suite.rb
+++ b/lib/gitlab/ci/reports/test_suite.rb
@@ -12,18 +12,24 @@ module Gitlab
def initialize(name = nil)
@name = name
@test_cases = {}
+ @all_test_cases = []
@total_time = 0.0
- @duplicate_cases = []
end
def add_test_case(test_case)
- @duplicate_cases << test_case if existing_key?(test_case)
-
@test_cases[test_case.status] ||= {}
@test_cases[test_case.status][test_case.key] = test_case
@total_time += test_case.execution_time
end
+ def each_test_case
+ @test_cases.each do |status, test_cases|
+ test_cases.values.each do |test_case|
+ yield test_case
+ end
+ end
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def total_count
return 0 if suite_error
@@ -86,10 +92,6 @@ module Gitlab
private
- def existing_key?(test_case)
- @test_cases[test_case.status]&.key?(test_case.key)
- end
-
def sort_by_status
@test_cases = @test_cases.sort_by { |status, _| Gitlab::Ci::Reports::TestCase::STATUS_TYPES.index(status) }.to_h
end
diff --git a/lib/gitlab/ci/runner/backoff.rb b/lib/gitlab/ci/runner/backoff.rb
new file mode 100644
index 00000000000..95d7719e9cb
--- /dev/null
+++ b/lib/gitlab/ci/runner/backoff.rb
@@ -0,0 +1,75 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Runner
+ ##
+ # Runner Backoff class is an implementation of an exponential backoff
+ # used when a runner communicates with GitLab. We typically use it when a
+ # runner retries sending a build status after we created a build pending
+ # state.
+ #
+ # Backoff is calculated based on the backoff slot which is always a power
+ # of 2:
+ #
+ # 0s - 3s duration -> 1 second backoff
+ # 4s - 7s duration -> 2 seconds backoff
+ # 8s - 15s duration -> 4 seconds backoff
+ # 16s - 31s duration -> 8 seconds backoff
+ # 32s - 63s duration -> 16 seconds backoff
+ # 64s - 127s duration -> 32 seconds backoff
+ # 127s - 256s+ duration -> 64 seconds backoff
+ #
+ # It means that first 15 requests made by a runner will need to respect
+ # following backoffs:
+ #
+ # 0s -> 1 second backoff (backoff started, slot 0, 2^0 backoff)
+ # 1s -> 1 second backoff
+ # 2s -> 1 second backoff
+ # 3s -> 1 seconds backoff
+ # (slot 1 - 2^1 backoff)
+ # 4s -> 2 seconds backoff
+ # 6s -> 2 seconds backoff
+ # (slot 2 - 2^2 backoff)
+ # 8s -> 4 seconds backoff
+ # 12s -> 4 seconds backoff
+ # (slot 3 - 2^3 backoff)
+ # 16s -> 8 seconds backoff
+ # 24s -> 8 seconds backoff
+ # (slot 4 - 2^4 backoff)
+ # 32s -> 16 seconds backoff
+ # 48s -> 16 seconds backoff
+ # (slot 5 - 2^5 backoff)
+ # 64s -> 32 seconds backoff
+ # 96s -> 32 seconds backoff
+ # (slot 6 - 2^6 backoff)
+ # 128s -> 64 seconds backoff
+ #
+ # There is a cap on the backoff - it will never exceed 64 seconds.
+ #
+ class Backoff
+ def initialize(started)
+ @started = started
+
+ if duration < 0
+ raise ArgumentError, 'backoff duration negative'
+ end
+ end
+
+ def duration
+ (Time.current - @started).ceil
+ end
+
+ def slot
+ return 0 if duration < 2
+
+ Math.log(duration, 2).floor - 1
+ end
+
+ def to_seconds
+ 2**[slot, 6].min
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/status/bridge/action.rb b/lib/gitlab/ci/status/bridge/action.rb
new file mode 100644
index 00000000000..1ba4700d9b0
--- /dev/null
+++ b/lib/gitlab/ci/status/bridge/action.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Status
+ module Bridge
+ class Action < Status::Build::Action
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/status/bridge/common.rb b/lib/gitlab/ci/status/bridge/common.rb
index b95565b5e09..d66d4b20bba 100644
--- a/lib/gitlab/ci/status/bridge/common.rb
+++ b/lib/gitlab/ci/status/bridge/common.rb
@@ -14,7 +14,6 @@ module Gitlab
end
def details_path
- return unless Feature.enabled?(:ci_bridge_pipeline_details, subject.project, default_enabled: true)
return unless can?(user, :read_pipeline, downstream_pipeline)
project_pipeline_path(downstream_project, downstream_pipeline)
diff --git a/lib/gitlab/ci/status/bridge/factory.rb b/lib/gitlab/ci/status/bridge/factory.rb
index 5d397dba0de..b9bd66cee71 100644
--- a/lib/gitlab/ci/status/bridge/factory.rb
+++ b/lib/gitlab/ci/status/bridge/factory.rb
@@ -6,7 +6,10 @@ module Gitlab
module Bridge
class Factory < Status::Factory
def self.extended_statuses
- [Status::Bridge::Failed]
+ [[Status::Bridge::Failed],
+ [Status::Bridge::Manual],
+ [Status::Bridge::Play],
+ [Status::Bridge::Action]]
end
def self.common_helpers
diff --git a/lib/gitlab/ci/status/bridge/manual.rb b/lib/gitlab/ci/status/bridge/manual.rb
new file mode 100644
index 00000000000..e07e645a34d
--- /dev/null
+++ b/lib/gitlab/ci/status/bridge/manual.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Status
+ module Bridge
+ class Manual < Status::Build::Manual
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/status/bridge/play.rb b/lib/gitlab/ci/status/bridge/play.rb
new file mode 100644
index 00000000000..ae00ef6c2ad
--- /dev/null
+++ b/lib/gitlab/ci/status/bridge/play.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Status
+ module Bridge
+ class Play < Status::Build::Play
+ def has_action?
+ can?(user, :play_job, subject)
+ end
+
+ def self.matches?(bridge, user)
+ bridge.playable?
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/status/canceled.rb b/lib/gitlab/ci/status/canceled.rb
index 07f37732023..f173964b36c 100644
--- a/lib/gitlab/ci/status/canceled.rb
+++ b/lib/gitlab/ci/status/canceled.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_canceled'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/created.rb b/lib/gitlab/ci/status/created.rb
index fface4bb97b..33e67314d93 100644
--- a/lib/gitlab/ci/status/created.rb
+++ b/lib/gitlab/ci/status/created.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_created'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/failed.rb b/lib/gitlab/ci/status/failed.rb
index 770ed7d4d5a..215d27734a7 100644
--- a/lib/gitlab/ci/status/failed.rb
+++ b/lib/gitlab/ci/status/failed.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_failed'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/manual.rb b/lib/gitlab/ci/status/manual.rb
index 50c92add400..eb376df5f22 100644
--- a/lib/gitlab/ci/status/manual.rb
+++ b/lib/gitlab/ci/status/manual.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_manual'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/pending.rb b/lib/gitlab/ci/status/pending.rb
index cea7e6ed938..4280ad84534 100644
--- a/lib/gitlab/ci/status/pending.rb
+++ b/lib/gitlab/ci/status/pending.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_pending'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/preparing.rb b/lib/gitlab/ci/status/preparing.rb
index 1ebdbc482b7..e59d1d2eed1 100644
--- a/lib/gitlab/ci/status/preparing.rb
+++ b/lib/gitlab/ci/status/preparing.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_preparing'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/running.rb b/lib/gitlab/ci/status/running.rb
index ac7dd74cdce..eed1983e60e 100644
--- a/lib/gitlab/ci/status/running.rb
+++ b/lib/gitlab/ci/status/running.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_running'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/scheduled.rb b/lib/gitlab/ci/status/scheduled.rb
index 16ad1da89e3..e9068c326cf 100644
--- a/lib/gitlab/ci/status/scheduled.rb
+++ b/lib/gitlab/ci/status/scheduled.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_scheduled'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/skipped.rb b/lib/gitlab/ci/status/skipped.rb
index aaec1e1d201..238aa3ab4f9 100644
--- a/lib/gitlab/ci/status/skipped.rb
+++ b/lib/gitlab/ci/status/skipped.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_skipped'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/success.rb b/lib/gitlab/ci/status/success.rb
index 020f2c5b89f..2a10e60414e 100644
--- a/lib/gitlab/ci/status/success.rb
+++ b/lib/gitlab/ci/status/success.rb
@@ -19,6 +19,10 @@ module Gitlab
def favicon
'favicon_status_success'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/status/waiting_for_resource.rb b/lib/gitlab/ci/status/waiting_for_resource.rb
index 4c9e706bc51..2026148f752 100644
--- a/lib/gitlab/ci/status/waiting_for_resource.rb
+++ b/lib/gitlab/ci/status/waiting_for_resource.rb
@@ -23,6 +23,10 @@ module Gitlab
def group
'waiting-for-resource'
end
+
+ def details_path
+ nil
+ end
end
end
end
diff --git a/lib/gitlab/ci/templates/AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml b/lib/gitlab/ci/templates/AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml
new file mode 100644
index 00000000000..267027a1b8a
--- /dev/null
+++ b/lib/gitlab/ci/templates/AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml
@@ -0,0 +1,11 @@
+stages:
+ - provision
+ - review
+ - production
+
+variables:
+ AUTO_DEVOPS_PLATFORM_TARGET: EC2
+
+include:
+ - template: Jobs/CF-Provision.gitlab-ci.yml
+ - template: Jobs/Deploy/EC2.gitlab-ci.yml
diff --git a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
index 6966ce88b30..cba13f374f4 100644
--- a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
@@ -20,6 +20,7 @@
# * dast: DAST_DISABLED
# * review: REVIEW_DISABLED
# * stop_review: REVIEW_DISABLED
+# * code_intelligence: CODE_INTELLIGENCE_DISABLED
#
# In order to deploy, you must have a Kubernetes cluster configured either
# via a project integration, or via group/project variables.
@@ -159,6 +160,7 @@ include:
- template: Jobs/Build.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
- template: Jobs/Test.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Test.gitlab-ci.yml
- template: Jobs/Code-Quality.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+ - template: Jobs/Code-Intelligence.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Code-Intelligence.gitlab-ci.yml
- template: Jobs/Deploy.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
- template: Jobs/Deploy/ECS.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
- template: Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
diff --git a/lib/gitlab/ci/templates/Bash.gitlab-ci.yml b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
index 368069844ea..67e58d9ee99 100644
--- a/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
@@ -1,4 +1,4 @@
-# see https://docs.gitlab.com/ce/ci/yaml/README.html for all available options
+# see https://docs.gitlab.com/ee/ci/yaml/README.html for all available options
# you can delete this line if you're not using Docker
image: busybox:latest
diff --git a/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
index c3568c0d2c8..0c5850bdb8e 100644
--- a/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
@@ -1,7 +1,7 @@
# Based on openjdk:8, already includes lein
image: clojure:lein-2.7.0
# If you need to configure a database, add a `services` section here
-# See https://docs.gitlab.com/ce/ci/services/postgres.html
+# See https://docs.gitlab.com/ee/ci/services/postgres.html
# Make sure you configure the connection as well
before_script:
diff --git a/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
index e9301a2638d..538f96c4084 100644
--- a/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
@@ -4,7 +4,7 @@ image: "crystallang/crystal:latest"
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
-# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
+# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# services:
# - mysql:latest
# - redis:latest
diff --git a/lib/gitlab/ci/templates/Django.gitlab-ci.yml b/lib/gitlab/ci/templates/Django.gitlab-ci.yml
index d35fcb0f807..c657c7e8eb1 100644
--- a/lib/gitlab/ci/templates/Django.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Django.gitlab-ci.yml
@@ -4,7 +4,7 @@ image: python:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
-# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
+# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
services:
- mysql:latest
- postgres:latest
@@ -13,7 +13,7 @@ variables:
POSTGRES_DB: database_name
# This folder is cached between builds
-# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
+# http://docs.gitlab.com/ee/ci/yaml/README.html#cache
cache:
paths:
- ~/.cache/pip/
diff --git a/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
index 4d4c6a64cd5..7271526ab1b 100644
--- a/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
@@ -2,7 +2,7 @@ image: elixir:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
-# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
+# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
services:
- mysql:latest
- redis:latest
diff --git a/lib/gitlab/ci/templates/Jobs/CF-Provision.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/CF-Provision.gitlab-ci.yml
new file mode 100644
index 00000000000..31ca68c57d7
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/CF-Provision.gitlab-ci.yml
@@ -0,0 +1,14 @@
+stages:
+ - provision
+
+cloud_formation:
+ image: 'registry.gitlab.com/gitlab-org/cloud-deploy/aws-cloudformation:latest'
+ stage: provision
+ script:
+ - gl-cloudformation create-stack
+ rules:
+ - if: '($AUTO_DEVOPS_PLATFORM_TARGET != "EC2") || ($AUTO_DEVOPS_PLATFORM_TARGET != "ECS")'
+ when: never
+ - if: '$CI_KUBERNETES_ACTIVE'
+ when: never
+ - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
diff --git a/lib/gitlab/ci/templates/Jobs/Code-Intelligence.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Code-Intelligence.gitlab-ci.yml
new file mode 100644
index 00000000000..83bc5548614
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/Code-Intelligence.gitlab-ci.yml
@@ -0,0 +1,16 @@
+code_intelligence_go:
+ stage: test
+ needs: []
+ allow_failure: true
+ image: sourcegraph/lsif-go:v1
+ rules:
+ - if: $CODE_INTELLIGENCE_DISABLED
+ when: never
+ - if: $CI_COMMIT_BRANCH
+ exists:
+ - '**/*.go'
+ script:
+ - lsif-go
+ artifacts:
+ reports:
+ lsif: dump.lsif
diff --git a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
index 568ceceeaa2..ec33020205b 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -9,9 +9,8 @@ code_quality:
DOCKER_TLS_CERTDIR: ""
CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.10-gitlab.1"
needs: []
- before_script:
- - export SOURCE_CODE=$PWD
script:
+ - export SOURCE_CODE=$PWD
- |
if ! docker info &>/dev/null; then
if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
diff --git a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
index 86f946aafda..77216a6e404 100644
--- a/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
.dast-auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.3"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.5"
dast_environment_deploy:
extends: .dast-auto-deploy
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 829fd7a722f..32a207a85d1 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,5 +1,5 @@
.auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.3"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.5"
dependencies: []
review:
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
index 829fd7a722f..8b921305c11 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
@@ -1,5 +1,5 @@
.auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v1.0.3"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v2.0.0-beta.2"
dependencies: []
review:
@@ -91,7 +91,7 @@ canary:
- auto-deploy ensure_namespace
- auto-deploy initialize_tiller
- auto-deploy create_secret
- - auto-deploy deploy canary
+ - auto-deploy deploy canary 50
environment:
name: production
url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
@@ -114,7 +114,6 @@ canary:
- auto-deploy create_secret
- auto-deploy deploy
- auto-deploy delete canary
- - auto-deploy delete rollout
- auto-deploy persist_environment_url
environment:
name: production
@@ -163,9 +162,7 @@ production_manual:
- auto-deploy ensure_namespace
- auto-deploy initialize_tiller
- auto-deploy create_secret
- - auto-deploy deploy rollout $ROLLOUT_PERCENTAGE
- - auto-deploy scale stable $((100-ROLLOUT_PERCENTAGE))
- - auto-deploy delete canary
+ - auto-deploy deploy canary $ROLLOUT_PERCENTAGE
- auto-deploy persist_environment_url
environment:
name: production
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy/EC2.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy/EC2.gitlab-ci.yml
new file mode 100644
index 00000000000..ed2172ef7f5
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/Deploy/EC2.gitlab-ci.yml
@@ -0,0 +1,39 @@
+stages:
+ - review
+ - production
+
+.push-and-deploy:
+ image: 'registry.gitlab.com/gitlab-org/cloud-deploy/aws-ec2:latest'
+ script:
+ - gl-ec2 push-to-s3
+ - gl-ec2 deploy-to-ec2
+
+review_ec2:
+ extends: .push-and-deploy
+ stage: review
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ rules:
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET != "EC2"'
+ when: never
+ - if: '$CI_KUBERNETES_ACTIVE'
+ when: never
+ - if: '$REVIEW_DISABLED'
+ when: never
+ - if: '$CI_COMMIT_BRANCH == "master"'
+ when: never
+ - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+
+production_ec2:
+ extends: .push-and-deploy
+ stage: production
+ environment:
+ name: production
+ rules:
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET != "EC2"'
+ when: never
+ - if: '$CI_KUBERNETES_ACTIVE'
+ when: never
+ - if: '$CI_COMMIT_BRANCH != "master"'
+ when: never
+ - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
index da474f8ac88..317e8bfab0e 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
@@ -10,6 +10,7 @@
.deploy_to_ecs:
image: 'registry.gitlab.com/gitlab-org/cloud-deploy/aws-ecs:latest'
+ dependencies: []
script:
- ecs update-task-definition
diff --git a/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
index 9bde04dff19..5d2c8024524 100644
--- a/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
@@ -4,7 +4,7 @@ image: php:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
-# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
+# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
services:
- mysql:latest
@@ -13,7 +13,7 @@ variables:
MYSQL_ROOT_PASSWORD: secret
# This folder is cached between builds
-# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
+# http://docs.gitlab.com/ee/ci/yaml/README.html#cache
cache:
paths:
- vendor/
diff --git a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
index 7050b41e045..a9638f564f3 100644
--- a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
@@ -1,6 +1,6 @@
apply:
stage: deploy
- image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.29.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.33.0"
environment:
name: production
variables:
diff --git a/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
index b87178141a1..92379ded77c 100644
--- a/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
@@ -4,14 +4,14 @@ image: node:latest
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
-# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
+# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
services:
- mysql:latest
- redis:latest
- postgres:latest
# This folder is cached between builds
-# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
+# http://docs.gitlab.com/ee/ci/yaml/README.html#cache
cache:
paths:
- node_modules/
diff --git a/lib/gitlab/ci/templates/PHP.gitlab-ci.yml b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
index 25ea20e454f..84e8223e69b 100644
--- a/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
@@ -19,7 +19,7 @@ before_script:
- php composer.phar install
# Bring in any services we need http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
-# See http://docs.gitlab.com/ce/ci/services/README.html for examples.
+# See http://docs.gitlab.com/ee/ci/services/README.html for examples.
services:
- mysql:5.7
diff --git a/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml
index a683561a455..3a6eac63892 100644
--- a/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Gatsby.gitlab-ci.yml
@@ -1,7 +1,7 @@
image: node:latest
# This folder is cached between builds
-# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
+# http://docs.gitlab.com/ee/ci/yaml/README.html#cache
cache:
paths:
- node_modules/
diff --git a/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml b/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml
index 0c8859dc779..f2f92fe0704 100644
--- a/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Pages/Jekyll.gitlab-ci.yml
@@ -1,5 +1,5 @@
# Template project: https://gitlab.com/pages/jekyll
-# Docs: https://docs.gitlab.com/ce/pages/
+# Docs: https://docs.gitlab.com/ee/pages/
image: ruby:2.6
variables:
diff --git a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
index b3cad8b858a..275364afae4 100644
--- a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
@@ -4,7 +4,7 @@ image: "ruby:2.5"
# Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
-# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
+# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
services:
- mysql:latest
- redis:latest
diff --git a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
index f35470367cc..94117a79d1c 100644
--- a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
@@ -4,7 +4,7 @@ image: "rust:latest"
# Optional: Pick zero or more services to be used on all builds.
# Only needed when using a docker container to run your tests in.
-# Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service
+# Check out: http://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service
# services:
# - mysql:latest
# - redis:latest
diff --git a/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
index 4b957a8f771..e268b48d133 100644
--- a/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
@@ -35,4 +35,3 @@ variables:
- if: $COVFUZZ_DISABLED
when: never
- if: $CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bcoverage_fuzzing\b/
- - if: $CI_RUNNER_EXECUTABLE_ARCH == "linux"
diff --git a/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
index cc34d23decc..63237e41376 100644
--- a/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
@@ -1,7 +1,7 @@
# Read more about this feature here: https://docs.gitlab.com/ee/user/application_security/license_compliance/
#
# Configure the scanning tool through the environment variables.
-# List of the variables: https://gitlab.com/gitlab-org/security-products/license-management#settings
+# List of the variables: https://gitlab.com/gitlab-org/security-products/analyzers/license-finder#settings
# How to set: https://docs.gitlab.com/ee/ci/yaml/#variables
variables:
diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
index 77ea11d01d1..4418ff18d73 100644
--- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
@@ -9,7 +9,7 @@ variables:
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
- SAST_DEFAULT_ANALYZERS: "bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, sobelow, pmd-apex, kubesec"
+ SAST_DEFAULT_ANALYZERS: "bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, sobelow, pmd-apex, kubesec, mobsf"
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
SAST_ANALYZER_IMAGE_TAG: 2
SCAN_KUBERNETES_MANIFESTS: "false"
@@ -125,6 +125,42 @@ gosec-sast:
exists:
- '**/*.go'
+mobsf-android-sast:
+ extends: .sast-analyzer
+ services:
+ - name: opensecurity/mobile-security-framework-mobsf:latest
+ alias: mobsf
+ image:
+ name: "$SAST_ANALYZER_IMAGE"
+ variables:
+ SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
+ rules:
+ - if: $SAST_DISABLED
+ when: never
+ - if: $CI_COMMIT_BRANCH &&
+ $SAST_DEFAULT_ANALYZERS =~ /mobsf/ &&
+ $SAST_EXPERIMENTAL_FEATURES == 'true'
+ exists:
+ - '**/AndroidManifest.xml'
+
+mobsf-ios-sast:
+ extends: .sast-analyzer
+ services:
+ - name: opensecurity/mobile-security-framework-mobsf:latest
+ alias: mobsf
+ image:
+ name: "$SAST_ANALYZER_IMAGE"
+ variables:
+ SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
+ rules:
+ - if: $SAST_DISABLED
+ when: never
+ - if: $CI_COMMIT_BRANCH &&
+ $SAST_DEFAULT_ANALYZERS =~ /mobsf/ &&
+ $SAST_EXPERIMENTAL_FEATURES == 'true'
+ exists:
+ - '**/*.xcodeproj/*'
+
nodejs-scan-sast:
extends: .sast-analyzer
image:
@@ -203,6 +239,11 @@ spotbugs-sast:
variables:
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/spotbugs:$SAST_ANALYZER_IMAGE_TAG"
rules:
+ - if: $SAST_DEFAULT_ANALYZERS =~ /mobsf/ &&
+ $SAST_EXPERIMENTAL_FEATURES == 'true'
+ exists:
+ - '**/AndroidManifest.xml'
+ when: never
- if: $SAST_DISABLED
when: never
- if: $CI_COMMIT_BRANCH &&
diff --git a/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
index bde6a0fbebb..6ebff102ccb 100644
--- a/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
@@ -34,8 +34,8 @@ secret_detection:
when: never
- if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
script:
- - git fetch origin $CI_DEFAULT_BRANCH $CI_BUILD_REF_NAME
- - git log --left-right --cherry-pick --pretty=format:"%H" refs/remotes/origin/$CI_DEFAULT_BRANCH...refs/remotes/origin/$CI_BUILD_REF_NAME > "$CI_COMMIT_SHA"_commit_list.txt
+ - git fetch origin $CI_DEFAULT_BRANCH $CI_COMMIT_REF_NAME
+ - git log --left-right --cherry-pick --pretty=format:"%H" refs/remotes/origin/$CI_DEFAULT_BRANCH...refs/remotes/origin/$CI_COMMIT_REF_NAME > "$CI_COMMIT_SHA"_commit_list.txt
- export SECRET_DETECTION_COMMITS_FILE="$CI_COMMIT_SHA"_commit_list.txt
- /analyzer run
- rm "$CI_COMMIT_SHA"_commit_list.txt
diff --git a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..b08ccf18b58
--- /dev/null
+++ b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
@@ -0,0 +1,22 @@
+include:
+ - template: Terraform/Base.latest.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml
+
+stages:
+ - init
+ - validate
+ - build
+ - deploy
+
+init:
+ extends: .init
+
+validate:
+ extends: .validate
+
+build:
+ extends: .build
+
+deploy:
+ extends: .deploy
+ dependencies:
+ - build
diff --git a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
new file mode 100644
index 00000000000..000a1a7f580
--- /dev/null
+++ b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
@@ -0,0 +1,53 @@
+# Terraform/Base.latest
+#
+# The purpose of this template is to provide flexibility to the user so
+# they are able to only include the jobs that they find interesting.
+#
+# Therefore, this template is not supposed to run any jobs. The idea is to only
+# create hidden jobs. See: https://docs.gitlab.com/ee/ci/yaml/#hide-jobs
+#
+# There is a more opinionated template which we suggest the users to abide,
+# which is the lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
+
+image:
+ name: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
+
+before_script:
+ - cd ${TF_ROOT}
+
+variables:
+ TF_ROOT: ${CI_PROJECT_DIR}
+
+cache:
+ key: "${TF_ROOT}"
+ paths:
+ - ${TF_ROOT}/.terraform/
+
+.init: &init
+ stage: init
+ script:
+ - gitlab-terraform init
+
+.validate: &validate
+ stage: validate
+ script:
+ - gitlab-terraform validate
+
+.build: &build
+ stage: build
+ script:
+ - gitlab-terraform plan
+ - gitlab-terraform plan-json
+ artifacts:
+ paths:
+ - ${TF_ROOT}/plan.cache
+ reports:
+ terraform: ${TF_ROOT}/plan.json
+
+.deploy: &deploy
+ stage: deploy
+ script:
+ - gitlab-terraform apply
+ when: manual
+ only:
+ - master
diff --git a/lib/gitlab/ci/trace.rb b/lib/gitlab/ci/trace.rb
index 348e5472cb4..0222ca021b7 100644
--- a/lib/gitlab/ci/trace.rb
+++ b/lib/gitlab/ci/trace.rb
@@ -16,6 +16,7 @@ module Gitlab
ArchiveError = Class.new(StandardError)
AlreadyArchivedError = Class.new(StandardError)
+ LockedError = Class.new(StandardError)
attr_reader :job
@@ -79,11 +80,9 @@ module Gitlab
job.trace_chunks.any? || current_path.present? || old_trace.present?
end
- def read(should_retry: true, &block)
+ def read(&block)
read_stream(&block)
- rescue Errno::ENOENT
- raise unless should_retry
-
+ rescue Errno::ENOENT, ChunkedIO::FailedToGetChunkError
job.reset
read_stream(&block)
end
@@ -130,6 +129,12 @@ module Gitlab
end
end
+ def lock(&block)
+ in_write_lock(&block)
+ rescue FailedToObtainLockError
+ raise LockedError, "build trace `#{job.id}` is locked"
+ end
+
private
def read_stream
diff --git a/lib/gitlab/ci/trace/checksum.rb b/lib/gitlab/ci/trace/checksum.rb
new file mode 100644
index 00000000000..62532ef1cd2
--- /dev/null
+++ b/lib/gitlab/ci/trace/checksum.rb
@@ -0,0 +1,83 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Trace
+ ##
+ # Trace::Checksum class is responsible for calculating a CRC32 checksum
+ # of an entire build trace using partial build trace chunks stored in a
+ # database.
+ #
+ # CRC32 checksum can be easily calculated by combining partial checksums
+ # in a right order.
+ #
+ # Then we compare CRC32 checksum provided by a GitLab Runner and expect
+ # it to be the same as the CRC32 checksum derived from partial chunks.
+ #
+ class Checksum
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :build
+
+ def initialize(build)
+ @build = build
+ end
+
+ def valid?
+ return false unless state_crc32.present?
+
+ state_crc32 == chunks_crc32
+ end
+
+ def state_crc32
+ strong_memoize(:state_crc32) { build.pending_state&.crc32 }
+ end
+
+ def chunks_crc32
+ strong_memoize(:chunks_crc32) do
+ trace_chunks.reduce(0) do |crc32, chunk|
+ Zlib.crc32_combine(crc32, chunk.crc32, chunk_size(chunk))
+ end
+ end
+ end
+
+ def last_chunk
+ strong_memoize(:last_chunk) { trace_chunks.max }
+ end
+
+ ##
+ # Trace chunks will be persisted in a database if an object store is
+ # not configured - in that case we do not want to load entire raw data
+ # of all the chunks into memory.
+ #
+ # We ignore `raw_data` attribute instead, and rely on internal build
+ # trace chunk database adapter to handle
+ # `ActiveModel::MissingAttributeError` exception.
+ #
+ # Alternative solution would be separating chunk data from chunk
+ # metadata on the database level too.
+ #
+ def trace_chunks
+ strong_memoize(:trace_chunks) do
+ build.trace_chunks.persisted
+ .select(::Ci::BuildTraceChunk.metadata_attributes)
+ end
+ end
+
+ def chunks_count
+ trace_chunks.to_a.size
+ end
+
+ private
+
+ def chunk_size(chunk)
+ if chunk == last_chunk
+ chunk.size
+ else
+ ::Ci::BuildTraceChunk::CHUNK_SIZE
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/trace/metrics.rb b/lib/gitlab/ci/trace/metrics.rb
index 82a7d5fb83c..097436d84ea 100644
--- a/lib/gitlab/ci/trace/metrics.rb
+++ b/lib/gitlab/ci/trace/metrics.rb
@@ -6,8 +6,20 @@ module Gitlab
class Metrics
extend Gitlab::Utils::StrongMemoize
- OPERATIONS = [:appended, :streamed, :chunked, :mutated, :overwrite,
- :accepted, :finalized, :discarded, :conflict].freeze
+ OPERATIONS = [
+ :appended, # new trace data has been written to a chunk
+ :streamed, # new trace data has been sent by a runner
+ :chunked, # new trace chunk has been created
+ :mutated, # trace has been mutated when removing secrets
+ :overwrite, # runner requested overwritting a build trace
+ :accepted, # scheduled chunks for migration and responded with 202
+ :finalized, # all live build trace chunks have been persisted
+ :discarded, # failed to persist live chunks before timeout
+ :conflict, # runner has sent unrecognized build state details
+ :locked, # build trace has been locked by a different mechanism
+ :stalled, # failed to migrate chunk due to a worker duplication
+ :invalid # malformed build trace has been detected using CRC32
+ ].freeze
def increment_trace_operation(operation: :unknown)
unless OPERATIONS.include?(operation)
@@ -18,7 +30,11 @@ module Gitlab
end
def increment_trace_bytes(size)
- self.class.trace_bytes.increment(by: size.to_i)
+ self.class.trace_bytes.increment({}, size.to_i)
+ end
+
+ def observe_migration_duration(seconds)
+ self.class.finalize_histogram.observe({}, seconds.to_f)
end
def self.trace_operations
@@ -38,6 +54,17 @@ module Gitlab
Gitlab::Metrics.counter(name, comment)
end
end
+
+ def self.finalize_histogram
+ strong_memoize(:finalize_histogram) do
+ name = :gitlab_ci_trace_finalize_duration_seconds
+ comment = 'Duration of build trace chunks migration to object storage'
+ buckets = [0.1, 0.5, 1.0, 2.0, 3.0, 5.0, 7.0, 10.0, 20.0, 30.0, 60.0, 300.0]
+ labels = {}
+
+ ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/ci/variables/collection/item.rb b/lib/gitlab/ci/variables/collection/item.rb
index a072036daa8..84a9280e507 100644
--- a/lib/gitlab/ci/variables/collection/item.rb
+++ b/lib/gitlab/ci/variables/collection/item.rb
@@ -36,9 +36,9 @@ module Gitlab
def self.fabricate(resource)
case resource
when Hash
- self.new(resource.symbolize_keys)
+ self.new(**resource.symbolize_keys)
when ::Ci::HasVariable
- self.new(resource.to_runner_variable)
+ self.new(**resource.to_runner_variable)
when self
resource.dup
else
diff --git a/lib/gitlab/ci/yaml_processor/result.rb b/lib/gitlab/ci/yaml_processor/result.rb
index 68f61e52df7..52a00e41214 100644
--- a/lib/gitlab/ci/yaml_processor/result.rb
+++ b/lib/gitlab/ci/yaml_processor/result.rb
@@ -95,6 +95,14 @@ module Gitlab
}.compact }.compact
end
+ def merged_yaml
+ @ci_config&.to_hash&.to_yaml
+ end
+
+ def variables_with_data
+ @ci_config.variables_with_data
+ end
+
private
def variables