Commit 01ec4674 authored by Douwe Maan's avatar Douwe Maan

Merge branch 'fj-create-webide-terminal-service' into 'master'

Add new service to create the web ide terminal

See merge request gitlab-org/gitlab-ee!8549
parents 5159d9fc e6ce54f8
...@@ -78,7 +78,8 @@ module Ci ...@@ -78,7 +78,8 @@ module Ci
enum_with_nil config_source: { enum_with_nil config_source: {
unknown_source: nil, unknown_source: nil,
repository_source: 1, repository_source: 1,
auto_devops_source: 2 auto_devops_source: 2,
webide_source: 3 ## EE-specific
} }
# We use `Ci::PipelineEnums.failure_reasons` here so that EE can more easily # We use `Ci::PipelineEnums.failure_reasons` here so that EE can more easily
...@@ -182,6 +183,8 @@ module Ci ...@@ -182,6 +183,8 @@ module Ci
scope :internal, -> { where(source: internal_sources) } scope :internal, -> { where(source: internal_sources) }
scope :for_user, -> (user) { where(user: user) }
# Returns the pipelines in descending order (= newest first), optionally # Returns the pipelines in descending order (= newest first), optionally
# limited to a number of references. # limited to a number of references.
# #
...@@ -507,6 +510,8 @@ module Ci ...@@ -507,6 +510,8 @@ module Ci
end end
def ci_yaml_file_path def ci_yaml_file_path
return unless repository_source? || unknown_source?
if project.ci_config_path.blank? if project.ci_config_path.blank?
'.gitlab-ci.yml' '.gitlab-ci.yml'
else else
...@@ -675,6 +680,7 @@ module Ci ...@@ -675,6 +680,7 @@ module Ci
def ci_yaml_from_repo def ci_yaml_from_repo
return unless project return unless project
return unless sha return unless sha
return unless ci_yaml_file_path
project.repository.gitlab_ci_yml_for(sha, ci_yaml_file_path) project.repository.gitlab_ci_yml_for(sha, ci_yaml_file_path)
rescue GRPC::NotFound, GRPC::Internal rescue GRPC::NotFound, GRPC::Internal
......
...@@ -15,7 +15,7 @@ module EE ...@@ -15,7 +15,7 @@ module EE
override :sources override :sources
def sources def sources
super.merge(pipeline: 7, chat: 8) super.merge(pipeline: 7, chat: 8, webide: 9)
end end
end end
end end
......
...@@ -55,6 +55,8 @@ module EE ...@@ -55,6 +55,8 @@ module EE
has_many :source_pipelines, class_name: 'Ci::Sources::Pipeline', foreign_key: :project_id has_many :source_pipelines, class_name: 'Ci::Sources::Pipeline', foreign_key: :project_id
has_many :webide_pipelines, -> { webide_source }, class_name: 'Ci::Pipeline', inverse_of: :project
has_many :prometheus_alerts, inverse_of: :project has_many :prometheus_alerts, inverse_of: :project
has_many :prometheus_alert_events, inverse_of: :project has_many :prometheus_alert_events, inverse_of: :project
...@@ -482,6 +484,10 @@ module EE ...@@ -482,6 +484,10 @@ module EE
end end
end end
def active_webide_pipelines(user:)
webide_pipelines.running_or_pending.for_user(user)
end
private private
def set_override_pull_mirror_available def set_override_pull_mirror_available
......
...@@ -92,6 +92,7 @@ class License < ActiveRecord::Base ...@@ -92,6 +92,7 @@ class License < ActiveRecord::Base
prometheus_alerts prometheus_alerts
operations_dashboard operations_dashboard
tracing tracing
webide_terminal
].freeze ].freeze
# List all features available for early adopters, # List all features available for early adopters,
......
...@@ -201,6 +201,12 @@ module EE ...@@ -201,6 +201,12 @@ module EE
prevent(*::ProjectPolicy.create_update_admin_destroy(feature)) prevent(*::ProjectPolicy.create_update_admin_destroy(feature))
end end
end end
condition(:web_ide_terminal_available) do
@subject.feature_available?(:webide_terminal)
end
rule { web_ide_terminal_available & can?(:create_pipeline) & can?(:maintainer_access) }.enable :create_web_ide_terminal
end end
end end
end end
# frozen_string_literal: true
module Ci
class CreateWebideTerminalService < ::BaseService
include ::Gitlab::Utils::StrongMemoize
TerminalCreationError = Class.new(StandardError)
TERMINAL_NAME = 'terminal'.freeze
attr_reader :terminal
def execute
check_access!
validate_params!
load_terminal_config!
pipeline = create_pipeline!
success(pipeline: pipeline)
rescue TerminalCreationError => e
error(e.message)
rescue ActiveRecord::RecordInvalid => e
error("Failed to persist the pipeline: #{e.message}")
end
private
def create_pipeline!
build_pipeline.tap do |pipeline|
pipeline.stages << terminal_stage_seed(pipeline).to_resource
pipeline.save!
pipeline.process!
pipeline_created_counter.increment(source: :webide)
end
end
def build_pipeline
Ci::Pipeline.new(
project: project,
user: current_user,
source: :webide,
config_source: :webide_source,
ref: ref,
sha: sha,
tag: false,
before_sha: Gitlab::Git::BLANK_SHA
)
end
def terminal_stage_seed(pipeline)
Gitlab::Ci::Pipeline::Seed::Stage.new(pipeline,
name: TERMINAL_NAME,
index: 0,
builds: [terminal_build_seed])
end
def terminal_build_seed
terminal.merge(
name: TERMINAL_NAME,
stage: TERMINAL_NAME,
user: current_user)
end
def load_terminal_config!
result = ::Ci::WebideConfigService.new(project, current_user, sha: sha).execute
raise TerminalCreationError, result[:message] if result[:status] != :success
@terminal = result[:terminal]
raise TerminalCreationError, 'Terminal is not configured' unless terminal
end
def validate_params!
unless sha
raise TerminalCreationError, 'Ref does not exist'
end
unless branch_exists?
raise TerminalCreationError, 'Ref needs to be a branch'
end
end
def check_access!
unless can?(current_user, :create_web_ide_terminal, project)
raise TerminalCreationError, 'Insufficient permissions to create a terminal'
end
if terminal_active?
raise TerminalCreationError, 'There is already a terminal running'
end
end
def pipeline_created_counter
@pipeline_created_counter ||= Gitlab::Metrics
.counter(:pipelines_created_total, "Counter of pipelines created")
end
def terminal_active?
project.active_webide_pipelines(user: current_user).exists?
end
def ref
strong_memoize(:ref) do
Gitlab::Git.ref_name(params[:ref])
end
end
def branch_exists?
project.repository.branch_exists?(ref)
end
def sha
project.commit(params[:ref]).try(:id)
end
end
end
# frozen_string_literal: true
module Ci
class WebideConfigService < ::BaseService
include ::Gitlab::Utils::StrongMemoize
ValidationError = Class.new(StandardError)
WEBIDE_CONFIG_FILE = '.gitlab/.gitlab-webide.yml'.freeze
attr_reader :config, :config_content
def execute
check_access!
load_config_content!
load_config!
success(terminal: config.terminal_value)
rescue ValidationError => e
error(e.message)
end
private
def check_access!
unless can?(current_user, :download_code, project)
raise ValidationError, 'Insufficient permissions to read configuration'
end
end
def load_config_content!
@config_content = webide_yaml_from_repo
unless config_content
raise ValidationError, "Failed to load Web IDE config file '#{WEBIDE_CONFIG_FILE}' for #{params[:sha]}"
end
end
def load_config!
@config = Gitlab::Webide::Config.new(config_content)
unless @config.valid?
raise ValidationError, @config.errors.first
end
rescue Gitlab::Webide::Config::ConfigError => e
raise ValidationError, e.message
end
def webide_yaml_from_repo
gitlab_webide_yml_for(params[:sha])
rescue GRPC::NotFound, GRPC::Internal
nil
end
def gitlab_webide_yml_for(sha)
project.repository.blob_data_at(sha, WEBIDE_CONFIG_FILE)
end
end
end
# frozen_string_literal: true
module Gitlab
module Webide
#
# Base GitLab Webide Configuration facade
#
class Config
ConfigError = Class.new(StandardError)
def initialize(config, opts = {})
@config = build_config(config, opts)
@global = Entry::Global.new(@config)
@global.compose!
rescue Gitlab::Config::Loader::FormatError => e
raise Config::ConfigError, e.message
end
def valid?
@global.valid?
end
def errors
@global.errors
end
def to_hash
@config
end
def terminal_value
@global.terminal_value
end
private
def build_config(config, opts = {})
Gitlab::Config::Loader::Yaml.new(config).load!
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Webide
class Config
module Entry
##
# This class represents a global entry - root Entry for entire
# GitLab Webide Configuration file.
#
class Global < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Configurable
include ::Gitlab::Config::Entry::Attributable
ALLOWED_KEYS = %i[terminal].freeze
validations do
validates :config, allowed_keys: ALLOWED_KEYS
end
entry :terminal, Entry::Terminal,
description: 'Configuration of the webide terminal.'
helpers :terminal
attributes :terminal
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Webide
class Config
module Entry
##
# Entry that represents a concrete CI/CD job.
#
class Terminal < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Configurable
include ::Gitlab::Config::Entry::Attributable
# By default the build will finish in a few seconds, not giving the webide
# enough time to connect to the terminal. This default script provides
# those seconds blocking the build from finishing inmediately.
DEFAULT_SCRIPT = ['sleep 60'].freeze
ALLOWED_KEYS = %i[image services tags before_script script variables].freeze
validations do
validates :config, allowed_keys: ALLOWED_KEYS
with_options allow_nil: true do
validates :tags, array_of_strings: true
end
end
entry :before_script, ::Gitlab::Ci::Config::Entry::Script,
description: 'Global before script overridden in this job.'
entry :script, ::Gitlab::Ci::Config::Entry::Commands,
description: 'Commands that will be executed in this job.'
entry :image, ::Gitlab::Ci::Config::Entry::Image,
description: 'Image that will be used to execute this job.'
entry :services, ::Gitlab::Ci::Config::Entry::Services,
description: 'Services that will be used to execute this job.'
entry :variables, ::Gitlab::Ci::Config::Entry::Variables,
description: 'Environment variables available for this job.'
helpers :before_script, :script, :image, :variables, :services
attributes :tags
def value
to_hash.compact
end
private
def to_hash
{ tag_list: tags || [],
yaml_variables: yaml_variables,
options: {
image: image_value,
services: services_value,
before_script: before_script_value,
script: script_value || DEFAULT_SCRIPT
}.compact }
end
def yaml_variables
return unless variables_value
variables_value.map do |key, value|
{ key: key.to_s, value: value, public: true }
end
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Ci::CreateWebideTerminalService do
set(:project) { create(:project, :repository) }
set(:user) { create(:user) }
let(:ref) { 'master' }
before do
stub_licensed_features(webide_terminal: true)
end
describe '#execute' do
subject { described_class.new(project, user, ref: ref).execute }
context 'for maintainer' do
shared_examples 'be successful' do
it 'returns a success with pipeline object' do
is_expected.to include(status: :success)
expect(subject[:pipeline]).to be_a(Ci::Pipeline)
expect(subject[:pipeline]).to be_persisted
expect(subject[:pipeline].stages.count).to eq(1)
expect(subject[:pipeline].builds.count).to eq(1)
end
end
before do
project.add_maintainer(user)
end
context 'when web-ide has valid configuration' do
before do
stub_webide_config_file(config_content)
end
context 'for empty configuration' do
let(:config_content) do
'terminal: {}'
end
it_behaves_like 'be successful'
end
context 'for configuration with container image' do
let(:config_content) do
'terminal: { image: ruby }'
end
it_behaves_like 'be successful'
end
end
end
context 'error handling' do
shared_examples 'having an error' do |message|
it 'returns an error' do
is_expected.to eq(
status: :error,
message: message
)
end
end
shared_examples 'having insufficient permissions' do
it_behaves_like 'having an error', 'Insufficient permissions to create a terminal'
end
context 'when user is developer' do
before do
project.add_developer(user)
end
it_behaves_like 'having insufficient permissions'
end
context 'when user is maintainer' do
before do
project.add_maintainer(user)
end
context 'when terminal is already running' do
let!(:webide_pipeline) { create(:ee_ci_pipeline, :webide, :running, project: project, user: user) }
it_behaves_like 'having an error', 'There is already a terminal running'
end
context 'when ref is non-existing' do
let(:ref) { 'non-existing-ref' }
it_behaves_like 'having an error', 'Ref does not exist'
end
context 'when ref is a tag' do
let(:ref) { 'v1.0.0' }
it_behaves_like 'having an error', 'Ref needs to be a branch'
end
context 'when terminal config is missing' do
let(:ref) { 'v1.0.0' }
it_behaves_like 'having an error', 'Ref needs to be a branch'
end
context 'when webide config is present' do
before do
stub_webide_config_file(config_content)
end
context 'config has invalid content' do
let(:config_content) { 'invalid' }
it_behaves_like 'having an error', 'Invalid configuration format'
end
context 'config is valid, but does not have terminal' do
let(:config_content) { '{}' }
it_behaves_like 'having an error', 'Terminal is not configured'
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Ci::WebideConfigService do
set(:project) { create(:project, :repository) }
set(:user) { create(:user) }
let(:sha) { 'sha' }
describe '#execute' do
subject { described_class.new(project, user, sha: sha).execute }
context 'when insufficient permission' do
it 'returns an error' do
is_expected.to include(
status: :error,
message: 'Insufficient permissions to read configuration')
end
end
context 'for developer' do
before do
project.add_developer(user)
end
context 'when file is missing' do
it 'returns an error' do
is_expected.to include(
status: :error,
message: "Failed to load Web IDE config file '.gitlab/.gitlab-webide.yml' for sha")
end
end
context 'when file is present' do
before do
allow(project.repository).to receive(:blob_data_at).with('sha', anything) do
config_content
end
end
context 'content is not valid' do
let(:config_content) { 'invalid content' }
it 'returns an error' do
is_expected.to include(
status: :error,
message: "Invalid configuration format")
end
end
context 'content is valid, but terminal not defined' do
let(:config_content) { '{}' }
it 'returns success' do
is_expected.to include(
status: :success,
terminal: nil)
end
end
context 'content is valid, with enabled terminal' do
let(:config_content) { 'terminal: {}' }
it 'returns success' do
is_expected.to include(
status: :success,
terminal: {
tag_list: [],
yaml_variables: [],
options: { script: ["sleep 60"] }
})
end
end
context 'content is valid, with custom terminal' do
let(:config_content) { 'terminal: { before_script: [ls] }' }
it 'returns success' do
is_expected.to include(
status: :success,
terminal: {
tag_list: [],
yaml_variables: [],
options: { before_script: ["ls"], script: ["sleep 60"] }
})
end
end
end
end
end
end
# frozen_string_literal: true
FactoryBot.define do
factory :ee_ci_pipeline, class: Ci::Pipeline, parent: :ci_pipeline do
trait :webide do
source :webide
config_source :webide_source
end
end
end
...@@ -68,6 +68,7 @@ project: ...@@ -68,6 +68,7 @@ project:
- project_registry - project_registry
- packages - packages
- tracing_setting - tracing_setting
- webide_pipelines
prometheus_metrics: prometheus_metrics:
- project - project
- prometheus_alerts - prometheus_alerts
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Webide::Config::Entry::Global do
let(:global) { described_class.new(hash) }
describe '.nodes' do
it 'returns a hash' do
expect(described_class.nodes).to be_a(Hash)
end
context 'when filtering all the entry/node names' do
it 'contains the expected node names' do
expect(described_class.nodes.keys)
.to match_array(%i[terminal])
end
end
end
context 'when configuration is valid' do
context 'when some entries defined' do
let(:hash) do
{ terminal: { before_script: ['ls'], variables: {}, script: 'sleep 10s', services: ['mysql'] } }
end
describe '#compose!' do
before do
global.compose!
end
it 'creates nodes hash' do
expect(global.descendants).to be_an Array
end
it 'creates node object for each entry' do
expect(global.descendants.count).to eq 1
end
it 'creates node object using valid class' do
expect(global.descendants.first)
.to be_an_instance_of Gitlab::Webide::Config::Entry::Terminal
end
it 'sets correct description for nodes' do
expect(global.descendants.first.description)
.to eq 'Configuration of the webide terminal.'
end
describe '#leaf?' do
it 'is not leaf' do
expect(global).not_to be_leaf
end
end
end
context 'when not composed' do
describe '#terminal_value' do
it 'returns nil' do
expect(global.terminal_value).to be nil
end
end
describe '#leaf?' do
it 'is leaf' do
expect(global).to be_leaf
end
end
end
context 'when composed' do
before do
global.compose!
end
describe '#errors' do
it 'has no errors' do
expect(global.errors).to be_empty
end
end
describe '#terminal_value' do
it 'returns correct script' do
expect(global.terminal_value).to eq({
tag_list: [],
yaml_variables: [],
options: {
before_script: ['ls'],
script: ['sleep 10s'],
services: [{ name: "mysql" }]
}
})
end
end
end
end
end
context 'when configuration is not valid' do
before do
global.compose!
end
context 'when job does not have valid before script' do
let(:hash) do
{ terminal: { before_script: 100 } }
end
describe '#errors' do
it 'reports errors about missing script' do
expect(global.errors)
.to include "terminal:before_script config should be an array of strings"
end
end
end
end
context 'when value is not a hash' do
let(:hash) { [] }
describe '#valid?' do
it 'is not valid' do
expect(global).not_to be_valid
end
end
describe '#errors' do
it 'returns error about invalid type' do
expect(global.errors.first).to match /should be a hash/
end
end
end
describe '#specified?' do
it 'is concrete entry that is defined' do
expect(global.specified?).to be true
end
end
describe '#[]' do
before do
global.compose!
end
let(:hash) do
{ terminal: { before_script: ['ls'] } }
end
context 'when entry exists' do
it 'returns correct entry' do
expect(global[:terminal])
.to be_an_instance_of Gitlab::Webide::Config::Entry::Terminal
expect(global[:terminal][:before_script].value).to eq ['ls']
end
end
context 'when entry does not exist' do
it 'always return unspecified node' do
expect(global[:some][:unknown][:node])
.not_to be_specified
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Webide::Config::Entry::Terminal do
let(:entry) { described_class.new(config) }
describe '.nodes' do
context 'when filtering all the entry/node names' do
subject { described_class.nodes.keys }
let(:result) do
%i[before_script script image services variables]
end
it { is_expected.to match_array result }
end
end
describe 'validations' do
before do
entry.compose!
end
context 'when entry config value is correct' do
let(:config) { { script: 'rspec' } }
describe '#valid?' do
it 'is valid' do
expect(entry).to be_valid
end
end
end
context 'when entry value is not correct' do
context 'incorrect config value type' do
let(:config) { ['incorrect'] }
describe '#errors' do
it 'reports error about a config type' do
expect(entry.errors)
.to include 'terminal config should be a hash'
end
end
end
context 'when config is empty' do
let(:config) { {} }
describe '#valid' do
it 'is valid' do
expect(entry).to be_valid
end
end
end
context 'when unknown keys detected' do
let(:config) { { unknown: true } }
describe '#valid' do
it 'is not valid' do
expect(entry).not_to be_valid
end
end
end
end
end
describe '#relevant?' do
it 'is a relevant entry' do
entry = described_class.new({ script: 'rspec' })
expect(entry).to be_relevant
end
end
context 'when composed' do
before do
entry.compose!
end
describe '#value' do
before do
entry.compose!
end
context 'when entry is correct' do
let(:config) do
{ before_script: %w[ls pwd],
script: 'sleep 100',
tags: ['webide'],
image: 'ruby:2.5',
services: ['mysql'],
variables: { KEY: 'value' } }
end
it 'returns correct value' do
expect(entry.value)
.to eq(
tag_list: ['webide'],
yaml_variables: [{ key: 'KEY', value: 'value', public: true }],
options: {
image: { name: "ruby:2.5" },
services: [{ name: "mysql" }],
before_script: %w[ls pwd],
script: ['sleep 100']
}
)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Webide::Config do
let(:config) do
described_class.new(yml)
end
context 'when config is valid' do
let(:yml) do
<<-EOS
terminal:
image: ruby:2.2
before_script:
- gem install rspec
EOS
end
describe '#to_hash' do
it 'returns hash created from string' do
hash = {
terminal: {
image: 'ruby:2.2',
before_script: ['gem install rspec']
}
}
expect(config.to_hash).to eq hash
end
describe '#valid?' do
it 'is valid' do
expect(config).to be_valid
end
it 'has no errors' do
expect(config.errors).to be_empty
end
end
end
end
context 'when config is invalid' do
context 'when yml is incorrect' do
let(:yml) { '// invalid' }
describe '.new' do
it 'raises error' do
expect { config }.to raise_error(
described_class::ConfigError,
/Invalid configuration format/
)
end
end
end
context 'when config logic is incorrect' do
let(:yml) { 'terminal: { before_script: "ls" }' }
describe '#valid?' do
it 'is not valid' do
expect(config).not_to be_valid
end
it 'has errors' do
expect(config.errors).not_to be_empty
end
end
describe '#errors' do
it 'returns an array of strings' do
expect(config.errors).to all(be_an_instance_of(String))
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe API::Runner, :clean_gitlab_redis_shared_state do
include StubGitlabCalls
include RedisHelpers
set(:project) { create(:project, :repository) }
describe '/api/v4/jobs' do
let(:runner) { create(:ci_runner, :project, projects: [project]) }
describe 'POST /api/v4/jobs/request' do
context 'for web-ide job' do
let(:user) { create(:user) }
let(:service) { Ci::CreateWebideTerminalService.new(project, user, ref: 'master').execute }
let(:pipeline) { service[:pipeline] }
let(:build) { pipeline.builds.first }
before do
stub_licensed_features(webide_terminal: true)
stub_webide_config_file(config_content)
project.add_maintainer(user)
pipeline
end
let(:config_content) do
'terminal: { image: ruby, services: [mysql], before_script: [ls], tags: [tag-1], variables: { KEY: value } }'
end
context 'when runner has matching tag' do
before do
runner.update!(tag_list: ['tag-1'])
end
it 'successfully picks job' do
request_job
build.reload
expect(build).to be_running
expect(build.runner).to eq(runner)
expect(response).to have_http_status(:created)
expect(json_response).to include(
"id" => build.id,
"variables" => include("key" => 'KEY', "value" => 'value', "public" => true),
"image" => a_hash_including("name" => 'ruby'),
"services" => all(a_hash_including("name" => 'mysql')),
"job_info" => a_hash_including("name" => 'terminal', "stage" => 'terminal'))
end
end
context 'when runner does not have matching tags' do
it 'does not pick a job' do
request_job
build.reload
expect(build).to be_pending
expect(response).to have_http_status(204)
end
end
end
def request_job(token = runner.token, **params)
post api('/jobs/request'), params.merge(token: token)
end
end
end
end
module EE
module StubGitlabCalls
def stub_webide_config_file(content, sha: anything)
allow_any_instance_of(Repository)
.to receive(:blob_data_at).with(sha, '.gitlab/.gitlab-webide.yml')
.and_return(content)
end
end
end
...@@ -1256,6 +1256,12 @@ describe Ci::Pipeline, :mailer do ...@@ -1256,6 +1256,12 @@ describe Ci::Pipeline, :mailer do
describe '#ci_yaml_file_path' do describe '#ci_yaml_file_path' do
subject { pipeline.ci_yaml_file_path } subject { pipeline.ci_yaml_file_path }
%i[unknown_source repository_source].each do |source|
context source.to_s do
before do
pipeline.config_source = described_class.config_sources.fetch(source)
end
it 'returns the path from project' do it 'returns the path from project' do
allow(pipeline.project).to receive(:ci_config_path) { 'custom/path' } allow(pipeline.project).to receive(:ci_config_path) { 'custom/path' }
...@@ -1274,6 +1280,18 @@ describe Ci::Pipeline, :mailer do ...@@ -1274,6 +1280,18 @@ describe Ci::Pipeline, :mailer do
is_expected.to eq('.gitlab-ci.yml') is_expected.to eq('.gitlab-ci.yml')
end end
end end
end
context 'when pipeline is for auto-devops' do
before do
pipeline.config_source = 'auto_devops_source'
end
it 'does not return config file' do
is_expected.to be_nil
end
end
end
describe '#set_config_source' do describe '#set_config_source' do
context 'when pipelines does not contain needed data and auto devops is disabled' do context 'when pipelines does not contain needed data and auto devops is disabled' do
......
module StubGitlabCalls module StubGitlabCalls
prepend EE::StubGitlabCalls
def stub_gitlab_calls def stub_gitlab_calls
stub_user stub_user
stub_project_8 stub_project_8
......
...@@ -11,6 +11,7 @@ describe PipelineScheduleWorker do ...@@ -11,6 +11,7 @@ describe PipelineScheduleWorker do
end end
before do before do
stub_application_setting(auto_devops_enabled: false)
stub_ci_pipeline_to_return_yaml_file stub_ci_pipeline_to_return_yaml_file
pipeline_schedule.update_column(:next_run_at, 1.day.ago) pipeline_schedule.update_column(:next_run_at, 1.day.ago)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment