summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci')
-rw-r--r--lib/gitlab/ci/build/rules/rule/clause/changes.rb12
-rw-r--r--lib/gitlab/ci/charts.rb81
-rw-r--r--lib/gitlab/ci/config/entry/bridge.rb11
-rw-r--r--lib/gitlab/ci/config/entry/job.rb11
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb11
-rw-r--r--lib/gitlab/ci/config/entry/product/variables.rb6
-rw-r--r--lib/gitlab/ci/config/external/mapper.rb10
-rw-r--r--lib/gitlab/ci/features.rb22
-rw-r--r--lib/gitlab/ci/jwt.rb16
-rw-r--r--lib/gitlab/ci/lint.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb10
-rw-r--r--lib/gitlab/ci/pipeline/chain/seed.rb10
-rw-r--r--lib/gitlab/ci/pipeline/chain/seed_block.rb31
-rw-r--r--lib/gitlab/ci/pipeline/seed/environment.rb15
-rw-r--r--lib/gitlab/ci/reports/test_case.rb8
-rw-r--r--lib/gitlab/ci/reports/test_failure_history.rb43
-rw-r--r--lib/gitlab/ci/reports/test_suite_comparer.rb26
-rw-r--r--lib/gitlab/ci/runner_instructions.rb2
-rw-r--r--lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml1
-rw-r--r--lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml5
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml10
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml56
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml167
-rw-r--r--lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml8
-rw-r--r--lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/trace/chunked_io.rb4
34 files changed, 461 insertions, 151 deletions
diff --git a/lib/gitlab/ci/build/rules/rule/clause/changes.rb b/lib/gitlab/ci/build/rules/rule/clause/changes.rb
index 728a66ca87f..cbecce57163 100644
--- a/lib/gitlab/ci/build/rules/rule/clause/changes.rb
+++ b/lib/gitlab/ci/build/rules/rule/clause/changes.rb
@@ -11,12 +11,22 @@ module Gitlab
def satisfied_by?(pipeline, context)
return true if pipeline.modified_paths.nil?
+ expanded_globs = expand_globs(pipeline, context)
pipeline.modified_paths.any? do |path|
- @globs.any? do |glob|
+ expanded_globs.any? do |glob|
File.fnmatch?(glob, path, File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB)
end
end
end
+
+ def expand_globs(pipeline, context)
+ return @globs unless ::Feature.enabled?(:ci_variable_expansion_in_rules_changes, pipeline.project, default_enabled: true)
+ return @globs unless context
+
+ @globs.map do |glob|
+ ExpandVariables.expand_existing(glob, context.variables)
+ end
+ end
end
end
end
diff --git a/lib/gitlab/ci/charts.rb b/lib/gitlab/ci/charts.rb
index 3fbfdffe277..25fb9c0ca97 100644
--- a/lib/gitlab/ci/charts.rb
+++ b/lib/gitlab/ci/charts.rb
@@ -3,38 +3,8 @@
module Gitlab
module Ci
module Charts
- module DailyInterval
- # rubocop: disable CodeReuse/ActiveRecord
- def grouped_count(query)
- query
- .group("DATE(#{::Ci::Pipeline.table_name}.created_at)")
- .count(:created_at)
- .transform_keys { |date| date.strftime(@format) } # rubocop:disable Gitlab/ModuleWithInstanceVariables
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def interval_step
- @interval_step ||= 1.day
- end
- end
-
- module MonthlyInterval
- # rubocop: disable CodeReuse/ActiveRecord
- def grouped_count(query)
- query
- .group("to_char(#{::Ci::Pipeline.table_name}.created_at, '01 Month YYYY')")
- .count(:created_at)
- .transform_keys(&:squish)
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def interval_step
- @interval_step ||= 1.month
- end
- end
-
class Chart
- attr_reader :labels, :total, :success, :project, :pipeline_times
+ attr_reader :from, :to, :labels, :total, :success, :project, :pipeline_times
def initialize(project)
@labels = []
@@ -46,48 +16,59 @@ module Gitlab
collect
end
+ private
+
+ attr_reader :interval
+
# rubocop: disable CodeReuse/ActiveRecord
def collect
query = project.all_pipelines
- .where("? > #{::Ci::Pipeline.table_name}.created_at AND #{::Ci::Pipeline.table_name}.created_at > ?", @to, @from) # rubocop:disable GitlabSecurity/SqlInjection
+ .where(::Ci::Pipeline.arel_table['created_at'].gteq(@from))
+ .where(::Ci::Pipeline.arel_table['created_at'].lteq(@to))
totals_count = grouped_count(query)
success_count = grouped_count(query.success)
current = @from
- while current < @to
- label = current.strftime(@format)
-
- @labels << label
- @total << (totals_count[label] || 0)
- @success << (success_count[label] || 0)
+ while current <= @to
+ @labels << current.strftime(@format)
+ @total << (totals_count[current] || 0)
+ @success << (success_count[current] || 0)
current += interval_step
end
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def grouped_count(query)
+ query
+ .group("date_trunc('#{interval}', #{::Ci::Pipeline.table_name}.created_at)")
+ .count(:created_at)
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def interval_step
+ @interval_step ||= 1.public_send(interval) # rubocop: disable GitlabSecurity/PublicSend
+ end
end
class YearChart < Chart
- include MonthlyInterval
- attr_reader :to, :from
-
def initialize(*)
@to = Date.today.end_of_month.end_of_day
- @from = @to.years_ago(1).beginning_of_month.beginning_of_day
- @format = '%d %B %Y'
+ @from = (@to - 1.year).beginning_of_month.beginning_of_day
+ @interval = :month
+ @format = '%B %Y'
super
end
end
class MonthChart < Chart
- include DailyInterval
- attr_reader :to, :from
-
def initialize(*)
@to = Date.today.end_of_day
- @from = 1.month.ago.beginning_of_day
+ @from = (@to - 1.month).beginning_of_day
+ @interval = :day
@format = '%d %B'
super
@@ -95,12 +76,10 @@ module Gitlab
end
class WeekChart < Chart
- include DailyInterval
- attr_reader :to, :from
-
def initialize(*)
@to = Date.today.end_of_day
- @from = 1.week.ago.beginning_of_day
+ @from = (@to - 1.week).beginning_of_day
+ @interval = :day
@format = '%d %B'
super
diff --git a/lib/gitlab/ci/config/entry/bridge.rb b/lib/gitlab/ci/config/entry/bridge.rb
index 1740032e5c7..70fcc1d586a 100644
--- a/lib/gitlab/ci/config/entry/bridge.rb
+++ b/lib/gitlab/ci/config/entry/bridge.rb
@@ -18,7 +18,6 @@ module Gitlab
validates :config, allowed_keys: ALLOWED_KEYS + PROCESSABLE_ALLOWED_KEYS
with_options allow_nil: true do
- validates :allow_failure, boolean: true
validates :when, inclusion: {
in: ALLOWED_WHEN,
message: "should be one of: #{ALLOWED_WHEN.join(', ')}"
@@ -48,7 +47,7 @@ module Gitlab
inherit: false,
metadata: { allowed_needs: %i[job bridge] }
- attributes :when, :allow_failure
+ attributes :when
def self.matching?(name, config)
!name.to_s.start_with?('.') &&
@@ -60,14 +59,6 @@ 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?),
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index ecc2c5cb729..1ce7060df22 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -24,7 +24,6 @@ module Gitlab
validates :script, presence: true
with_options allow_nil: true do
- validates :allow_failure, boolean: true
validates :when, inclusion: {
in: ALLOWED_WHEN,
message: "should be one of: #{ALLOWED_WHEN.join(', ')}"
@@ -118,7 +117,7 @@ module Gitlab
description: 'Parallel configuration for this job.',
inherit: false
- attributes :script, :tags, :allow_failure, :when, :dependencies,
+ attributes :script, :tags, :when, :dependencies,
:needs, :retry, :parallel, :start_in,
:interruptible, :timeout, :resource_group, :release
@@ -141,18 +140,10 @@ module Gitlab
end
end
- def manual_action?
- self.when == 'manual'
- end
-
def delayed?
self.when == 'delayed'
end
- def ignored?
- allow_failure.nil? ? manual_action? : allow_failure
- end
-
def value
super.merge(
before_script: before_script_value,
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
index f10c509d0cc..c0315e5f901 100644
--- a/lib/gitlab/ci/config/entry/processable.rb
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -32,6 +32,7 @@ module Gitlab
with_options allow_nil: true do
validates :extends, array_of_strings_or_string: true
validates :rules, array_of_hashes: true
+ validates :allow_failure, boolean: true
end
end
@@ -64,7 +65,7 @@ module Gitlab
inherit: false,
default: {}
- attributes :extends, :rules
+ attributes :extends, :rules, :allow_failure
end
def compose!(deps = nil)
@@ -136,6 +137,14 @@ module Gitlab
root_variables.merge(variables_value.to_h)
end
+
+ def manual_action?
+ self.when == 'manual'
+ end
+
+ def ignored?
+ allow_failure.nil? ? manual_action? : allow_failure
+ end
end
end
end
diff --git a/lib/gitlab/ci/config/entry/product/variables.rb b/lib/gitlab/ci/config/entry/product/variables.rb
index 2481989060e..aa34cfb3acc 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: :minimum,
+ minimum: 1,
too_short: 'requires at least %{count} items'
}
end
@@ -28,10 +28,6 @@ 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/external/mapper.rb b/lib/gitlab/ci/config/external/mapper.rb
index 97ae6c4ceba..90692eafc3f 100644
--- a/lib/gitlab/ci/config/external/mapper.rb
+++ b/lib/gitlab/ci/config/external/mapper.rb
@@ -33,6 +33,7 @@ module Gitlab
locations
.compact
.map(&method(:normalize_location))
+ .flat_map(&method(:expand_project_files))
.each(&method(:verify_duplicates!))
.map(&method(:select_first_matching))
end
@@ -52,6 +53,15 @@ module Gitlab
end
end
+ def expand_project_files(location)
+ return location unless ::Feature.enabled?(:ci_include_multiple_files_from_project, context.project, default_enabled: true)
+ return location unless location[:project]
+
+ Array.wrap(location[:file]).map do |file|
+ location.merge(file: file)
+ end
+ end
+
def normalize_location_string(location)
if ::Gitlab::UrlSanitizer.valid?(location)
{ remote: location }
diff --git a/lib/gitlab/ci/features.rb b/lib/gitlab/ci/features.rb
index 1b58e3ec71a..661189eea50 100644
--- a/lib/gitlab/ci/features.rb
+++ b/lib/gitlab/ci/features.rb
@@ -32,16 +32,12 @@ module Gitlab
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,
+ # is a safe switch to disable the feature for a particular project when something went wrong,
# therefore it's not supposed to be enabled by default.
def self.disallow_to_create_merge_request_pipelines_in_target_project?(target_project)
::Feature.enabled?(:ci_disallow_to_create_merge_request_pipelines_in_target_project, target_project)
end
- def self.lint_creates_pipeline_with_dry_run?(project)
- ::Feature.enabled?(:ci_lint_creates_pipeline_with_dry_run, project, default_enabled: true)
- end
-
def self.project_transactionless_destroy?(project)
Feature.enabled?(:project_transactionless_destroy, project, default_enabled: false)
end
@@ -59,13 +55,21 @@ module Gitlab
::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.manual_bridges_enabled?(project)
::Feature.enabled?(:ci_manual_bridges, project, default_enabled: true)
end
+
+ def self.auto_rollback_available?(project)
+ ::Feature.enabled?(:cd_auto_rollback, project) && project&.feature_available?(:auto_rollback)
+ end
+
+ def self.seed_block_run_before_workflow_rules_enabled?(project)
+ ::Feature.enabled?(:ci_seed_block_run_before_workflow_rules, project, default_enabled: true)
+ end
+
+ def self.ci_pipeline_editor_page_enabled?(project)
+ ::Feature.enabled?(:ci_pipeline_editor_page, project, default_enabled: false)
+ end
end
end
end
diff --git a/lib/gitlab/ci/jwt.rb b/lib/gitlab/ci/jwt.rb
index 491facd0a43..a8943eadf4f 100644
--- a/lib/gitlab/ci/jwt.rb
+++ b/lib/gitlab/ci/jwt.rb
@@ -6,6 +6,8 @@ module Gitlab
NOT_BEFORE_TIME = 5
DEFAULT_EXPIRE_TIME = 60 * 5
+ NoSigningKeyError = Class.new(StandardError)
+
def self.for_build(build)
self.new(build, ttl: build.metadata_timeout).encoded
end
@@ -27,7 +29,7 @@ module Gitlab
private
- attr_reader :build, :ttl, :key_data
+ attr_reader :build, :ttl
def reserved_claims
now = Time.now.to_i
@@ -60,7 +62,17 @@ module Gitlab
end
def key
- @key ||= OpenSSL::PKey::RSA.new(Rails.application.secrets.openid_connect_signing_key)
+ @key ||= begin
+ key_data = if Feature.enabled?(:ci_jwt_signing_key, build.project, default_enabled: true)
+ Gitlab::CurrentSettings.ci_jwt_signing_key
+ else
+ Rails.application.secrets.openid_connect_signing_key
+ end
+
+ raise NoSigningKeyError unless key_data
+
+ OpenSSL::PKey::RSA.new(key_data)
+ end
end
def public_key
diff --git a/lib/gitlab/ci/lint.rb b/lib/gitlab/ci/lint.rb
index 44f2ac23ce3..fb795152abe 100644
--- a/lib/gitlab/ci/lint.rb
+++ b/lib/gitlab/ci/lint.rb
@@ -24,7 +24,7 @@ module Gitlab
end
def validate(content, dry_run: false)
- if dry_run && Gitlab::Ci::Features.lint_creates_pipeline_with_dry_run?(@project)
+ if dry_run
simulate_pipeline_creation(content)
else
static_validation(content)
diff --git a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
index 468f3bc4689..a864c843dd8 100644
--- a/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
+++ b/lib/gitlab/ci/pipeline/chain/cancel_pending_pipelines.rb
@@ -25,7 +25,7 @@ module Gitlab
# rubocop: disable CodeReuse/ActiveRecord
def auto_cancelable_pipelines
- project.ci_pipelines
+ pipelines
.where(ref: pipeline.ref)
.where.not(id: pipeline.same_family_pipeline_ids)
.where.not(sha: project.commit(pipeline.ref).try(:id))
@@ -33,6 +33,14 @@ module Gitlab
.with_only_interruptible_builds
end
# rubocop: enable CodeReuse/ActiveRecord
+
+ def pipelines
+ if ::Feature.enabled?(:ci_auto_cancel_all_pipelines, project, default_enabled: false)
+ project.all_pipelines.ci_and_parent_sources
+ else
+ project.ci_pipelines
+ end
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/seed.rb b/lib/gitlab/ci/pipeline/chain/seed.rb
index e10a0bc3718..ba86b08d209 100644
--- a/lib/gitlab/ci/pipeline/chain/seed.rb
+++ b/lib/gitlab/ci/pipeline/chain/seed.rb
@@ -19,10 +19,12 @@ module Gitlab
# Build to prevent erroring out on ambiguous refs.
pipeline.protected = @command.protected_ref?
- ##
- # Populate pipeline with block argument of CreatePipelineService#execute.
- #
- @command.seeds_block&.call(pipeline)
+ unless ::Gitlab::Ci::Features.seed_block_run_before_workflow_rules_enabled?(project)
+ ##
+ # Populate pipeline with block argument of CreatePipelineService#execute.
+ #
+ @command.seeds_block&.call(pipeline)
+ end
##
# Gather all runtime build/stage errors
diff --git a/lib/gitlab/ci/pipeline/chain/seed_block.rb b/lib/gitlab/ci/pipeline/chain/seed_block.rb
new file mode 100644
index 00000000000..f8e62949bea
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/chain/seed_block.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Pipeline
+ module Chain
+ class SeedBlock < Chain::Base
+ include Chain::Helpers
+ include Gitlab::Utils::StrongMemoize
+
+ def perform!
+ return unless ::Gitlab::Ci::Features.seed_block_run_before_workflow_rules_enabled?(project)
+
+ ##
+ # Populate pipeline with block argument of CreatePipelineService#execute.
+ #
+ @command.seeds_block&.call(pipeline)
+
+ raise "Pipeline cannot be persisted by `seeds_block`" if pipeline.persisted?
+ end
+
+ def break?
+ return false unless ::Gitlab::Ci::Features.seed_block_run_before_workflow_rules_enabled?(project)
+
+ pipeline.errors.any?
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/seed/environment.rb b/lib/gitlab/ci/pipeline/seed/environment.rb
index 42e8c365824..b20dc383419 100644
--- a/lib/gitlab/ci/pipeline/seed/environment.rb
+++ b/lib/gitlab/ci/pipeline/seed/environment.rb
@@ -12,12 +12,23 @@ module Gitlab
end
def to_resource
- job.project.environments
- .safe_find_or_create_by(name: expanded_environment_name)
+ environments.safe_find_or_create_by(name: expanded_environment_name) do |environment|
+ environment.auto_stop_in = auto_stop_in
+ end
end
private
+ def environments
+ job.project.environments
+ end
+
+ def auto_stop_in
+ if Feature.enabled?(:environment_auto_stop_start_on_create)
+ job.environment_auto_stop_in
+ end
+ end
+
def expanded_environment_name
job.expanded_environment_name
end
diff --git a/lib/gitlab/ci/reports/test_case.rb b/lib/gitlab/ci/reports/test_case.rb
index 8c70dbb6931..09121191047 100644
--- a/lib/gitlab/ci/reports/test_case.rb
+++ b/lib/gitlab/ci/reports/test_case.rb
@@ -10,7 +10,7 @@ module Gitlab
STATUS_ERROR = 'error'
STATUS_TYPES = [STATUS_ERROR, STATUS_FAILED, STATUS_SUCCESS, STATUS_SKIPPED].freeze
- attr_reader :suite_name, :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, :recent_failures
def initialize(params)
@suite_name = params.fetch(:suite_name)
@@ -24,9 +24,15 @@ module Gitlab
@attachment = params.fetch(:attachment, nil)
@job = params.fetch(:job, nil)
+ @recent_failures = nil
+
@key = hash_key("#{suite_name}_#{classname}_#{name}")
end
+ def set_recent_failures(count, base_branch)
+ @recent_failures = { count: count, base_branch: base_branch }
+ end
+
def has_attachment?
attachment.present?
end
diff --git a/lib/gitlab/ci/reports/test_failure_history.rb b/lib/gitlab/ci/reports/test_failure_history.rb
new file mode 100644
index 00000000000..beceac5423a
--- /dev/null
+++ b/lib/gitlab/ci/reports/test_failure_history.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ class TestFailureHistory
+ include Gitlab::Utils::StrongMemoize
+
+ def initialize(failed_test_cases, project)
+ @failed_test_cases = build_map(failed_test_cases)
+ @project = project
+ end
+
+ def load!
+ return unless Feature.enabled?(:test_failure_history, project)
+
+ recent_failures_count.each do |key_hash, count|
+ failed_test_cases[key_hash].set_recent_failures(count, project.default_branch_or_master)
+ end
+ end
+
+ private
+
+ attr_reader :report, :project, :failed_test_cases
+
+ def recent_failures_count
+ ::Ci::TestCaseFailure.recent_failures_count(
+ project: project,
+ test_case_keys: failed_test_cases.keys
+ )
+ end
+
+ def build_map(test_cases)
+ {}.tap do |hash|
+ test_cases.each do |test_case|
+ hash[test_case.key] = test_case
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/test_suite_comparer.rb b/lib/gitlab/ci/reports/test_suite_comparer.rb
index a58de43e55e..239fc3b15e7 100644
--- a/lib/gitlab/ci/reports/test_suite_comparer.rb
+++ b/lib/gitlab/ci/reports/test_suite_comparer.rb
@@ -6,6 +6,9 @@ module Gitlab
class TestSuiteComparer
include Gitlab::Utils::StrongMemoize
+ DEFAULT_MAX_TESTS = 100
+ DEFAULT_MIN_TESTS = 10
+
attr_reader :name, :base_suite, :head_suite
def initialize(name, base_suite, head_suite)
@@ -81,6 +84,29 @@ module Gitlab
def error_count
new_errors.count + existing_errors.count
end
+
+ # This is used to limit the presented test cases but does not affect
+ # total count of tests in the summary
+ def limited_tests
+ strong_memoize(:limited_tests) do
+ # rubocop: disable CodeReuse/ActiveRecord
+ OpenStruct.new(
+ new_failures: new_failures.take(max_tests),
+ existing_failures: existing_failures.take(max_tests(new_failures)),
+ resolved_failures: resolved_failures.take(max_tests(new_failures, existing_failures)),
+ new_errors: new_errors.take(max_tests),
+ existing_errors: existing_errors.take(max_tests(new_errors)),
+ resolved_errors: resolved_errors.take(max_tests(new_errors, existing_errors))
+ )
+ # rubocop: enable CodeReuse/ActiveRecord
+ end
+ end
+
+ private
+
+ def max_tests(*used)
+ [DEFAULT_MAX_TESTS - used.map(&:count).sum, DEFAULT_MIN_TESTS].max
+ end
end
end
end
diff --git a/lib/gitlab/ci/runner_instructions.rb b/lib/gitlab/ci/runner_instructions.rb
index 2171637687f..dd0bfa768a8 100644
--- a/lib/gitlab/ci/runner_instructions.rb
+++ b/lib/gitlab/ci/runner_instructions.rb
@@ -106,7 +106,7 @@ module Gitlab
end
def get_file(path)
- File.read(path)
+ File.read(Rails.root.join(path).to_s)
end
def registration_token
diff --git a/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml b/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml
index 82b2f5c035e..453803a6f7e 100644
--- a/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/AWS/Deploy-ECS.gitlab-ci.yml
@@ -4,6 +4,7 @@ stages:
- review
- deploy
- production
+ - cleanup
variables:
AUTO_DEVOPS_PLATFORM_TARGET: ECS
diff --git a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
index cba13f374f4..a13f2046291 100644
--- a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
@@ -160,9 +160,10 @@ 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/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/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/Deploy/EC2.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Deploy/EC2.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
- template: Jobs/Browser-Performance-Testing.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
- template: Security/DAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
index 0c3598a61a7..1c25d9d583b 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
@@ -16,4 +16,14 @@ build:
fi
- /build/build.sh
rules:
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'
+ when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+
+build_artifact:
+ stage: build
+ script:
+ - printf "To build your project, please create a build_artifact job into your .gitlab-ci.yml file.\nMore information at https://docs.gitlab.com/ee/ci/cloud_deployment\n"
+ - exit 1
+ rules:
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET == "EC2"'
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 ec33020205b..fe23641802b 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -7,7 +7,7 @@ code_quality:
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
- CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.10-gitlab.1"
+ CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.18"
needs: []
script:
- export SOURCE_CODE=$PWD
@@ -34,6 +34,7 @@ code_quality:
CODECLIMATE_DEBUG \
CODECLIMATE_DEV \
REPORT_STDOUT \
+ REPORT_FORMAT \
ENGINE_MEMORY_LIMIT_BYTES \
) \
--volume "$PWD":/code \
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 33d77e39bc9..c4e194bd658 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -186,7 +186,7 @@ production_manual:
when: never
- if: '$CI_COMMIT_BRANCH != "master"'
when: never
- # $INCREMENTAL_ROLLOUT_ENABLED is for compamtibilty with pre-GitLab 11.4 syntax
+ # $INCREMENTAL_ROLLOUT_ENABLED is for compatibility with pre-GitLab 11.4 syntax
- if: '$INCREMENTAL_ROLLOUT_MODE == "manual" || $INCREMENTAL_ROLLOUT_ENABLED'
when: manual
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 8b921305c11..385959389de 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.latest.gitlab-ci.yml
@@ -183,7 +183,7 @@ production_manual:
when: never
- if: '$CI_COMMIT_BRANCH != "master"'
when: never
- # $INCREMENTAL_ROLLOUT_ENABLED is for compamtibilty with pre-GitLab 11.4 syntax
+ # $INCREMENTAL_ROLLOUT_ENABLED is for compatibility with pre-GitLab 11.4 syntax
- if: '$INCREMENTAL_ROLLOUT_MODE == "manual" || $INCREMENTAL_ROLLOUT_ENABLED'
when: manual
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 317e8bfab0e..0289ba1c473 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
@@ -8,8 +8,11 @@
#
# More about including CI templates: https://docs.gitlab.com/ee/ci/yaml/#includetemplate
-.deploy_to_ecs:
+.ecs_image:
image: 'registry.gitlab.com/gitlab-org/cloud-deploy/aws-ecs:latest'
+
+.deploy_to_ecs:
+ extends: .ecs_image
dependencies: []
script:
- ecs update-task-definition
@@ -17,8 +20,6 @@
.review_ecs_base:
stage: review
extends: .deploy_to_ecs
- environment:
- name: review/$CI_COMMIT_REF_NAME
.production_ecs_base:
stage: production
@@ -26,8 +27,18 @@
environment:
name: production
+.stop_review_ecs_base:
+ extends: .ecs_image
+ stage: cleanup
+ allow_failure: true
+ script:
+ - ecs stop-task
+
review_ecs:
extends: .review_ecs_base
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ on_stop: stop_review_ecs
rules:
- if: '$AUTO_DEVOPS_PLATFORM_TARGET != "ECS"'
when: never
@@ -39,8 +50,46 @@ review_ecs:
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+stop_review_ecs:
+ extends: .stop_review_ecs_base
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ action: stop
+ rules:
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET != "ECS"'
+ 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'
+ when: manual
+
review_fargate:
extends: .review_ecs_base
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ on_stop: stop_review_fargate
+ script:
+ - ecs update-task-definition
+ rules:
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET != "FARGATE"'
+ 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'
+
+stop_review_fargate:
+ extends: .stop_review_ecs_base
+ environment:
+ name: review/$CI_COMMIT_REF_NAME
+ action: stop
rules:
- if: '$AUTO_DEVOPS_PLATFORM_TARGET != "FARGATE"'
when: never
@@ -51,6 +100,7 @@ review_fargate:
- if: '$CI_COMMIT_BRANCH == "master"'
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+ when: manual
production_ecs:
extends: .production_ecs_base
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 a9638f564f3..3f62d92ad13 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.33.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.34.1"
environment:
name: production
variables:
diff --git a/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
index c3a92b67a8b..0ae8fd833c4 100644
--- a/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/API-Fuzzing.gitlab-ci.yml
@@ -1,3 +1,9 @@
+# Read more about this feature here: https://docs.gitlab.com/ee/user/application_security/api_fuzzing/
+
+# Configure the scanning tool through the environment variables.
+# List of the variables: https://docs.gitlab.com/ee/user/application_security/api_fuzzing/#available-variables
+# How to set: https://docs.gitlab.com/ee/ci/yaml/#variables
+
stages:
- build
- test
@@ -7,7 +13,7 @@ stages:
variables:
FUZZAPI_PROFILE: Quick
FUZZAPI_VERSION: latest
- FUZZAPI_CONFIG: "/app/.gitlab-api-fuzzing.yml"
+ FUZZAPI_CONFIG: .gitlab-api-fuzzing.yml
FUZZAPI_TIMEOUT: 30
FUZZAPI_REPORT: gl-api-fuzzing-report.xml
#
@@ -17,9 +23,70 @@ variables:
# available (non 500 response to HTTP(s))
FUZZAPI_SERVICE_START_TIMEOUT: "300"
#
+ FUZZAPI_IMAGE: registry.gitlab.com/gitlab-org/security-products/analyzers/api-fuzzing:${FUZZAPI_VERSION}-engine
+ #
+
+apifuzzer_fuzz_unlicensed:
+ stage: fuzz
+ allow_failure: true
+ rules:
+ - if: '$GITLAB_FEATURES !~ /\bapi_fuzzing\b/ && $API_FUZZING_DISABLED == null'
+ - when: never
+ script:
+ - |
+ echo "Error: Your GitLab project is not licensed for API Fuzzing."
+ - exit 1
apifuzzer_fuzz:
stage: fuzz
+ image:
+ name: $FUZZAPI_IMAGE
+ entrypoint: ["/bin/bash", "-l", "-c"]
+ variables:
+ FUZZAPI_PROJECT: $CI_PROJECT_PATH
+ FUZZAPI_API: http://apifuzzer:80
+ TZ: America/Los_Angeles
+ services:
+ - name: $FUZZAPI_IMAGE
+ alias: apifuzzer
+ entrypoint: ["dotnet", "/peach/Peach.Web.dll"]
+ allow_failure: true
+ rules:
+ - if: $FUZZAPI_D_TARGET_IMAGE
+ when: never
+ - if: $FUZZAPI_D_WORKER_IMAGE
+ when: never
+ - if: $API_FUZZING_DISABLED
+ when: never
+ - if: $API_FUZZING_DISABLED_FOR_DEFAULT_BRANCH &&
+ $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
+ when: never
+ - if: $GITLAB_FEATURES =~ /\bapi_fuzzing\b/
+ script:
+ #
+ # Validate options
+ - |
+ if [ "$FUZZAPI_HAR$FUZZAPI_OPENAPI$FUZZAPI_POSTMAN_COLLECTION" == "" ]; then \
+ echo "Error: One of FUZZAPI_HAR, FUZZAPI_OPENAPI, or FUZZAPI_POSTMAN_COLLECTION must be provided."; \
+ echo "See https://docs.gitlab.com/ee/user/application_security/api_fuzzing/ for information on how to configure API Fuzzing."; \
+ exit 1; \
+ fi
+ #
+ # Run user provided pre-script
+ - sh -c "$FUZZAPI_PRE_SCRIPT"
+ #
+ # Start scanning
+ - worker-entry
+ #
+ # Run user provided post-script
+ - sh -c "$FUZZAPI_POST_SCRIPT"
+ #
+ artifacts:
+ reports:
+ junit: $FUZZAPI_REPORT
+
+apifuzzer_fuzz_dnd:
+ stage: fuzz
image: docker:19.03.12
variables:
DOCKER_DRIVER: overlay2
@@ -28,20 +95,19 @@ apifuzzer_fuzz:
FUZZAPI_API: http://apifuzzer:80
allow_failure: true
rules:
+ - if: $FUZZAPI_D_TARGET_IMAGE == null && $FUZZAPI_D_WORKER_IMAGE == null
+ when: never
- if: $API_FUZZING_DISABLED
when: never
- if: $API_FUZZING_DISABLED_FOR_DEFAULT_BRANCH &&
- $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
- when: never
- - if: $FUZZAPI_HAR == null &&
- $FUZZAPI_OPENAPI == null &&
- $FUZZAPI_D_WORKER_IMAGE == null
+ $CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
- if: $GITLAB_FEATURES =~ /\bapi_fuzzing\b/
services:
- docker:19.03.12-dind
script:
#
+ #
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
#
- docker network create --driver bridge $FUZZAPI_D_NETWORK
@@ -56,30 +122,13 @@ apifuzzer_fuzz:
--network $FUZZAPI_D_NETWORK \
-e Proxy:Port=8000 \
-e TZ=America/Los_Angeles \
- -e FUZZAPI_API=http://127.0.0.1:80 \
- -e FUZZAPI_PROJECT \
- -e FUZZAPI_PROFILE \
- -e FUZZAPI_CONFIG \
- -e FUZZAPI_REPORT \
- -e FUZZAPI_HAR \
- -e FUZZAPI_OPENAPI \
- -e FUZZAPI_TARGET_URL \
- -e FUZZAPI_OVERRIDES_FILE \
- -e FUZZAPI_OVERRIDES_ENV \
- -e FUZZAPI_OVERRIDES_CMD \
- -e FUZZAPI_OVERRIDES_INTERVAL \
- -e FUZZAPI_TIMEOUT \
- -e FUZZAPI_VERBOSE \
- -e FUZZAPI_SERVICE_START_TIMEOUT \
- -e FUZZAPI_HTTP_USERNAME \
- -e FUZZAPI_HTTP_PASSWORD \
-e GITLAB_FEATURES \
- -v $CI_PROJECT_DIR:/app \
-p 80:80 \
-p 8000:8000 \
-p 514:514 \
--restart=no \
- registry.gitlab.com/gitlab-org/security-products/analyzers/api-fuzzing:${FUZZAPI_VERSION}-engine
+ $FUZZAPI_IMAGE \
+ dotnet /peach/Peach.Web.dll
#
# Start target container
- |
@@ -94,19 +143,31 @@ apifuzzer_fuzz:
$FUZZAPI_D_TARGET_IMAGE \
; fi
#
- # Start worker container
+ # Start worker container if provided
- |
if [ "$FUZZAPI_D_WORKER_IMAGE" != "" ]; then \
- echo "Starting worker image $FUZZAPI_D_WORKER_IMAGE" \
+ echo "Starting worker image $FUZZAPI_D_WORKER_IMAGE"; \
docker run \
--name worker \
--network $FUZZAPI_D_NETWORK \
-e FUZZAPI_API=http://apifuzzer:80 \
-e FUZZAPI_PROJECT \
-e FUZZAPI_PROFILE \
- -e FUZZAPI_AUTOMATION_CMD \
-e FUZZAPI_CONFIG \
-e FUZZAPI_REPORT \
+ -e FUZZAPI_HAR \
+ -e FUZZAPI_OPENAPI \
+ -e FUZZAPI_POSTMAN_COLLECTION \
+ -e FUZZAPI_TARGET_URL \
+ -e FUZZAPI_OVERRIDES_FILE \
+ -e FUZZAPI_OVERRIDES_ENV \
+ -e FUZZAPI_OVERRIDES_CMD \
+ -e FUZZAPI_OVERRIDES_INTERVAL \
+ -e FUZZAPI_TIMEOUT \
+ -e FUZZAPI_VERBOSE \
+ -e FUZZAPI_SERVICE_START_TIMEOUT \
+ -e FUZZAPI_HTTP_USERNAME \
+ -e FUZZAPI_HTTP_PASSWORD \
-e CI_COMMIT_BRANCH=${CI_COMMIT_BRANCH} \
$FUZZAPI_D_WORKER_ENV \
$FUZZAPI_D_WORKER_PORTS \
@@ -115,13 +176,49 @@ apifuzzer_fuzz:
$FUZZAPI_D_WORKER_IMAGE \
; fi
#
- # Wait for testing to complete if api fuzzer is scanning
- - if [ "$FUZZAPI_HAR$FUZZAPI_OPENAPI" != "" ]; then echo "Waiting for API Fuzzer to exit"; docker wait apifuzzer; fi
+ # Start API Fuzzing provided worker if no other worker present
+ - |
+ if [ "$FUZZAPI_D_WORKER_IMAGE" == "" ]; then \
+ if [ "$FUZZAPI_HAR$FUZZAPI_OPENAPI$FUZZAPI_POSTMAN_COLLECTION" == "" ]; then \
+ echo "Error: One of FUZZAPI_HAR, FUZZAPI_OPENAPI, or FUZZAPI_POSTMAN_COLLECTION must be provided."; \
+ echo "See https://docs.gitlab.com/ee/user/application_security/api_fuzzing/ for information on how to configure API Fuzzing."; \
+ exit 1; \
+ fi; \
+ docker run \
+ --name worker \
+ --network $FUZZAPI_D_NETWORK \
+ -e TZ=America/Los_Angeles \
+ -e FUZZAPI_API=http://apifuzzer:80 \
+ -e FUZZAPI_PROJECT \
+ -e FUZZAPI_PROFILE \
+ -e FUZZAPI_CONFIG \
+ -e FUZZAPI_REPORT \
+ -e FUZZAPI_HAR \
+ -e FUZZAPI_OPENAPI \
+ -e FUZZAPI_POSTMAN_COLLECTION \
+ -e FUZZAPI_TARGET_URL \
+ -e FUZZAPI_OVERRIDES_FILE \
+ -e FUZZAPI_OVERRIDES_ENV \
+ -e FUZZAPI_OVERRIDES_CMD \
+ -e FUZZAPI_OVERRIDES_INTERVAL \
+ -e FUZZAPI_TIMEOUT \
+ -e FUZZAPI_VERBOSE \
+ -e FUZZAPI_SERVICE_START_TIMEOUT \
+ -e FUZZAPI_HTTP_USERNAME \
+ -e FUZZAPI_HTTP_PASSWORD \
+ -v $CI_PROJECT_DIR:/app \
+ -p 81:80 \
+ -p 8001:8000 \
+ -p 515:514 \
+ --restart=no \
+ $FUZZAPI_IMAGE \
+ worker-entry \
+ ; fi
#
- # Propagate exit code from api fuzzer (if any)
- - if [[ $(docker inspect apifuzzer --format='{{.State.ExitCode}}') != "0" ]]; then echo "API Fuzzing exited with an error. Logs are available as job artifacts."; docker logs apifuzzer; exit 1; fi
+ # Propagate exit code from api fuzzing scanner (if any)
+ - if [[ $(docker inspect apifuzzer --format='{{.State.ExitCode}}') != "0" ]]; then echo "API Fuzzing scanner exited with an error. Logs are available as job artifacts."; exit 1; fi
#
- # Run user provided pre-script
+ # Run user provided post-script
- sh -c "$FUZZAPI_POST_SCRIPT"
#
after_script:
@@ -129,13 +226,13 @@ apifuzzer_fuzz:
# Shutdown all containers
- echo "Stopping all containers"
- if [ "$FUZZAPI_D_TARGET_IMAGE" != "" ]; then docker stop target; fi
- - if [ "$FUZZAPI_D_WORKER_IMAGE" != "" ]; then docker stop worker; fi
+ - docker stop worker
- docker stop apifuzzer
#
# Save docker logs
- docker logs apifuzzer &> gl-api_fuzzing-logs.log
- if [ "$FUZZAPI_D_TARGET_IMAGE" != "" ]; then docker logs target &> gl-api_fuzzing-target-logs.log; fi
- - if [ "$FUZZAPI_D_WORKER_IMAGE" != "" ]; then docker logs worker &> gl-api_fuzzing-worker-logs.log; fi
+ - docker logs worker &> gl-api_fuzzing-worker-logs.log
#
artifacts:
when: always
diff --git a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
index 21bcdd8d9b5..3cbde9d30c8 100644
--- a/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
@@ -4,8 +4,7 @@ variables:
# Setting this variable will affect all Security templates
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
-
- CS_MAJOR_VERSION: 2
+ CS_MAJOR_VERSION: 3
container_scanning:
stage: test
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 e268b48d133..a1b6dc2cc1b 100644
--- a/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
@@ -11,6 +11,14 @@ variables:
COVFUZZ_URL_PREFIX: "https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-cov-fuzz/-/raw"
+coverage_fuzzing_unlicensed:
+ stage: test
+ allow_failure: true
+ rules:
+ - if: $GITLAB_FEATURES !~ /\bcoverage_fuzzing\b/ && $COVFUZZ_DISABLED == null
+ script:
+ - echo "ERROR Your GitLab project is missing licensing for Coverage Fuzzing" && exit 1
+
.fuzz_base:
stage: fuzz
allow_failure: true
diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
index 4418ff18d73..a51cb61da6d 100644
--- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
@@ -134,6 +134,7 @@ mobsf-android-sast:
name: "$SAST_ANALYZER_IMAGE"
variables:
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
+ MOBSF_API_KEY: key
rules:
- if: $SAST_DISABLED
when: never
@@ -152,6 +153,7 @@ mobsf-ios-sast:
name: "$SAST_ANALYZER_IMAGE"
variables:
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
+ MOBSF_API_KEY: key
rules:
- if: $SAST_DISABLED
when: never
diff --git a/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
index 2d2e0859373..232c320562b 100644
--- a/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
@@ -131,6 +131,8 @@ secrets:
variables:
- $SECURE_BINARIES_DOWNLOAD_IMAGES == "true" &&
$SECURE_BINARIES_ANALYZERS =~ /\bsecrets\b/
+ variables:
+ SECURE_BINARIES_ANALYZER_VERSION: "3"
sobelow:
extends: .download_images
@@ -162,6 +164,8 @@ klar:
variables:
- $SECURE_BINARIES_DOWNLOAD_IMAGES == "true" &&
$SECURE_BINARIES_ANALYZERS =~ /\bklar\b/
+ variables:
+ SECURE_BINARIES_ANALYZER_VERSION: "3"
clair-vulnerabilities-db:
extends: .download_images
diff --git a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
index b08ccf18b58..5963d7138c5 100644
--- a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml
@@ -1,11 +1,12 @@
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
+ - template: Terraform/Base.latest.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
stages:
- init
- validate
- build
- deploy
+ - cleanup
init:
extends: .init
diff --git a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
index 000a1a7f580..e455bfac9de 100644
--- a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml
@@ -12,9 +12,6 @@
image:
name: registry.gitlab.com/gitlab-org/terraform-images/stable:latest
-before_script:
- - cd ${TF_ROOT}
-
variables:
TF_ROOT: ${CI_PROJECT_DIR}
@@ -26,16 +23,19 @@ cache:
.init: &init
stage: init
script:
+ - cd ${TF_ROOT}
- gitlab-terraform init
.validate: &validate
stage: validate
script:
+ - cd ${TF_ROOT}
- gitlab-terraform validate
.build: &build
stage: build
script:
+ - cd ${TF_ROOT}
- gitlab-terraform plan
- gitlab-terraform plan-json
artifacts:
@@ -47,7 +47,14 @@ cache:
.deploy: &deploy
stage: deploy
script:
+ - cd ${TF_ROOT}
- gitlab-terraform apply
when: manual
only:
- master
+
+.destroy: &destroy
+ stage: cleanup
+ script:
+ - gitlab-terraform destroy
+ when: manual
diff --git a/lib/gitlab/ci/trace/chunked_io.rb b/lib/gitlab/ci/trace/chunked_io.rb
index e99889f4a25..6f3e4ccf48d 100644
--- a/lib/gitlab/ci/trace/chunked_io.rb
+++ b/lib/gitlab/ci/trace/chunked_io.rb
@@ -75,7 +75,7 @@ module Gitlab
until length <= 0 || eof?
data = chunk_slice_from_offset
- raise FailedToGetChunkError if data.empty?
+ raise FailedToGetChunkError if data.to_s.empty?
chunk_bytes = [CHUNK_SIZE - chunk_offset, length].min
chunk_data_slice = data.byteslice(0, chunk_bytes)
@@ -100,7 +100,7 @@ module Gitlab
until eof?
data = chunk_slice_from_offset
- raise FailedToGetChunkError if data.empty?
+ raise FailedToGetChunkError if data.to_s.empty?
new_line = data.index("\n")