104 lines
3 KiB
Ruby
104 lines
3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Resolvers
|
|
module Ci
|
|
class ConfigResolver < BaseResolver
|
|
include Gitlab::Graphql::Authorize::AuthorizeResource
|
|
include ResolvesProject
|
|
|
|
type Types::Ci::Config::ConfigType, null: true
|
|
description <<~MD
|
|
Linted and processed contents of a CI config.
|
|
Should not be requested more than once per request.
|
|
MD
|
|
|
|
authorize :read_pipeline
|
|
|
|
argument :project_path, GraphQL::Types::ID,
|
|
required: true,
|
|
description: 'Project of the CI config.'
|
|
|
|
argument :sha, GraphQL::Types::String,
|
|
required: false,
|
|
description: "Sha for the pipeline."
|
|
|
|
argument :content, GraphQL::Types::String,
|
|
required: true,
|
|
description: "Contents of `.gitlab-ci.yml`."
|
|
|
|
argument :dry_run, GraphQL::Types::Boolean,
|
|
required: false,
|
|
description: 'Run pipeline creation simulation, or only do static check.'
|
|
|
|
def resolve(project_path:, content:, sha: nil, dry_run: false)
|
|
project = authorized_find!(project_path: project_path)
|
|
|
|
result = ::Gitlab::Ci::Lint
|
|
.new(project: project, current_user: context[:current_user], sha: sha)
|
|
.validate(content, dry_run: dry_run)
|
|
|
|
response(result).merge(merged_yaml: result.merged_yaml)
|
|
rescue GRPC::InvalidArgument => error
|
|
Gitlab::ErrorTracking.track_and_raise_exception(error, sha: sha)
|
|
end
|
|
|
|
private
|
|
|
|
def response(result)
|
|
if result.errors.empty?
|
|
{
|
|
status: :valid,
|
|
errors: [],
|
|
warnings: result.warnings,
|
|
stages: make_stages(result.jobs)
|
|
}
|
|
else
|
|
{
|
|
status: :invalid,
|
|
warnings: result.warnings,
|
|
errors: result.errors
|
|
}
|
|
end
|
|
end
|
|
|
|
def make_jobs(config_jobs)
|
|
config_jobs.map do |job|
|
|
{
|
|
name: job[:name],
|
|
stage: job[:stage],
|
|
group_name: CommitStatus.new(name: job[:name]).group_name,
|
|
needs: job[:needs] || [],
|
|
allow_failure: job[:allow_failure],
|
|
before_script: job[:before_script],
|
|
script: job[:script],
|
|
after_script: job[:after_script],
|
|
only: job[:only],
|
|
except: job[:except],
|
|
when: job[:when],
|
|
tags: job[:tag_list],
|
|
environment: job[:environment]
|
|
}
|
|
end
|
|
end
|
|
|
|
def make_groups(job_data)
|
|
jobs = make_jobs(job_data)
|
|
|
|
jobs_by_group = jobs.group_by { |job| job[:group_name] }
|
|
jobs_by_group.map do |name, jobs|
|
|
{ jobs: jobs, name: name, stage: jobs.first[:stage], size: jobs.size }
|
|
end
|
|
end
|
|
|
|
def make_stages(jobs)
|
|
make_groups(jobs)
|
|
.group_by { |group| group[:stage] }
|
|
.map { |name, groups| { name: name, groups: groups } }
|
|
end
|
|
|
|
def find_object(project_path:)
|
|
resolve_project(full_path: project_path)
|
|
end
|
|
end
|
|
end
|
|
end
|