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-07-20 15:26:25 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-07-20 15:26:25 +0300
commita09983ae35713f5a2bbb100981116d31ce99826e (patch)
tree2ee2af7bd104d57086db360a7e6d8c9d5d43667a /lib/gitlab/ci
parent18c5ab32b738c0b6ecb4d0df3994000482f34bd8 (diff)
Add latest changes from gitlab-org/gitlab@13-2-stable-ee
Diffstat (limited to 'lib/gitlab/ci')
-rw-r--r--lib/gitlab/ci/build/releaser.rb17
-rw-r--r--lib/gitlab/ci/config.rb6
-rw-r--r--lib/gitlab/ci/config/entry/environment.rb2
-rw-r--r--lib/gitlab/ci/config/entry/job.rb4
-rw-r--r--lib/gitlab/ci/config/entry/processable.rb4
-rw-r--r--lib/gitlab/ci/config/entry/release.rb24
-rw-r--r--lib/gitlab/ci/config/entry/reports.rb9
-rw-r--r--lib/gitlab/ci/features.rb54
-rw-r--r--lib/gitlab/ci/parsers/terraform/tfplan.rb34
-rw-r--r--lib/gitlab/ci/pipeline/chain/build.rb6
-rw-r--r--lib/gitlab/ci/pipeline/chain/command.rb8
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content.rb1
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content/parameter.rb30
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content/source.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/process.rb12
-rw-r--r--lib/gitlab/ci/pipeline/chain/create.rb4
-rw-r--r--lib/gitlab/ci/pipeline/chain/helpers.rb9
-rw-r--r--lib/gitlab/ci/pipeline/chain/metrics.rb35
-rw-r--r--lib/gitlab/ci/pipeline/chain/validate/abilities.rb2
-rw-r--r--lib/gitlab/ci/pipeline/chain/validate/repository.rb2
-rw-r--r--lib/gitlab/ci/pipeline/metrics.rb42
-rw-r--r--lib/gitlab/ci/pipeline/preloader.rb18
-rw-r--r--lib/gitlab/ci/reports/test_report_summary.rb49
-rw-r--r--lib/gitlab/ci/reports/test_suite.rb14
-rw-r--r--lib/gitlab/ci/reports/test_suite_summary.rb49
-rw-r--r--lib/gitlab/ci/status/composite.rb4
-rw-r--r--lib/gitlab/ci/status/factory.rb2
-rw-r--r--lib/gitlab/ci/status/stage/play_manual.rb2
-rw-r--r--lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Android.gitlab-ci.yml63
-rw-r--r--lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Composer.gitlab-ci.yml19
-rw-r--r--lib/gitlab/ci/templates/Dart.gitlab-ci.yml22
-rw-r--r--lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml20
-rw-r--r--lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml7
-rw-r--r--lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml42
-rw-r--r--lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml29
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml2
-rw-r--r--lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml34
-rw-r--r--lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml7
-rw-r--r--lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml16
-rw-r--r--lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml48
-rw-r--r--lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml28
-rw-r--r--lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml11
-rw-r--r--lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml12
-rw-r--r--lib/gitlab/ci/templates/Verify/Load-Performance-Testing.gitlab-ci.yml23
-rw-r--r--lib/gitlab/ci/templates/index.md3
-rw-r--r--lib/gitlab/ci/templates/npm.gitlab-ci.yml59
-rw-r--r--lib/gitlab/ci/yaml_processor.rb65
53 files changed, 780 insertions, 204 deletions
diff --git a/lib/gitlab/ci/build/releaser.rb b/lib/gitlab/ci/build/releaser.rb
index ba6c7857e96..facb5f619bd 100644
--- a/lib/gitlab/ci/build/releaser.rb
+++ b/lib/gitlab/ci/build/releaser.rb
@@ -5,6 +5,8 @@ module Gitlab
module Build
class Releaser
BASE_COMMAND = 'release-cli create'
+ SINGLE_FLAGS = %i[name description tag_name ref released_at].freeze
+ ARRAY_FLAGS = %i[milestones].freeze
attr_reader :config
@@ -14,9 +16,20 @@ module Gitlab
def script
command = BASE_COMMAND.dup
- config.each { |k, v| command.concat(" --#{k.to_s.dasherize} \"#{v}\"") }
+ single_flags.each { |k, v| command.concat(" --#{k.to_s.dasherize} \"#{v}\"") }
+ array_commands.each { |k, v| v.each { |elem| command.concat(" --#{k.to_s.singularize.dasherize} \"#{elem}\"") } }
- command
+ [command]
+ end
+
+ private
+
+ def single_flags
+ config.slice(*SINGLE_FLAGS)
+ end
+
+ def array_commands
+ config.slice(*ARRAY_FLAGS)
end
end
end
diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb
index 10e0f4b8e4d..d81a3fef1f5 100644
--- a/lib/gitlab/ci/config.rb
+++ b/lib/gitlab/ci/config.rb
@@ -39,6 +39,10 @@ module Gitlab
@root.errors
end
+ def warnings
+ @root.warnings
+ end
+
def to_hash
@config
end
@@ -93,7 +97,7 @@ module Gitlab
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error, @context.sentry_payload)
end
- # Overriden in EE
+ # Overridden in EE
def rescue_errors
RESCUE_ERRORS
end
diff --git a/lib/gitlab/ci/config/entry/environment.rb b/lib/gitlab/ci/config/entry/environment.rb
index fc62cca58ff..64e6d48133f 100644
--- a/lib/gitlab/ci/config/entry/environment.rb
+++ b/lib/gitlab/ci/config/entry/environment.rb
@@ -44,7 +44,7 @@ module Gitlab
validates :action,
type: String,
- inclusion: { in: %w[start stop], message: 'should be start or stop' },
+ inclusion: { in: %w[start stop prepare], message: 'should be start, stop or prepare' },
allow_nil: true
validates :on_stop, type: String, allow_nil: true
diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index 66050a7bbe0..a615cab1a80 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -15,7 +15,7 @@ module Gitlab
allow_failure type when start_in artifacts cache
dependencies before_script needs after_script
environment coverage retry parallel interruptible timeout
- resource_group release].freeze
+ resource_group release secrets].freeze
REQUIRED_BY_NEEDS = %i[stage].freeze
@@ -191,3 +191,5 @@ module Gitlab
end
end
end
+
+::Gitlab::Ci::Config::Entry::Job.prepend_if_ee('::EE::Gitlab::Ci::Config::Entry::Job')
diff --git a/lib/gitlab/ci/config/entry/processable.rb b/lib/gitlab/ci/config/entry/processable.rb
index 81211acbec7..b4539475d88 100644
--- a/lib/gitlab/ci/config/entry/processable.rb
+++ b/lib/gitlab/ci/config/entry/processable.rb
@@ -82,6 +82,10 @@ module Gitlab
@entries.delete(:except) unless except_defined? # rubocop:disable Gitlab/ModuleWithInstanceVariables
end
+ if has_rules? && !has_workflow_rules && Gitlab::Ci::Features.raise_job_rules_without_workflow_rules_warning?
+ add_warning('uses `rules` without defining `workflow:rules`')
+ end
+
# inherit root variables
@root_variables_value = deps&.variables_value # rubocop:disable Gitlab/ModuleWithInstanceVariables
diff --git a/lib/gitlab/ci/config/entry/release.rb b/lib/gitlab/ci/config/entry/release.rb
index b4e4c149730..7e504c24ade 100644
--- a/lib/gitlab/ci/config/entry/release.rb
+++ b/lib/gitlab/ci/config/entry/release.rb
@@ -12,8 +12,9 @@ module Gitlab
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
- ALLOWED_KEYS = %i[tag_name name description assets].freeze
- attributes %i[tag_name name assets].freeze
+ ALLOWED_KEYS = %i[tag_name name description ref released_at milestones assets].freeze
+ attributes %i[tag_name name ref milestones assets].freeze
+ attr_reader :released_at
# Attributable description conflicts with
# ::Gitlab::Config::Entry::Node.description
@@ -29,8 +30,25 @@ module Gitlab
validations do
validates :config, allowed_keys: ALLOWED_KEYS
- validates :tag_name, presence: true
+ validates :tag_name, type: String, presence: true
validates :description, type: String, presence: true
+ validates :milestones, array_of_strings_or_string: true, allow_blank: true
+ validate do
+ next unless config[:released_at]
+
+ begin
+ @released_at = DateTime.iso8601(config[:released_at])
+ rescue ArgumentError
+ errors.add(:released_at, "must be a valid datetime")
+ end
+ end
+ validate do
+ next unless config[:ref]
+ next if Commit.reference_valid?(config[:ref])
+ next if Gitlab::GitRefValidator.validate(config[:ref])
+
+ errors.add(:ref, "must be a valid ref")
+ end
end
def value
diff --git a/lib/gitlab/ci/config/entry/reports.rb b/lib/gitlab/ci/config/entry/reports.rb
index 74736b24d73..0ae65f43723 100644
--- a/lib/gitlab/ci/config/entry/reports.rb
+++ b/lib/gitlab/ci/config/entry/reports.rb
@@ -13,9 +13,9 @@ module Gitlab
ALLOWED_KEYS =
%i[junit codequality sast secret_detection dependency_scanning container_scanning
- dast performance license_management license_scanning metrics lsif
+ dast performance browser_performance load_performance license_management license_scanning metrics lsif
dotenv cobertura terraform accessibility cluster_applications
- requirements].freeze
+ requirements coverage_fuzzing].freeze
attributes ALLOWED_KEYS
@@ -25,13 +25,16 @@ module Gitlab
with_options allow_nil: true do
validates :junit, array_of_strings_or_string: true
- validates :codequality, 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
validates :secret_detection, array_of_strings_or_string: true
validates :dependency_scanning, array_of_strings_or_string: true
validates :container_scanning, array_of_strings_or_string: true
validates :dast, array_of_strings_or_string: true
validates :performance, array_of_strings_or_string: true
+ validates :browser_performance, array_of_strings_or_string: true
+ validates :load_performance, array_of_strings_or_string: true
validates :license_management, array_of_strings_or_string: true
validates :license_scanning, array_of_strings_or_string: true
validates :metrics, array_of_strings_or_string: true
diff --git a/lib/gitlab/ci/features.rb b/lib/gitlab/ci/features.rb
index a2eb31369c7..6130baeb9d5 100644
--- a/lib/gitlab/ci/features.rb
+++ b/lib/gitlab/ci/features.rb
@@ -10,20 +10,12 @@ module Gitlab
::Feature.enabled?(:ci_artifacts_exclude, default_enabled: true)
end
- def self.ensure_scheduling_type_enabled?
- ::Feature.enabled?(:ci_ensure_scheduling_type, default_enabled: true)
- end
-
def self.job_heartbeats_runner?(project)
::Feature.enabled?(:ci_job_heartbeats_runner, project, default_enabled: true)
end
- def self.instance_level_variables_limit_enabled?
- ::Feature.enabled?(:ci_instance_level_variables_limit, default_enabled: true)
- end
-
def self.pipeline_fixed_notifications?
- ::Feature.enabled?(:ci_pipeline_fixed_notifications)
+ ::Feature.enabled?(:ci_pipeline_fixed_notifications, default_enabled: true)
end
def self.instance_variables_ui_enabled?
@@ -38,9 +30,51 @@ module Gitlab
::Feature.enabled?(:ci_atomic_processing, project, default_enabled: true)
end
+ def self.pipeline_latest?
+ ::Feature.enabled?(:ci_pipeline_latest, default_enabled: true)
+ end
+
+ def self.pipeline_status_omit_commit_sha_in_cache_key?(project)
+ Feature.enabled?(:ci_pipeline_status_omit_commit_sha_in_cache_key, project)
+ end
+
def self.release_generation_enabled?
- ::Feature.enabled?(:ci_release_generation)
+ ::Feature.enabled?(:ci_release_generation, default_enabled: true)
+ end
+
+ # Remove in https://gitlab.com/gitlab-org/gitlab/-/issues/224199
+ def self.store_pipeline_messages?(project)
+ ::Feature.enabled?(:ci_store_pipeline_messages, project, default_enabled: true)
+ end
+
+ # Remove in https://gitlab.com/gitlab-org/gitlab/-/issues/227052
+ def self.variables_api_filter_environment_scope?
+ ::Feature.enabled?(:ci_variables_api_filter_environment_scope, default_enabled: false)
+ end
+
+ # This FF is only used for development purpose to test that warnings can be
+ # raised and propagated to the UI.
+ def self.raise_job_rules_without_workflow_rules_warning?
+ ::Feature.enabled?(:ci_raise_job_rules_without_workflow_rules_warning)
+ end
+
+ def self.keep_latest_artifacts_for_ref_enabled?(project)
+ ::Feature.enabled?(:keep_latest_artifacts_for_ref, project, default_enabled: false)
+ end
+
+ def self.destroy_only_unlocked_expired_artifacts_enabled?
+ ::Feature.enabled?(:destroy_only_unlocked_expired_artifacts, default_enabled: false)
+ end
+
+ def self.bulk_insert_on_create?(project)
+ ::Feature.enabled?(:ci_bulk_insert_on_create, project, default_enabled: true)
+ end
+
+ def self.allow_to_create_merge_request_pipelines_in_target_project?(target_project)
+ ::Feature.enabled?(:ci_allow_to_create_merge_request_pipelines_in_target_project, target_project)
end
end
end
end
+
+::Gitlab::Ci::Features.prepend_if_ee('::EE::Gitlab::Ci::Features')
diff --git a/lib/gitlab/ci/parsers/terraform/tfplan.rb b/lib/gitlab/ci/parsers/terraform/tfplan.rb
index 19f724b79af..abfbe18e23f 100644
--- a/lib/gitlab/ci/parsers/terraform/tfplan.rb
+++ b/lib/gitlab/ci/parsers/terraform/tfplan.rb
@@ -8,15 +8,21 @@ module Gitlab
TfplanParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
def parse!(json_data, terraform_reports, artifact:)
+ job_details = job_details(artifact.job)
+ job_id = job_details['job_id']
plan_data = Gitlab::Json.parse(json_data)
- raise TfplanParserError, 'Tfplan missing required key' unless has_required_keys?(plan_data)
-
- terraform_reports.add_plan(artifact.job.id.to_s, tfplan(plan_data, artifact.job))
+ if has_required_keys?(plan_data)
+ terraform_reports.add_plan(job_id, valid_tfplan(plan_data, job_details))
+ else
+ terraform_reports.add_plan(job_id, invalid_tfplan(:missing_json_keys, job_details))
+ end
rescue JSON::ParserError
- raise TfplanParserError, 'JSON parsing failed'
+ terraform_reports.add_plan(job_id, invalid_tfplan(:invalid_json_format, job_details))
rescue
- raise TfplanParserError, 'Tfplan parsing failed'
+ details = job_details || {}
+ plan_name = job_id || 'failed_tf_plan'
+ terraform_reports.add_plan(plan_name, invalid_tfplan(:unknown_error, details))
end
private
@@ -25,14 +31,24 @@ module Gitlab
(%w[create update delete] - plan_data.keys).empty?
end
- def tfplan(plan_data, artifact_job)
+ def job_details(job)
{
+ 'job_id' => job.id.to_s,
+ 'job_name' => job.options.dig(:artifacts, :name).to_s,
+ 'job_path' => Gitlab::Routing.url_helpers.project_job_path(job.project, job)
+ }
+ end
+
+ def invalid_tfplan(error_type, job_details)
+ job_details.merge('tf_report_error' => error_type)
+ end
+
+ def valid_tfplan(plan_data, job_details)
+ job_details.merge(
'create' => plan_data['create'].to_i,
'delete' => plan_data['delete'].to_i,
- 'job_name' => artifact_job.options.dig(:artifacts, :name).to_s,
- 'job_path' => Gitlab::Routing.url_helpers.project_job_path(artifact_job.project, artifact_job),
'update' => plan_data['update'].to_i
- }
+ )
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/build.rb b/lib/gitlab/ci/pipeline/chain/build.rb
index 9662209f88e..4190c40eb66 100644
--- a/lib/gitlab/ci/pipeline/chain/build.rb
+++ b/lib/gitlab/ci/pipeline/chain/build.rb
@@ -20,7 +20,11 @@ module Gitlab
pipeline_schedule: @command.schedule,
merge_request: @command.merge_request,
external_pull_request: @command.external_pull_request,
- variables_attributes: Array(@command.variables_attributes)
+ variables_attributes: Array(@command.variables_attributes),
+ # This should be removed and set on the database column default
+ # level when the keep_latest_artifacts_for_ref feature flag is
+ # removed.
+ locked: ::Gitlab::Ci::Features.keep_latest_artifacts_for_ref_enabled?(@command.project) ? :artifacts_locked : :unlocked
)
end
diff --git a/lib/gitlab/ci/pipeline/chain/command.rb b/lib/gitlab/ci/pipeline/chain/command.rb
index 8118e7b2487..74b28b181bc 100644
--- a/lib/gitlab/ci/pipeline/chain/command.rb
+++ b/lib/gitlab/ci/pipeline/chain/command.rb
@@ -10,7 +10,7 @@ module Gitlab
:trigger_request, :schedule, :merge_request, :external_pull_request,
:ignore_skip_ci, :save_incompleted,
:seeds_block, :variables_attributes, :push_options,
- :chat_data, :allow_mirror_update, :bridge,
+ :chat_data, :allow_mirror_update, :bridge, :content,
# These attributes are set by Chains during processing:
:config_content, :config_processor, :stage_seeds
) do
@@ -78,7 +78,7 @@ module Gitlab
end
def metrics
- @metrics ||= Chain::Metrics.new
+ @metrics ||= ::Gitlab::Ci::Pipeline::Metrics.new
end
def observe_creation_duration(duration)
@@ -90,6 +90,10 @@ module Gitlab
metrics.pipeline_size_histogram
.observe({ source: pipeline.source.to_s }, pipeline.total_size)
end
+
+ def dangling_build?
+ %i[ondemand_dast_scan webide].include?(source)
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/config/content.rb b/lib/gitlab/ci/pipeline/chain/config/content.rb
index 2008010b523..5314fd471c3 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content.rb
@@ -9,6 +9,7 @@ module Gitlab
include Chain::Helpers
SOURCES = [
+ Gitlab::Ci::Pipeline::Chain::Config::Content::Parameter,
Gitlab::Ci::Pipeline::Chain::Config::Content::Bridge,
Gitlab::Ci::Pipeline::Chain::Config::Content::Repository,
Gitlab::Ci::Pipeline::Chain::Config::Content::ExternalProject,
diff --git a/lib/gitlab/ci/pipeline/chain/config/content/parameter.rb b/lib/gitlab/ci/pipeline/chain/config/content/parameter.rb
new file mode 100644
index 00000000000..3dd216b33d1
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/chain/config/content/parameter.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Pipeline
+ module Chain
+ module Config
+ class Content
+ class Parameter < Source
+ UnsupportedSourceError = Class.new(StandardError)
+
+ def content
+ strong_memoize(:content) do
+ next unless command.content.present?
+ raise UnsupportedSourceError, "#{command.source} not a dangling build" unless command.dangling_build?
+
+ command.content
+ end
+ end
+
+ def source
+ :parameter_source
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/chain/config/content/source.rb b/lib/gitlab/ci/pipeline/chain/config/content/source.rb
index 3389187473b..8bc172f93d3 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content/source.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content/source.rb
@@ -11,6 +11,8 @@ module Gitlab
DEFAULT_YAML_FILE = '.gitlab-ci.yml'
+ attr_reader :command
+
def initialize(pipeline, command)
@pipeline = pipeline
@command = command
diff --git a/lib/gitlab/ci/pipeline/chain/config/process.rb b/lib/gitlab/ci/pipeline/chain/config/process.rb
index 1e47be21b93..2cfcb295407 100644
--- a/lib/gitlab/ci/pipeline/chain/config/process.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/process.rb
@@ -19,7 +19,11 @@ module Gitlab
parent_pipeline: parent_pipeline
}
)
+
+ add_warnings_to_pipeline(@command.config_processor.warnings)
rescue Gitlab::Ci::YamlProcessor::ValidationError => ex
+ add_warnings_to_pipeline(ex.warnings)
+
error(ex.message, config_error: true)
rescue => ex
Gitlab::ErrorTracking.track_exception(ex,
@@ -34,6 +38,14 @@ module Gitlab
def break?
@pipeline.errors.any? || @pipeline.persisted?
end
+
+ private
+
+ def add_warnings_to_pipeline(warnings)
+ return unless warnings.present?
+
+ warnings.each { |message| warning(message) }
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/create.rb b/lib/gitlab/ci/pipeline/chain/create.rb
index aa627bdb009..34649fe16f3 100644
--- a/lib/gitlab/ci/pipeline/chain/create.rb
+++ b/lib/gitlab/ci/pipeline/chain/create.rb
@@ -8,7 +8,9 @@ module Gitlab
include Chain::Helpers
def perform!
- pipeline.save!
+ BulkInsertableAssociations.with_bulk_insert(enabled: ::Gitlab::Ci::Features.bulk_insert_on_create?(project)) do
+ pipeline.save!
+ end
rescue ActiveRecord::RecordInvalid => e
error("Failed to persist the pipeline: #{e}")
end
diff --git a/lib/gitlab/ci/pipeline/chain/helpers.rb b/lib/gitlab/ci/pipeline/chain/helpers.rb
index 982ecc0ff51..aba7dab508d 100644
--- a/lib/gitlab/ci/pipeline/chain/helpers.rb
+++ b/lib/gitlab/ci/pipeline/chain/helpers.rb
@@ -11,9 +11,18 @@ module Gitlab
pipeline.yaml_errors = message
end
+ pipeline.add_error_message(message)
pipeline.drop!(drop_reason) if drop_reason
+
+ # TODO: consider not to rely on AR errors directly as they can be
+ # polluted with other unrelated errors (e.g. state machine)
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/220823
pipeline.errors.add(:base, message)
end
+
+ def warning(message)
+ pipeline.add_warning_message(message)
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/metrics.rb b/lib/gitlab/ci/pipeline/chain/metrics.rb
deleted file mode 100644
index 980ab2de9b0..00000000000
--- a/lib/gitlab/ci/pipeline/chain/metrics.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Ci
- module Pipeline
- module Chain
- class Metrics
- include Gitlab::Utils::StrongMemoize
-
- def pipeline_creation_duration_histogram
- strong_memoize(:pipeline_creation_duration_histogram) do
- name = :gitlab_ci_pipeline_creation_duration_seconds
- comment = 'Pipeline creation duration'
- labels = {}
- buckets = [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 20.0, 50.0, 240.0]
-
- ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
- end
- end
-
- def pipeline_size_histogram
- strong_memoize(:pipeline_size_histogram) do
- name = :gitlab_ci_pipeline_size_builds
- comment = 'Pipeline size'
- labels = { source: nil }
- buckets = [0, 1, 5, 10, 20, 50, 100, 200, 500, 1000]
-
- ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
- end
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb
index a30b6c6ef0e..769d0dffd0b 100644
--- a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb
+++ b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb
@@ -19,7 +19,7 @@ module Gitlab
end
unless allowed_to_write_ref?
- return error("Insufficient permissions for protected ref '#{command.ref}'")
+ error("Insufficient permissions for protected ref '#{command.ref}'")
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/validate/repository.rb b/lib/gitlab/ci/pipeline/chain/validate/repository.rb
index 8f5445850d7..7977ce90443 100644
--- a/lib/gitlab/ci/pipeline/chain/validate/repository.rb
+++ b/lib/gitlab/ci/pipeline/chain/validate/repository.rb
@@ -18,7 +18,7 @@ module Gitlab
end
if @command.ambiguous_ref?
- return error('Ref is ambiguous')
+ error('Ref is ambiguous')
end
end
diff --git a/lib/gitlab/ci/pipeline/metrics.rb b/lib/gitlab/ci/pipeline/metrics.rb
new file mode 100644
index 00000000000..649da745eea
--- /dev/null
+++ b/lib/gitlab/ci/pipeline/metrics.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Pipeline
+ class Metrics
+ include Gitlab::Utils::StrongMemoize
+
+ def pipeline_creation_duration_histogram
+ strong_memoize(:pipeline_creation_duration_histogram) do
+ name = :gitlab_ci_pipeline_creation_duration_seconds
+ comment = 'Pipeline creation duration'
+ labels = {}
+ buckets = [0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0, 20.0, 50.0, 240.0]
+
+ ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
+ end
+ end
+
+ def pipeline_size_histogram
+ strong_memoize(:pipeline_size_histogram) do
+ name = :gitlab_ci_pipeline_size_builds
+ comment = 'Pipeline size'
+ labels = { source: nil }
+ buckets = [0, 1, 5, 10, 20, 50, 100, 200, 500, 1000]
+
+ ::Gitlab::Metrics.histogram(name, comment, labels, buckets)
+ end
+ end
+
+ def pipeline_processing_events_counter
+ strong_memoize(:pipeline_processing_events_counter) do
+ name = :gitlab_ci_pipeline_processing_events_total
+ comment = 'Total amount of pipeline processing events'
+
+ Gitlab::Metrics.counter(name, comment)
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/pipeline/preloader.rb b/lib/gitlab/ci/pipeline/preloader.rb
index db0a1ea4dab..7befc126ca9 100644
--- a/lib/gitlab/ci/pipeline/preloader.rb
+++ b/lib/gitlab/ci/pipeline/preloader.rb
@@ -17,6 +17,7 @@ module Gitlab
pipelines.each do |pipeline|
self.new(pipeline).tap do |preloader|
preloader.preload_commit_authors
+ preloader.preload_ref_commits
preloader.preload_pipeline_warnings
preloader.preload_stages_warnings
end
@@ -27,12 +28,19 @@ module Gitlab
@pipeline = pipeline
end
+ # This also preloads the author of every commit. We're using "lazy_author"
+ # here since "author" immediately loads the data on the first call.
def preload_commit_authors
- # This also preloads the author of every commit. We're using "lazy_author"
- # here since "author" immediately loads the data on the first call.
@pipeline.commit.try(:lazy_author)
end
+ # This preloads latest commits for given refs and therefore makes it
+ # much less expensive to check if a pipeline is a latest one for
+ # given branch.
+ def preload_ref_commits
+ @pipeline.lazy_ref_commit
+ end
+
def preload_pipeline_warnings
# This preloads the number of warnings for every pipeline, ensuring
# that Ci::Pipeline#has_warnings? doesn't execute any additional
@@ -40,10 +48,10 @@ module Gitlab
@pipeline.number_of_warnings
end
+ # This preloads the number of warnings for every stage, ensuring
+ # that Ci::Stage#has_warnings? doesn't execute any additional
+ # queries.
def preload_stages_warnings
- # This preloads the number of warnings for every stage, ensuring
- # that Ci::Stage#has_warnings? doesn't execute any additional
- # queries.
@pipeline.stages.each { |stage| stage.number_of_warnings }
end
end
diff --git a/lib/gitlab/ci/reports/test_report_summary.rb b/lib/gitlab/ci/reports/test_report_summary.rb
new file mode 100644
index 00000000000..85b83b790e7
--- /dev/null
+++ b/lib/gitlab/ci/reports/test_report_summary.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ class TestReportSummary
+ attr_reader :all_results
+
+ def initialize(all_results)
+ @all_results = all_results
+ end
+
+ def total
+ TestSuiteSummary.new(all_results)
+ end
+
+ def total_time
+ total.total_time
+ end
+
+ def total_count
+ total.total_count
+ end
+
+ def success_count
+ total.success_count
+ end
+
+ def failed_count
+ total.failed_count
+ end
+
+ def skipped_count
+ total.skipped_count
+ end
+
+ def error_count
+ total.error_count
+ end
+
+ def test_suites
+ all_results
+ .group_by(&:tests_name)
+ .transform_values { |results| TestSuiteSummary.new(results) }
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/test_suite.rb b/lib/gitlab/ci/reports/test_suite.rb
index 8bbf2e0f6cf..28b81e7a471 100644
--- a/lib/gitlab/ci/reports/test_suite.rb
+++ b/lib/gitlab/ci/reports/test_suite.rb
@@ -4,9 +4,9 @@ module Gitlab
module Ci
module Reports
class TestSuite
- attr_reader :name
- attr_reader :test_cases
- attr_reader :total_time
+ attr_accessor :name
+ attr_accessor :test_cases
+ attr_accessor :total_time
attr_reader :suite_error
def initialize(name = nil)
@@ -70,6 +70,14 @@ module Gitlab
@suite_error = msg
end
+ def +(other)
+ self.class.new.tap do |test_suite|
+ test_suite.name = self.name
+ test_suite.test_cases = self.test_cases.deep_merge(other.test_cases)
+ test_suite.total_time = self.total_time + other.total_time
+ end
+ end
+
private
def existing_key?(test_case)
diff --git a/lib/gitlab/ci/reports/test_suite_summary.rb b/lib/gitlab/ci/reports/test_suite_summary.rb
new file mode 100644
index 00000000000..f9b0bedb712
--- /dev/null
+++ b/lib/gitlab/ci/reports/test_suite_summary.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ class TestSuiteSummary
+ attr_reader :results
+
+ def initialize(results)
+ @results = results
+ end
+
+ def name
+ @name ||= results.first.tests_name
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def build_ids
+ results.pluck(:build_id)
+ end
+
+ def total_time
+ @total_time ||= results.sum(&:tests_duration)
+ end
+
+ def success_count
+ @success_count ||= results.sum(&:tests_success)
+ end
+
+ def failed_count
+ @failed_count ||= results.sum(&:tests_failed)
+ end
+
+ def skipped_count
+ @skipped_count ||= results.sum(&:tests_skipped)
+ end
+
+ def error_count
+ @error_count ||= results.sum(&:tests_errored)
+ end
+
+ def total_count
+ @total_count ||= [success_count, failed_count, skipped_count, error_count].sum
+ end
+ # rubocop: disable CodeReuse/ActiveRecord
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/status/composite.rb b/lib/gitlab/ci/status/composite.rb
index 074651f1040..04a9fc29802 100644
--- a/lib/gitlab/ci/status/composite.rb
+++ b/lib/gitlab/ci/status/composite.rb
@@ -112,13 +112,13 @@ module Gitlab
def success_with_warnings?(status)
@allow_failure_key &&
status[@allow_failure_key] &&
- HasStatus::PASSED_WITH_WARNINGS_STATUSES.include?(status[@status_key])
+ ::Ci::HasStatus::PASSED_WITH_WARNINGS_STATUSES.include?(status[@status_key])
end
def ignored_status?(status)
@allow_failure_key &&
status[@allow_failure_key] &&
- HasStatus::EXCLUDE_IGNORED_STATUSES.include?(status[@status_key])
+ ::Ci::HasStatus::EXCLUDE_IGNORED_STATUSES.include?(status[@status_key])
end
end
end
diff --git a/lib/gitlab/ci/status/factory.rb b/lib/gitlab/ci/status/factory.rb
index 73c73a3b3fc..4a384531c57 100644
--- a/lib/gitlab/ci/status/factory.rb
+++ b/lib/gitlab/ci/status/factory.rb
@@ -7,7 +7,7 @@ module Gitlab
def initialize(subject, user)
@subject = subject
@user = user
- @status = subject.status || HasStatus::DEFAULT_STATUS
+ @status = subject.status || ::Ci::HasStatus::DEFAULT_STATUS
end
def fabricate!
diff --git a/lib/gitlab/ci/status/stage/play_manual.rb b/lib/gitlab/ci/status/stage/play_manual.rb
index ac3fc0912fa..58859a8f191 100644
--- a/lib/gitlab/ci/status/stage/play_manual.rb
+++ b/lib/gitlab/ci/status/stage/play_manual.rb
@@ -18,7 +18,7 @@ module Gitlab
def action_path
pipeline = subject.pipeline
- project_stage_play_manual_path(pipeline.project, pipeline, subject.name)
+ project_pipeline_stage_play_manual_path(pipeline.project, pipeline, subject.name)
end
def action_method
diff --git a/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml b/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml
index be584814271..5ebbbf15682 100644
--- a/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Android-Fastlane.gitlab-ci.yml
@@ -20,7 +20,7 @@ stages:
- docker:dind
script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- - docker pull $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG || true
+ - docker pull --quiet $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG || true
- docker build --cache-from $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG -t $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
diff --git a/lib/gitlab/ci/templates/Android.gitlab-ci.yml b/lib/gitlab/ci/templates/Android.gitlab-ci.yml
index b7194110002..d20dabc0b00 100644
--- a/lib/gitlab/ci/templates/Android.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Android.gitlab-ci.yml
@@ -4,32 +4,65 @@
image: openjdk:8-jdk
variables:
- ANDROID_COMPILE_SDK: "28"
- ANDROID_BUILD_TOOLS: "28.0.2"
- ANDROID_SDK_TOOLS: "4333796"
+ # ANDROID_COMPILE_SDK is the version of Android you're compiling with.
+ # It should match compileSdkVersion.
+ ANDROID_COMPILE_SDK: "29"
+
+ # ANDROID_BUILD_TOOLS is the version of the Android build tools you are using.
+ # It should match buildToolsVersion.
+ ANDROID_BUILD_TOOLS: "29.0.3"
+
+ # It's what version of the command line tools we're going to download from the official site.
+ # Official Site-> https://developer.android.com/studio/index.html
+ # There, look down below at the cli tools only, sdk tools package is of format:
+ # commandlinetools-os_type-ANDROID_SDK_TOOLS_latest.zip
+ # when the script was last modified for latest compileSdkVersion, it was which is written down below
+ ANDROID_SDK_TOOLS: "6514223"
+
+# Packages installation before running script
before_script:
- apt-get --quiet update --yes
- apt-get --quiet install --yes wget tar unzip lib32stdc++6 lib32z1
- - wget --quiet --output-document=android-sdk.zip https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS}.zip
- - unzip -d android-sdk-linux android-sdk.zip
- - echo y | android-sdk-linux/tools/bin/sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}" >/dev/null
- - echo y | android-sdk-linux/tools/bin/sdkmanager "platform-tools" >/dev/null
- - echo y | android-sdk-linux/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS}" >/dev/null
- - export ANDROID_HOME=$PWD/android-sdk-linux
- - export PATH=$PATH:$PWD/android-sdk-linux/platform-tools/
+
+ # Setup path as android_home for moving/exporting the downloaded sdk into it
+ - export ANDROID_HOME="${PWD}/android-home"
+ # Create a new directory at specified location
+ - install -d $ANDROID_HOME
+ # Here we are installing androidSDK tools from official source,
+ # (the key thing here is the url from where you are downloading these sdk tool for command line, so please do note this url pattern there and here as well)
+ # after that unzipping those tools and
+ # then running a series of SDK manager commands to install necessary android SDK packages that'll allow the app to build
+ - wget --output-document=$ANDROID_HOME/cmdline-tools.zip https://dl.google.com/android/repository/commandlinetools-linux-${ANDROID_SDK_TOOLS}_latest.zip
+ # move to the archive at ANDROID_HOME
+ - pushd $ANDROID_HOME
+ - unzip -d cmdline-tools cmdline-tools.zip
+ - popd
+ - export PATH=$PATH:${ANDROID_HOME}/cmdline-tools/tools/bin/
+
+ # Nothing fancy here, just checking sdkManager version
+ - sdkmanager --version
+
+ # use yes to accept all licenses
+ - yes | sdkmanager --sdk_root=${ANDROID_HOME} --licenses || true
+ - sdkmanager --sdk_root=${ANDROID_HOME} "platforms;android-${ANDROID_COMPILE_SDK}"
+ - sdkmanager --sdk_root=${ANDROID_HOME} "platform-tools"
+ - sdkmanager --sdk_root=${ANDROID_HOME} "build-tools;${ANDROID_BUILD_TOOLS}"
+
+ # Not necessary, but just for surity
- chmod +x ./gradlew
- # temporarily disable checking for EPIPE error and use yes to accept all licenses
- - set +o pipefail
- - yes | android-sdk-linux/tools/bin/sdkmanager --licenses
- - set -o pipefail
+# Basic android and gradle stuff
+# Check linting
lintDebug:
+ interruptible: true
stage: build
script:
- ./gradlew -Pci --console=plain :app:lintDebug -PbuildDir=lint
+# Make Project
assembleDebug:
+ interruptible: true
stage: build
script:
- ./gradlew assembleDebug
@@ -37,7 +70,9 @@ assembleDebug:
paths:
- app/build/outputs/
+# Run all tests, if any fails, interrupt the pipeline(fail it)
debugTests:
+ interruptible: true
stage: test
script:
- ./gradlew -Pci --console=plain :app:testDebug
diff --git a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
index e37cd14d1d1..c10d87a537b 100644
--- a/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Auto-DevOps.gitlab-ci.yml
@@ -12,6 +12,7 @@
# * code_quality: CODE_QUALITY_DISABLED
# * license_management: LICENSE_MANAGEMENT_DISABLED
# * performance: PERFORMANCE_DISABLED
+# * load_performance: LOAD_PERFORMANCE_DISABLED
# * sast: SAST_DISABLED
# * secret_detection: SECRET_DETECTION_DISABLED
# * dependency_scanning: DEPENDENCY_SCANNING_DISABLED
@@ -74,7 +75,7 @@ stages:
workflow:
rules:
- - if: '$BUILDPACK_URL || $AUTO_DEVOPS_EXPLICITLY_ENABLED == "1"'
+ - if: '$BUILDPACK_URL || $AUTO_DEVOPS_EXPLICITLY_ENABLED == "1" || $DOCKERFILE_PATH'
- exists:
- Dockerfile
diff --git a/lib/gitlab/ci/templates/Composer.gitlab-ci.yml b/lib/gitlab/ci/templates/Composer.gitlab-ci.yml
new file mode 100644
index 00000000000..5d9c68d3031
--- /dev/null
+++ b/lib/gitlab/ci/templates/Composer.gitlab-ci.yml
@@ -0,0 +1,19 @@
+# Publishes a tag/branch to Composer Packages of the current project
+publish:
+ image: curlimages/curl:latest
+ stage: build
+ variables:
+ URL: "$CI_SERVER_PROTOCOL://$CI_SERVER_HOST:$CI_SERVER_PORT/api/v4/projects/$CI_PROJECT_ID/packages/composer?job_token=$CI_JOB_TOKEN"
+ script:
+ - version=$([[ -z "$CI_COMMIT_TAG" ]] && echo "branch=$CI_COMMIT_REF_NAME" || echo "tag=$CI_COMMIT_TAG")
+ - insecure=$([ "$CI_SERVER_PROTOCOL" = "http" ] && echo "--insecure" || echo "")
+ - response=$(curl -s -w "\n%{http_code}" $insecure --data $version $URL)
+ - code=$(echo "$response" | tail -n 1)
+ - body=$(echo "$response" | head -n 1)
+ # Output state information
+ - if [ $code -eq 201 ]; then
+ echo "Package created - Code $code - $body";
+ else
+ echo "Could not create package - Code $code - $body";
+ exit 1;
+ fi
diff --git a/lib/gitlab/ci/templates/Dart.gitlab-ci.yml b/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
new file mode 100644
index 00000000000..cc383f89b0c
--- /dev/null
+++ b/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
@@ -0,0 +1,22 @@
+# https://hub.docker.com/r/google/dart
+image: google/dart:2.8.4
+
+variables:
+ # Use to learn more:
+ # pub run test --help
+ PUB_VARS: "--platform vm --timeout 30s --concurrency=6 --test-randomize-ordering-seed=random --reporter=expanded"
+
+# Cache downloaded dependencies and plugins between builds.
+# To keep cache across branches add 'key: "$CI_JOB_NAME"'
+cache:
+ paths:
+ - .pub-cache/global_packages
+
+before_script:
+ - export PATH="$PATH":"~/.pub-cache/bin"
+ - pub get --no-precompile
+
+test:
+ stage: test
+ script:
+ - pub run test $PUB_VARS
diff --git a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
index 9a34f8cb113..8553a940bd7 100644
--- a/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
@@ -1,11 +1,16 @@
+# Read more about the feature here: https://docs.gitlab.com/ee/user/project/merge_requests/browser_performance_testing.html
+
performance:
stage: performance
- image: docker:19.03.11
+ image: docker:19.03.12
allow_failure: true
variables:
DOCKER_TLS_CERTDIR: ""
+ SITESPEED_IMAGE: sitespeedio/sitespeed.io
+ SITESPEED_VERSION: 13.3.0
+ SITESPEED_OPTIONS: ''
services:
- - docker:19.03.11-dind
+ - docker:19.03.12-dind
script:
- |
if ! docker info &>/dev/null; then
@@ -15,21 +20,22 @@ performance:
fi
- export CI_ENVIRONMENT_URL=$(cat environment_url.txt)
- mkdir gitlab-exporter
- - wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.0.0/index.js
+ - wget -O gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/1.0.1/index.js
- mkdir sitespeed-results
- |
if [ -f .gitlab-urls.txt ]
then
sed -i -e 's@^@'"$CI_ENVIRONMENT_URL"'@' .gitlab-urls.txt
- docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:11.2.0 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt
+ docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --outputFolder sitespeed-results .gitlab-urls.txt $SITESPEED_OPTIONS
else
- docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:11.2.0 --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL"
+ docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --outputFolder sitespeed-results "$CI_ENVIRONMENT_URL" $SITESPEED_OPTIONS
fi
- - mv sitespeed-results/data/performance.json performance.json
+ - mv sitespeed-results/data/performance.json browser-performance.json
artifacts:
paths:
- - performance.json
- sitespeed-results/
+ reports:
+ browser_performance: browser-performance.json
rules:
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
index b5550461482..dbe870953ae 100644
--- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
@@ -1,10 +1,10 @@
build:
stage: build
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.2.3"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-build-image:v0.3.1"
variables:
DOCKER_TLS_CERTDIR: ""
services:
- - docker:19.03.11-dind
+ - docker:19.03.12-dind
script:
- |
if [[ -z "$CI_COMMIT_TAG" ]]; then
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 bde6f185d3a..6b76d7e0c9b 100644
--- a/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
@@ -1,13 +1,14 @@
code_quality:
stage: test
- image: docker:19.03.11
+ image: docker:19.03.12
allow_failure: true
services:
- - docker:19.03.11-dind
+ - docker:19.03.12-dind
variables:
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
- CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.9"
+ CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.10"
+ needs: []
script:
- |
if ! docker info &>/dev/null; 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 bab4fae67f0..d7d927ac8ee 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:v0.17.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.17.2"
dast_environment_deploy:
extends: .dast-auto-deploy
@@ -51,3 +51,4 @@ stop_dast_environment:
- if: $CI_COMMIT_BRANCH &&
$CI_KUBERNETES_ACTIVE &&
$GITLAB_FEATURES =~ /\bdast\b/
+ when: always
diff --git a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
index 97b5f3fd7f5..66c60e85892 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
@@ -1,5 +1,6 @@
.auto-deploy:
- image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.17.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:v0.17.2"
+ dependencies: []
include:
- template: Jobs/Deploy/ECS.gitlab-ci.yml
@@ -20,7 +21,8 @@ review:
url: http://$CI_PROJECT_ID-$CI_ENVIRONMENT_SLUG.$KUBE_INGRESS_BASE_DOMAIN
on_stop: stop_review
artifacts:
- paths: [environment_url.txt]
+ paths: [environment_url.txt, tiller.log]
+ when: always
rules:
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
when: never
@@ -41,7 +43,6 @@ stop_review:
environment:
name: review/$CI_COMMIT_REF_NAME
action: stop
- dependencies: []
allow_failure: true
rules:
- if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
@@ -122,7 +123,8 @@ canary:
name: production
url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
artifacts:
- paths: [environment_url.txt]
+ paths: [environment_url.txt, tiller.log]
+ when: always
production:
<<: *production_template
@@ -172,7 +174,8 @@ production_manual:
name: production
url: http://$CI_PROJECT_PATH_SLUG.$KUBE_INGRESS_BASE_DOMAIN
artifacts:
- paths: [environment_url.txt]
+ paths: [environment_url.txt, tiller.log]
+ when: always
.manual_rollout_template: &manual_rollout_template
<<: *rollout_template
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 bb3d5526f3a..da474f8ac88 100644
--- a/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Jobs/Deploy/ECS.gitlab-ci.yml
@@ -13,11 +13,20 @@
script:
- ecs update-task-definition
-review_ecs:
- extends: .deploy_to_ecs
+.review_ecs_base:
stage: review
+ extends: .deploy_to_ecs
environment:
name: review/$CI_COMMIT_REF_NAME
+
+.production_ecs_base:
+ stage: production
+ extends: .deploy_to_ecs
+ environment:
+ name: production
+
+review_ecs:
+ extends: .review_ecs_base
rules:
- if: '$AUTO_DEVOPS_PLATFORM_TARGET != "ECS"'
when: never
@@ -29,11 +38,21 @@ review_ecs:
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+review_fargate:
+ extends: .review_ecs_base
+ 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'
+
production_ecs:
- extends: .deploy_to_ecs
- stage: production
- environment:
- name: production
+ extends: .production_ecs_base
rules:
- if: '$AUTO_DEVOPS_PLATFORM_TARGET != "ECS"'
when: never
@@ -42,3 +61,14 @@ production_ecs:
- if: '$CI_COMMIT_BRANCH != "master"'
when: never
- if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
+
+production_fargate:
+ extends: .production_ecs_base
+ rules:
+ - if: '$AUTO_DEVOPS_PLATFORM_TARGET != "FARGATE"'
+ 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/Load-Performance-Testing.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml
new file mode 100644
index 00000000000..b437ddbd734
--- /dev/null
+++ b/lib/gitlab/ci/templates/Jobs/Load-Performance-Testing.gitlab-ci.yml
@@ -0,0 +1,29 @@
+load_performance:
+ stage: performance
+ image: docker:19.03.11
+ allow_failure: true
+ variables:
+ DOCKER_TLS_CERTDIR: ""
+ K6_IMAGE: loadimpact/k6
+ K6_VERSION: 0.26.2
+ K6_TEST_FILE: github.com/loadimpact/k6/samples/http_get.js
+ K6_OPTIONS: ''
+ services:
+ - docker:19.03.11-dind
+ script:
+ - |
+ if ! docker info &>/dev/null; then
+ if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then
+ export DOCKER_HOST='tcp://localhost:2375'
+ fi
+ fi
+ - docker run --rm -v "$(pwd)":/k6 -w /k6 $K6_IMAGE:$K6_VERSION run $K6_TEST_FILE --summary-export=load-performance.json $K6_OPTIONS
+ artifacts:
+ reports:
+ load_performance: load-performance.json
+ rules:
+ - if: '$CI_KUBERNETES_ACTIVE == null || $CI_KUBERNETES_ACTIVE == ""'
+ when: never
+ - if: '$LOAD_PERFORMANCE_DISABLED'
+ when: never
+ - if: '$CI_COMMIT_TAG || $CI_COMMIT_BRANCH'
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 316647b5921..3d0bacda853 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.20.0"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.24.2"
environment:
name: production
variables:
diff --git a/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
new file mode 100644
index 00000000000..2fab8b95a3d
--- /dev/null
+++ b/lib/gitlab/ci/templates/Security/Coverage-Fuzzing.gitlab-ci.yml
@@ -0,0 +1,34 @@
+# Read more about this feature https://docs.gitlab.com/ee/user/application_security/coverage_fuzzing
+
+variables:
+ # Which branch we want to run full fledged long running fuzzing jobs.
+ # All others will run fuzzing regression
+ COVERAGE_FUZZING_BRANCH: "$CI_DEFAULT_BRANCH"
+ # This is using semantic version and will always download latest v1 gitlab-cov-fuzz release
+ COVERAGE_FUZZING_VERSION: v1
+ # This is for users who have an offline environment and will have to replicate gitlab-cov-fuzz release binaries
+ # to their own servers
+ COVERAGE_FUZZING_URL_PREFIX: "https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-cov-fuzz/-/raw"
+
+.fuzz_base:
+ stage: fuzz
+ allow_failure: true
+ before_script:
+ - if [ -x "$(command -v apt-get)" ] ; then apt-get update && apt-get install -y wget; fi
+ - wget -O gitlab-cov-fuzz "${COVERAGE_FUZZING_URL_PREFIX}"/"${COVERAGE_FUZZING_VERSION}"/binaries/gitlab-cov-fuzz_Linux_x86_64
+ - chmod a+x gitlab-cov-fuzz
+ - export REGRESSION=true
+ - if [[ $CI_COMMIT_BRANCH = $COVERAGE_FUZZING_BRANCH ]]; then REGRESSION=false; fi;
+ artifacts:
+ paths:
+ - corpus
+ - crashes
+ - gl-coverage-fuzzing-report.json
+ reports:
+ coverage_fuzzing: gl-coverage-fuzzing-report.json
+ when: always
+ rules:
+ - if: $COVERAGE_FUZZING_DISABLED
+ when: never
+ - if: $GITLAB_FEATURES =~ /\bcoverage_fuzzing\b/
+ - if: $CI_RUNNER_EXECUTABLE_ARCH == "linux"
diff --git a/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
index 07399216597..7abecfb7e49 100644
--- a/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
@@ -41,4 +41,11 @@ dast:
$DAST_API_SPECIFICATION == null
when: never
- if: $CI_COMMIT_BRANCH &&
+ $CI_KUBERNETES_ACTIVE &&
$GITLAB_FEATURES =~ /\bdast\b/
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdast\b/ &&
+ $DAST_WEBSITE
+ - if: $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bdast\b/ &&
+ $DAST_API_SPECIFICATION
diff --git a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
index fa8ccb7cf93..37f6cd216ca 100644
--- a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
@@ -9,9 +9,6 @@ variables:
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
- # Deprecated, use SECURE_ANALYZERS_PREFIX instead
- DS_ANALYZER_IMAGE_PREFIX: "$SECURE_ANALYZERS_PREFIX"
-
DS_DEFAULT_ANALYZERS: "bundler-audit, retire.js, gemnasium, gemnasium-maven, gemnasium-python"
DS_EXCLUDED_PATHS: "spec, test, tests, tmp"
DS_MAJOR_VERSION: 2
@@ -45,7 +42,7 @@ dependency_scanning:
docker run \
$(propagate_env_vars \
DS_ANALYZER_IMAGES \
- DS_ANALYZER_IMAGE_PREFIX \
+ SECURE_ANALYZERS_PREFIX \
DS_ANALYZER_IMAGE_TAG \
DS_DEFAULT_ANALYZERS \
DS_EXCLUDED_PATHS \
@@ -55,6 +52,7 @@ dependency_scanning:
DS_PYTHON_VERSION \
DS_PIP_VERSION \
DS_PIP_DEPENDENCY_PATH \
+ DS_JAVA_VERSION \
GEMNASIUM_DB_LOCAL_PATH \
GEMNASIUM_DB_REMOTE_URL \
GEMNASIUM_DB_REF_NAME \
@@ -98,7 +96,7 @@ dependency_scanning:
gemnasium-dependency_scanning:
extends: .ds-analyzer
image:
- name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium:$DS_MAJOR_VERSION"
+ name: "$SECURE_ANALYZERS_PREFIX/gemnasium:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@@ -117,7 +115,7 @@ gemnasium-dependency_scanning:
gemnasium-maven-dependency_scanning:
extends: .ds-analyzer
image:
- name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION"
+ name: "$SECURE_ANALYZERS_PREFIX/gemnasium-maven:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@@ -133,7 +131,7 @@ gemnasium-maven-dependency_scanning:
gemnasium-python-dependency_scanning:
extends: .ds-analyzer
image:
- name: "$DS_ANALYZER_IMAGE_PREFIX/gemnasium-python:$DS_MAJOR_VERSION"
+ name: "$SECURE_ANALYZERS_PREFIX/gemnasium-python:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@@ -156,7 +154,7 @@ gemnasium-python-dependency_scanning:
bundler-audit-dependency_scanning:
extends: .ds-analyzer
image:
- name: "$DS_ANALYZER_IMAGE_PREFIX/bundler-audit:$DS_MAJOR_VERSION"
+ name: "$SECURE_ANALYZERS_PREFIX/bundler-audit:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
@@ -169,7 +167,7 @@ bundler-audit-dependency_scanning:
retire-js-dependency_scanning:
extends: .ds-analyzer
image:
- name: "$DS_ANALYZER_IMAGE_PREFIX/retire.js:$DS_MAJOR_VERSION"
+ name: "$SECURE_ANALYZERS_PREFIX/retire.js:$DS_MAJOR_VERSION"
rules:
- if: $DEPENDENCY_SCANNING_DISABLED || $DS_DISABLE_DIND == 'false'
when: never
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 b0c75b0aab0..cc34d23decc 100644
--- a/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/License-Scanning.gitlab-ci.yml
@@ -18,15 +18,15 @@ license_scanning:
name: "$SECURE_ANALYZERS_PREFIX/license-finder:$LICENSE_MANAGEMENT_VERSION"
entrypoint: [""]
variables:
- LM_REPORT_FILE: gl-license-scanning-report.json
LM_REPORT_VERSION: '2.1'
SETUP_CMD: $LICENSE_MANAGEMENT_SETUP_CMD
allow_failure: true
+ needs: []
script:
- /run.sh analyze .
artifacts:
reports:
- license_scanning: $LM_REPORT_FILE
+ license_scanning: gl-license-scanning-report.json
dependencies: []
rules:
- if: $LICENSE_MANAGEMENT_DISABLED
diff --git a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
index ec7b34d17b5..f0e2f48dd5c 100644
--- a/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
@@ -9,10 +9,7 @@ variables:
# (SAST, Dependency Scanning, ...)
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
- # Deprecated, use SECURE_ANALYZERS_PREFIX instead
- SAST_ANALYZER_IMAGE_PREFIX: "$SECURE_ANALYZERS_PREFIX"
-
- SAST_DEFAULT_ANALYZERS: "bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, tslint, secrets, sobelow, pmd-apex, kubesec"
+ SAST_DEFAULT_ANALYZERS: "bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, secrets, sobelow, pmd-apex, kubesec"
SAST_EXCLUDED_PATHS: "spec, test, tests, tmp"
SAST_ANALYZER_IMAGE_TAG: 2
SAST_DISABLE_DIND: "true"
@@ -63,7 +60,7 @@ sast:
bandit-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/bandit:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/bandit:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -76,7 +73,7 @@ bandit-sast:
brakeman-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/brakeman:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/brakeman:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -88,21 +85,23 @@ brakeman-sast:
eslint-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/eslint:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
- if: $CI_COMMIT_BRANCH &&
- $GITLAB_FEATURES =~ /\bsast\b/ &&
$SAST_DEFAULT_ANALYZERS =~ /eslint/
exists:
- '**/*.html'
- '**/*.js'
+ - '**/*.jsx'
+ - '**/*.ts'
+ - '**/*.tsx'
flawfinder-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/flawfinder:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/flawfinder:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -116,7 +115,7 @@ flawfinder-sast:
kubesec-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/kubesec:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/kubesec:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -128,7 +127,7 @@ kubesec-sast:
gosec-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/gosec:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/gosec:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -141,7 +140,7 @@ gosec-sast:
nodejs-scan-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/nodejs-scan:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -154,7 +153,7 @@ nodejs-scan-sast:
phpcs-security-audit-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/phpcs-security-audit:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/phpcs-security-audit:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -167,7 +166,7 @@ phpcs-security-audit-sast:
pmd-apex-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/pmd-apex:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/pmd-apex:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -180,7 +179,7 @@ pmd-apex-sast:
secrets-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/secrets:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/secrets:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -191,7 +190,7 @@ secrets-sast:
security-code-scan-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/security-code-scan:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/security-code-scan:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -205,7 +204,7 @@ security-code-scan-sast:
sobelow-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/sobelow:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/sobelow:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -218,7 +217,7 @@ sobelow-sast:
spotbugs-sast:
extends: .sast-analyzer
image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/spotbugs:$SAST_ANALYZER_IMAGE_TAG"
+ name: "$SECURE_ANALYZERS_PREFIX/spotbugs:$SAST_ANALYZER_IMAGE_TAG"
rules:
- if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
when: never
@@ -229,16 +228,3 @@ spotbugs-sast:
- '**/*.groovy'
- '**/*.java'
- '**/*.scala'
-
-tslint-sast:
- extends: .sast-analyzer
- image:
- name: "$SAST_ANALYZER_IMAGE_PREFIX/tslint:$SAST_ANALYZER_IMAGE_TAG"
- rules:
- - if: $SAST_DISABLED || $SAST_DISABLE_DIND == 'false'
- when: never
- - if: $CI_COMMIT_BRANCH &&
- $GITLAB_FEATURES =~ /\bsast\b/ &&
- $SAST_DEFAULT_ANALYZERS =~ /tslint/
- exists:
- - '**/*.ts'
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 e18f89cadd7..441a57048e1 100644
--- a/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Secret-Detection.gitlab-ci.yml
@@ -8,17 +8,33 @@ variables:
SECURE_ANALYZERS_PREFIX: "registry.gitlab.com/gitlab-org/security-products/analyzers"
SECRETS_ANALYZER_VERSION: "3"
-secret_detection:
+.secret-analyzer:
stage: test
image: "$SECURE_ANALYZERS_PREFIX/secrets:$SECRETS_ANALYZER_VERSION"
services: []
- rules:
- - if: $SECRET_DETECTION_DISABLED
- when: never
- - if: $CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bsecret_detection\b/
- when: on_success
artifacts:
reports:
secret_detection: gl-secret-detection-report.json
+
+secret_detection_default_branch:
+ extends: .secret-analyzer
+ rules:
+ - if: $SECRET_DETECTION_DISABLED
+ when: never
+ - if: $CI_DEFAULT_BRANCH == $CI_COMMIT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bsecret_detection\b/
+ script:
+ - /analyzer run
+
+secret_detection:
+ extends: .secret-analyzer
+ rules:
+ - if: $SECRET_DETECTION_DISABLED
+ when: never
+ - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH &&
+ $GITLAB_FEATURES =~ /\bsecret_detection\b/
script:
+ - git fetch origin $CI_DEFAULT_BRANCH $CI_BUILD_REF_NAME
+ - export SECRET_DETECTION_COMMIT_TO=$(git log --left-right --cherry-pick --pretty=format:"%H" refs/remotes/origin/$CI_DEFAULT_BRANCH...refs/remotes/origin/$CI_BUILD_REF_NAME | tail -n 1)
+ - export SECRET_DETECTION_COMMIT_FROM=$CI_COMMIT_SHA
- /analyzer run
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 b6c05c61db1..2d2e0859373 100644
--- a/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Secure-Binaries.gitlab-ci.yml
@@ -13,7 +13,7 @@
variables:
SECURE_BINARIES_ANALYZERS: >-
- bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, tslint, secrets, sobelow, pmd-apex, kubesec,
+ bandit, brakeman, gosec, spotbugs, flawfinder, phpcs-security-audit, security-code-scan, nodejs-scan, eslint, secrets, sobelow, pmd-apex, kubesec,
bundler-audit, retire.js, gemnasium, gemnasium-maven, gemnasium-python,
klar, clair-vulnerabilities-db,
license-finder,
@@ -40,7 +40,7 @@ variables:
- docker info
- env
- if [ -z "$SECURE_BINARIES_IMAGE" ]; then export SECURE_BINARIES_IMAGE=${SECURE_BINARIES_IMAGE:-"registry.gitlab.com/gitlab-org/security-products/analyzers/${CI_JOB_NAME}:${SECURE_BINARIES_ANALYZER_VERSION}"}; fi
- - docker pull ${SECURE_BINARIES_IMAGE}
+ - docker pull --quiet ${SECURE_BINARIES_IMAGE}
- mkdir -p output/$(dirname ${CI_JOB_NAME})
- |
if [ "$SECURE_BINARIES_SAVE_ARTIFACTS" = "true" ]; then
@@ -125,13 +125,6 @@ eslint:
- $SECURE_BINARIES_DOWNLOAD_IMAGES == "true" &&
$SECURE_BINARIES_ANALYZERS =~ /\beslint\b/
-tslint:
- extends: .download_images
- only:
- variables:
- - $SECURE_BINARIES_DOWNLOAD_IMAGES == "true" &&
- $SECURE_BINARIES_ANALYZERS =~ /\btslint\b/
-
secrets:
extends: .download_images
only:
diff --git a/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml b/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml
index e6097ae322e..9dbd9b679a8 100644
--- a/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Verify/Browser-Performance.gitlab-ci.yml
@@ -10,8 +10,9 @@ performance:
stage: performance
image: docker:git
variables:
- URL: https://example.com
- SITESPEED_VERSION: 11.2.0
+ URL: ''
+ SITESPEED_IMAGE: sitespeedio/sitespeed.io
+ SITESPEED_VERSION: 13.3.0
SITESPEED_OPTIONS: ''
services:
- docker:stable-dind
@@ -19,11 +20,10 @@ performance:
- mkdir gitlab-exporter
- wget -O ./gitlab-exporter/index.js https://gitlab.com/gitlab-org/gl-performance/raw/master/index.js
- mkdir sitespeed-results
- - docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io sitespeedio/sitespeed.io:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --outputFolder sitespeed-results $URL $SITESPEED_OPTIONS
- - mv sitespeed-results/data/performance.json performance.json
+ - docker run --shm-size=1g --rm -v "$(pwd)":/sitespeed.io $SITESPEED_IMAGE:$SITESPEED_VERSION --plugins.add ./gitlab-exporter --outputFolder sitespeed-results $URL $SITESPEED_OPTIONS
+ - mv sitespeed-results/data/performance.json browser-performance.json
artifacts:
paths:
- - performance.json
- sitespeed-results/
reports:
- performance: performance.json
+ browser_performance: browser-performance.json
diff --git a/lib/gitlab/ci/templates/Verify/Load-Performance-Testing.gitlab-ci.yml b/lib/gitlab/ci/templates/Verify/Load-Performance-Testing.gitlab-ci.yml
new file mode 100644
index 00000000000..d39bd234020
--- /dev/null
+++ b/lib/gitlab/ci/templates/Verify/Load-Performance-Testing.gitlab-ci.yml
@@ -0,0 +1,23 @@
+# Read more about the feature here: https://docs.gitlab.com/ee/user/project/merge_requests/load_performance_testing.html
+
+stages:
+ - build
+ - test
+ - deploy
+ - performance
+
+load_performance:
+ stage: performance
+ image: docker:git
+ variables:
+ K6_IMAGE: loadimpact/k6
+ K6_VERSION: 0.26.2
+ K6_TEST_FILE: github.com/loadimpact/k6/samples/http_get.js
+ K6_OPTIONS: ''
+ services:
+ - docker:stable-dind
+ script:
+ - docker run --rm -v "$(pwd)":/k6 -w /k6 $K6_IMAGE:$K6_VERSION run $K6_TEST_FILE --summary-export=load-performance.json $K6_OPTIONS
+ artifacts:
+ reports:
+ load_performance: load-performance.json
diff --git a/lib/gitlab/ci/templates/index.md b/lib/gitlab/ci/templates/index.md
new file mode 100644
index 00000000000..ff151dd4d1a
--- /dev/null
+++ b/lib/gitlab/ci/templates/index.md
@@ -0,0 +1,3 @@
+# Development guide for GitLab CI templates
+
+Please follow [the development guideline](../../../../doc/development/cicd/templates.md)
diff --git a/lib/gitlab/ci/templates/npm.gitlab-ci.yml b/lib/gitlab/ci/templates/npm.gitlab-ci.yml
new file mode 100644
index 00000000000..035ba52da84
--- /dev/null
+++ b/lib/gitlab/ci/templates/npm.gitlab-ci.yml
@@ -0,0 +1,59 @@
+default:
+ image: node:latest
+
+ # Validate that the repository contains a package.json and extract a few values from it.
+ before_script:
+ - |
+ if [[ ! -f package.json ]]; then
+ echo "No package.json found! A package.json file is required to publish a package to GitLab's NPM registry."
+ echo 'For more information, see https://docs.gitlab.com/ee/user/packages/npm_registry/#creating-a-project'
+ exit 1
+ fi
+ - NPM_PACKAGE_NAME=$(node -p "require('./package.json').name")
+ - NPM_PACKAGE_VERSION=$(node -p "require('./package.json').version")
+
+# Validate that the package name is properly scoped to the project's root namespace.
+# For more information, see https://docs.gitlab.com/ee/user/packages/npm_registry/#package-naming-convention
+validate_package_scope:
+ stage: build
+ script:
+ - |
+ if [[ ! $NPM_PACKAGE_NAME =~ ^@$CI_PROJECT_ROOT_NAMESPACE/ ]]; then
+ echo "Invalid package scope! Packages must be scoped in the root namespace of the project, e.g. \"@${CI_PROJECT_ROOT_NAMESPACE}/${CI_PROJECT_NAME}\""
+ echo 'For more information, see https://docs.gitlab.com/ee/user/packages/npm_registry/#package-naming-convention'
+ exit 1
+ fi
+
+# If no .npmrc if included in the repo, generate a temporary one to use during the publish step
+# that is configured to publish to GitLab's NPM registry
+create_npmrc:
+ stage: build
+ script:
+ - |
+ if [[ ! -f .npmrc ]]; then
+ echo 'No .npmrc found! Creating one now. Please review the following link for more information: https://docs.gitlab.com/ee/user/packages/npm_registry/index.html#authenticating-with-a-ci-job-token'
+
+ {
+ echo '@${CI_PROJECT_ROOT_NAMESPACE}:registry=${CI_SERVER_PROTOCOL}://${CI_SERVER_HOST}:${CI_SERVER_PORT}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/'
+ echo '//${CI_SERVER_HOST}:${CI_SERVER_PORT}/api/v4/packages/npm/:_authToken=${CI_JOB_TOKEN}'
+ echo '//${CI_SERVER_HOST}:${CI_SERVER_PORT}/api/v4/projects/${CI_PROJECT_ID}/packages/npm/:_authToken=${CI_JOB_TOKEN}'
+ } >> .npmrc
+
+ fi
+ artifacts:
+ paths:
+ - .npmrc
+
+# Publish the package. If the version in package.json has not yet been published, it will be
+# published to GitLab's NPM registry. If the version already exists, the publish command
+# will fail and the existing package will not be updated.
+publish_package:
+ stage: deploy
+ script:
+ - |
+ {
+ npm publish &&
+ echo "Successfully published version ${NPM_PACKAGE_VERSION} of ${NPM_PACKAGE_NAME} to GitLab's NPM registry: ${CI_PROJECT_URL}/-/packages"
+ } || {
+ echo "No new version of ${NPM_PACKAGE_NAME} published. This is most likely because version ${NPM_PACKAGE_VERSION} already exists in GitLab's NPM registry."
+ }
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 6a9b7b2fc85..8cf355bbfc1 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -3,15 +3,33 @@
module Gitlab
module Ci
class YamlProcessor
- ValidationError = Class.new(StandardError)
+ # ValidationError is treated like a result object in the form of an exception.
+ # We can return any warnings, raised during the config validation, along with
+ # the error object until we support multiple messages to be returned.
+ class ValidationError < StandardError
+ attr_reader :warnings
+
+ def initialize(message, warnings: [])
+ @warnings = warnings
+ super(message)
+ end
+ end
include Gitlab::Config::Entry::LegacyValidationHelpers
attr_reader :stages, :jobs
- ResultWithErrors = Struct.new(:content, :errors) do
+ class Result
+ attr_reader :config, :errors, :warnings
+
+ def initialize(config: nil, errors: [], warnings: [])
+ @config = config
+ @errors = errors
+ @warnings = warnings
+ end
+
def valid?
- errors.empty?
+ config.present? && errors.empty?
end
end
@@ -20,24 +38,32 @@ module Gitlab
@config = @ci_config.to_hash
unless @ci_config.valid?
- raise ValidationError, @ci_config.errors.first
+ error!(@ci_config.errors.first)
end
initial_parsing
rescue Gitlab::Ci::Config::ConfigError => e
- raise ValidationError, e.message
+ error!(e.message)
end
def self.new_with_validation_errors(content, opts = {})
- return ResultWithErrors.new('', ['Please provide content of .gitlab-ci.yml']) if content.blank?
+ return Result.new(errors: ['Please provide content of .gitlab-ci.yml']) if content.blank?
config = Gitlab::Ci::Config.new(content, **opts)
- return ResultWithErrors.new("", config.errors) unless config.valid?
+ return Result.new(errors: config.errors, warnings: config.warnings) unless config.valid?
config = Gitlab::Ci::YamlProcessor.new(content, opts)
- ResultWithErrors.new(config, [])
- rescue ValidationError, Gitlab::Ci::Config::ConfigError => e
- ResultWithErrors.new('', [e.message])
+ Result.new(config: config, warnings: config.warnings)
+
+ rescue ValidationError => e
+ Result.new(errors: [e.message], warnings: e.warnings)
+
+ rescue Gitlab::Ci::Config::ConfigError => e
+ Result.new(errors: [e.message])
+ end
+
+ def warnings
+ @ci_config&.warnings || []
end
def builds
@@ -66,6 +92,7 @@ module Gitlab
cache: job[:cache],
resource_group_key: job[:resource_group],
scheduling_type: job[:scheduling_type],
+ secrets: job[:secrets],
options: {
image: job[:image],
services: job[:services],
@@ -157,10 +184,14 @@ module Gitlab
return unless job[:stage]
unless job[:stage].is_a?(String) && job[:stage].in?(@stages)
- raise ValidationError, "#{name} job: chosen stage does not exist; available stages are #{@stages.join(", ")}"
+ error!("#{name} job: chosen stage does not exist; available stages are #{@stages.join(", ")}")
end
end
+ def error!(message)
+ raise ValidationError.new(message, warnings: warnings)
+ end
+
def validate_job_dependencies!(name, job)
return unless job[:dependencies]
@@ -190,7 +221,7 @@ module Gitlab
def validate_job_dependency!(name, dependency, dependency_type = 'dependency')
unless @jobs[dependency.to_sym]
- raise ValidationError, "#{name} job: undefined #{dependency_type}: #{dependency}"
+ error!("#{name} job: undefined #{dependency_type}: #{dependency}")
end
job_stage_index = stage_index(name)
@@ -199,7 +230,7 @@ module Gitlab
# A dependency might be defined later in the configuration
# with a stage that does not exist
unless dependency_stage_index.present? && dependency_stage_index < job_stage_index
- raise ValidationError, "#{name} job: #{dependency_type} #{dependency} is not defined in prior stages"
+ error!("#{name} job: #{dependency_type} #{dependency} is not defined in prior stages")
end
end
@@ -221,19 +252,19 @@ module Gitlab
on_stop_job = @jobs[on_stop.to_sym]
unless on_stop_job
- raise ValidationError, "#{name} job: on_stop job #{on_stop} is not defined"
+ error!("#{name} job: on_stop job #{on_stop} is not defined")
end
unless on_stop_job[:environment]
- raise ValidationError, "#{name} job: on_stop job #{on_stop} does not have environment defined"
+ error!("#{name} job: on_stop job #{on_stop} does not have environment defined")
end
unless on_stop_job[:environment][:name] == environment[:name]
- raise ValidationError, "#{name} job: on_stop job #{on_stop} have different environment name"
+ error!("#{name} job: on_stop job #{on_stop} have different environment name")
end
unless on_stop_job[:environment][:action] == 'stop'
- raise ValidationError, "#{name} job: on_stop job #{on_stop} needs to have action stop defined"
+ error!("#{name} job: on_stop job #{on_stop} needs to have action stop defined")
end
end
end