2020-11-24 15:15:51 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module Gitlab
|
|
|
|
module Ci
|
|
|
|
class Lint
|
|
|
|
class Result
|
2021-01-03 14:25:43 +05:30
|
|
|
attr_reader :jobs, :merged_yaml, :errors, :warnings
|
2020-11-24 15:15:51 +05:30
|
|
|
|
2021-01-03 14:25:43 +05:30
|
|
|
def initialize(jobs:, merged_yaml:, errors:, warnings:)
|
2020-11-24 15:15:51 +05:30
|
|
|
@jobs = jobs
|
2021-01-03 14:25:43 +05:30
|
|
|
@merged_yaml = merged_yaml
|
2020-11-24 15:15:51 +05:30
|
|
|
@errors = errors
|
|
|
|
@warnings = warnings
|
|
|
|
end
|
|
|
|
|
|
|
|
def valid?
|
|
|
|
@errors.empty?
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-03-08 18:12:59 +05:30
|
|
|
def initialize(project:, current_user:, sha: nil)
|
2020-11-24 15:15:51 +05:30
|
|
|
@project = project
|
|
|
|
@current_user = current_user
|
2021-04-17 20:07:23 +05:30
|
|
|
@sha = sha || project.repository.commit&.sha
|
2020-11-24 15:15:51 +05:30
|
|
|
end
|
|
|
|
|
|
|
|
def validate(content, dry_run: false)
|
2021-01-29 00:20:46 +05:30
|
|
|
if dry_run
|
2020-11-24 15:15:51 +05:30
|
|
|
simulate_pipeline_creation(content)
|
|
|
|
else
|
|
|
|
static_validation(content)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def simulate_pipeline_creation(content)
|
|
|
|
pipeline = ::Ci::CreatePipelineService
|
|
|
|
.new(@project, @current_user, ref: @project.default_branch)
|
|
|
|
.execute(:push, dry_run: true, content: content)
|
|
|
|
|
|
|
|
Result.new(
|
|
|
|
jobs: dry_run_convert_to_jobs(pipeline.stages),
|
2021-01-03 14:25:43 +05:30
|
|
|
merged_yaml: pipeline.merged_yaml,
|
2020-11-24 15:15:51 +05:30
|
|
|
errors: pipeline.error_messages.map(&:content),
|
|
|
|
warnings: pipeline.warning_messages(limit: ::Gitlab::Ci::Warnings::MAX_LIMIT).map(&:content)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def static_validation(content)
|
|
|
|
result = Gitlab::Ci::YamlProcessor.new(
|
|
|
|
content,
|
|
|
|
project: @project,
|
|
|
|
user: @current_user,
|
2021-03-08 18:12:59 +05:30
|
|
|
sha: @sha
|
2020-11-24 15:15:51 +05:30
|
|
|
).execute
|
|
|
|
|
|
|
|
Result.new(
|
|
|
|
jobs: static_validation_convert_to_jobs(result),
|
2021-01-03 14:25:43 +05:30
|
|
|
merged_yaml: result.merged_yaml,
|
2020-11-24 15:15:51 +05:30
|
|
|
errors: result.errors,
|
|
|
|
warnings: result.warnings.take(::Gitlab::Ci::Warnings::MAX_LIMIT) # rubocop: disable CodeReuse/ActiveRecord
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def dry_run_convert_to_jobs(stages)
|
|
|
|
stages.reduce([]) do |jobs, stage|
|
|
|
|
jobs + stage.statuses.map do |job|
|
|
|
|
{
|
|
|
|
name: job.name,
|
|
|
|
stage: stage.name,
|
|
|
|
before_script: job.options[:before_script].to_a,
|
|
|
|
script: job.options[:script].to_a,
|
|
|
|
after_script: job.options[:after_script].to_a,
|
|
|
|
tag_list: (job.tag_list if job.is_a?(::Ci::Build)).to_a,
|
|
|
|
environment: job.options.dig(:environment, :name),
|
|
|
|
when: job.when,
|
|
|
|
allow_failure: job.allow_failure
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def static_validation_convert_to_jobs(result)
|
|
|
|
jobs = []
|
|
|
|
return jobs unless result.valid?
|
|
|
|
|
|
|
|
result.stages.each do |stage_name|
|
|
|
|
result.builds.each do |job|
|
|
|
|
next unless job[:stage] == stage_name
|
|
|
|
|
|
|
|
jobs << {
|
|
|
|
name: job[:name],
|
|
|
|
stage: stage_name,
|
|
|
|
before_script: job.dig(:options, :before_script).to_a,
|
|
|
|
script: job.dig(:options, :script).to_a,
|
|
|
|
after_script: job.dig(:options, :after_script).to_a,
|
|
|
|
tag_list: job[:tag_list].to_a,
|
|
|
|
only: job[:only],
|
|
|
|
except: job[:except],
|
|
|
|
environment: job[:environment],
|
|
|
|
when: job[:when],
|
2021-03-08 18:12:59 +05:30
|
|
|
allow_failure: job[:allow_failure],
|
|
|
|
needs: job.dig(:needs_attributes)
|
2020-11-24 15:15:51 +05:30
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
jobs
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|