Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8d49a2afd7
commit
c4478b724a
|
|
@ -17,8 +17,6 @@ module Ci
|
|||
|
||||
validates :runner, presence: true
|
||||
validates :runner_id, uniqueness: { scope: :project_id }
|
||||
# NOTE: `on:` hook can be removed the milestone after https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155760
|
||||
# is merged
|
||||
validates :project, presence: true, on: [:create, :update]
|
||||
validates :project, presence: true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -48,12 +48,13 @@ module Members
|
|||
current_user = args[:current_user]
|
||||
next [] if managing_owners?(current_user, access_level) && cannot_manage_owners?(source, current_user)
|
||||
|
||||
emails, users, existing_members = parse_users_list(source, invitees)
|
||||
emails, users, existing_members, users_by_emails = parse_users_list(source, invitees)
|
||||
|
||||
common_arguments = {
|
||||
source: source,
|
||||
access_level: access_level,
|
||||
existing_members: existing_members
|
||||
existing_members: existing_members,
|
||||
users_by_emails: users_by_emails
|
||||
}.merge(parsed_args(args))
|
||||
|
||||
build_members(emails, users, common_arguments)
|
||||
|
|
@ -141,7 +142,7 @@ module Members
|
|||
existing_members = source.members_and_requesters.with_user(users + users_by_emails.values).index_by(&:user_id)
|
||||
end
|
||||
|
||||
[parsed_emails, users, existing_members]
|
||||
[parsed_emails, users, existing_members, users_by_emails]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ group: Dynamic Analysis
|
|||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# DAST On Demand Scan
|
||||
# DAST on-demand scan
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
|
|
|
|||
|
|
@ -64883,9 +64883,7 @@ msgid "function name"
|
|||
msgstr ""
|
||||
|
||||
msgid "group"
|
||||
msgid_plural "groups"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
msgstr ""
|
||||
|
||||
msgid "group access token"
|
||||
msgstr ""
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ FactoryBot.define do
|
|||
projects { [] }
|
||||
token_expires_at { nil }
|
||||
creator { nil }
|
||||
without_projects { false }
|
||||
end
|
||||
|
||||
after(:build) do |runner, evaluator|
|
||||
|
|
@ -28,6 +29,13 @@ FactoryBot.define do
|
|||
end
|
||||
|
||||
runner.creator = evaluator.creator if evaluator.creator
|
||||
|
||||
case runner.runner_type
|
||||
when 'group_type'
|
||||
raise ':groups is mandatory' unless evaluator.groups&.any?
|
||||
when 'project_type'
|
||||
raise ':projects is mandatory' unless evaluator.projects&.any? || evaluator.without_projects
|
||||
end
|
||||
end
|
||||
|
||||
after(:create) do |runner, evaluator|
|
||||
|
|
@ -79,7 +87,7 @@ FactoryBot.define do
|
|||
|
||||
after(:build) do |runner, evaluator|
|
||||
if runner.runner_namespaces.empty?
|
||||
runner.runner_namespaces << build(:ci_runner_namespace)
|
||||
runner.runner_namespaces << build(:ci_runner_namespace, runner: runner)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -89,14 +97,16 @@ FactoryBot.define do
|
|||
|
||||
after(:build) do |runner, evaluator|
|
||||
if runner.runner_projects.empty?
|
||||
runner.runner_projects << build(:ci_runner_project)
|
||||
runner.runner_projects << build(:ci_runner_project, runner: runner)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# we use without_projects to create invalid runner: the one without projects
|
||||
trait :without_projects do
|
||||
# we use that to create invalid runner:
|
||||
# the one without projects
|
||||
transient do
|
||||
without_projects { true }
|
||||
end
|
||||
after(:create) do |runner, evaluator|
|
||||
runner.runner_projects.delete_all
|
||||
end
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ RSpec.describe "Admin Runners", :freeze_time, feature_category: :fleet_visibilit
|
|||
describe "Runner edit page", :js do
|
||||
let_it_be(:project1) { create(:project) }
|
||||
let_it_be(:project2) { create(:project, organization: project1.organization) }
|
||||
let_it_be(:project_runner) { create(:ci_runner, :unregistered, :project) }
|
||||
let_it_be(:project_runner) { create(:ci_runner, :project, :unregistered, projects: [create(:project)]) }
|
||||
|
||||
before do
|
||||
visit edit_admin_runner_path(project_runner)
|
||||
|
|
|
|||
|
|
@ -55,9 +55,14 @@ RSpec.describe Ci::JobsFinder, '#execute', feature_category: :continuous_integra
|
|||
end
|
||||
|
||||
context 'with param `runner_type`' do
|
||||
let_it_be(:job_with_group_runner) { create(:ci_build, :success, runner: create(:ci_runner, :group)) }
|
||||
let_it_be(:job_with_instance_runner) { create(:ci_build, :success, runner: create(:ci_runner, :instance)) }
|
||||
let_it_be(:job_with_project_runner) { create(:ci_build, :success, runner: create(:ci_runner, :project)) }
|
||||
let_it_be(:job_with_group_runner) do
|
||||
create(:ci_build, :success, runner: create(:ci_runner, :group, groups: [project.parent]))
|
||||
end
|
||||
|
||||
let_it_be(:job_with_project_runner) do
|
||||
create(:ci_build, :success, runner: create(:ci_runner, :project, projects: [project]))
|
||||
end
|
||||
|
||||
context 'with feature flag :admin_jobs_filter_runner_type enabled' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
|
@ -98,11 +103,13 @@ RSpec.describe Ci::JobsFinder, '#execute', feature_category: :continuous_integra
|
|||
|
||||
context "with params" do
|
||||
let_it_be(:job_with_running_status_and_group_runner) do
|
||||
create(:ci_build, :running, runner: create(:ci_runner, :group))
|
||||
create(:ci_build, :running, runner: create(:ci_runner, :group, groups: [project.parent]))
|
||||
end
|
||||
|
||||
let_it_be(:job_with_instance_runner) { create(:ci_build, :success, runner: create(:ci_runner, :instance)) }
|
||||
let_it_be(:job_with_project_runner) { create(:ci_build, :success, runner: create(:ci_runner, :project)) }
|
||||
let_it_be(:job_with_project_runner) do
|
||||
create(:ci_build, :success, runner: create(:ci_runner, :project, projects: [project]))
|
||||
end
|
||||
|
||||
context 'with feature flag :admin_jobs_filter_runner_type enabled' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
|
|
|||
|
|
@ -84,8 +84,10 @@ RSpec.describe Resolvers::Ci::AllJobsResolver, feature_category: :continuous_int
|
|||
)
|
||||
end
|
||||
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) }
|
||||
let_it_be(:running_job_with_group_runner) do
|
||||
create(:ci_build, :running, name: 'running_job_with_instance_runner', runner: create(:ci_runner, :group))
|
||||
create(:ci_build, :running, name: 'running_job_with_instance_runner', runner: group_runner)
|
||||
end
|
||||
|
||||
context 'with feature flag :admin_jobs_filter_runner_type enabled' do
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ RSpec.describe Gitlab::ApplicationContext, feature_category: :shared do
|
|||
end
|
||||
|
||||
context 'when using a runner project' do
|
||||
let_it_be_with_reload(:runner) { create(:ci_runner, :project) }
|
||||
let_it_be_with_reload(:runner) { create(:ci_runner, :project, projects: [project]) }
|
||||
|
||||
it 'sets project path from runner project' do
|
||||
context = described_class.new(runner: runner)
|
||||
|
|
|
|||
|
|
@ -5565,7 +5565,7 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def
|
|||
|
||||
context 'when build has a project runner assigned' do
|
||||
before do
|
||||
build.runner = create(:ci_runner, :project)
|
||||
build.runner = create(:ci_runner, :project, projects: [project])
|
||||
end
|
||||
|
||||
it 'is not a shared runner build' do
|
||||
|
|
|
|||
|
|
@ -12,21 +12,19 @@ RSpec.describe Ci::RunnerNamespace, feature_category: :runner do
|
|||
end
|
||||
|
||||
it_behaves_like 'cleanup by a loose foreign key' do
|
||||
let!(:model) { create(:ci_runner_namespace) }
|
||||
|
||||
let!(:parent) { model.namespace }
|
||||
let!(:parent) { create(:group) }
|
||||
let!(:runner) { create(:ci_runner, :group, groups: [parent]) }
|
||||
let(:model) { runner.runner_namespaces.first }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
before_all do
|
||||
create(:ci_runner, :group, groups: [create(:group)])
|
||||
end
|
||||
let_it_be(:runner) { create(:ci_runner, :group, groups: [create(:group)]) }
|
||||
|
||||
it { is_expected.to validate_presence_of(:namespace).on([:create, :update]) }
|
||||
it { is_expected.to validate_uniqueness_of(:runner_id).scoped_to(:namespace_id) }
|
||||
|
||||
it 'validates that runner_id is valid' do
|
||||
runner_namespace = create(:ci_runner_namespace, namespace: Group.first)
|
||||
runner_namespace = runner.runner_namespaces.first
|
||||
runner_namespace.runner_id = nil
|
||||
expect(runner_namespace).not_to be_valid
|
||||
end
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ RSpec.describe Ci::RunnerProject, feature_category: :runner do
|
|||
context 'loose foreign key on ci_runner_projects.project_id' do
|
||||
it_behaves_like 'cleanup by a loose foreign key' do
|
||||
let!(:parent) { create(:project) }
|
||||
let!(:model) { create(:ci_runner_project, project: parent) }
|
||||
let!(:runner) { create(:ci_runner, :project, projects: [parent]) }
|
||||
let(:model) { runner.runner_projects.first }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ RSpec.describe Ci::RunnerProject, feature_category: :runner do
|
|||
create(:ci_runner, :project, projects: [create(:project)])
|
||||
end
|
||||
|
||||
it { is_expected.to validate_presence_of(:project).on([:create, :update]) }
|
||||
it { is_expected.to validate_presence_of(:project) }
|
||||
it { is_expected.to validate_presence_of :runner }
|
||||
it { is_expected.to validate_uniqueness_of(:runner_id).scoped_to(:project_id) }
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ require 'spec_helper'
|
|||
RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
||||
include StubGitlabCalls
|
||||
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:project) { create(:project, group: group) }
|
||||
|
||||
it_behaves_like 'having unique enum values'
|
||||
|
||||
it_behaves_like 'it has loose foreign keys' do
|
||||
|
|
@ -24,7 +27,7 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
# validate that at least groups association does not generate cross-DB
|
||||
# queries.
|
||||
it 'does not create a cross-database query' do
|
||||
runner = create(:ci_runner, :group)
|
||||
runner = create(:ci_runner, :group, groups: [group])
|
||||
|
||||
with_cross_joins_prevented do
|
||||
expect(runner.groups.count).to eq(1)
|
||||
|
|
@ -34,7 +37,7 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
|
||||
describe '#owner_runner_namespace' do
|
||||
it 'considers the first group' do
|
||||
runner = create(:ci_runner, :group)
|
||||
runner = create(:ci_runner, :group, groups: [group])
|
||||
|
||||
with_cross_joins_prevented do
|
||||
expect(runner.owner_runner_namespace.namespace_id).to eq(runner.groups.first.id)
|
||||
|
|
@ -43,7 +46,7 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
end
|
||||
|
||||
describe 'projects association' do
|
||||
let(:runner) { create(:ci_runner, :project) }
|
||||
let(:runner) { create(:ci_runner, :project, projects: [project]) }
|
||||
|
||||
it 'does not create a cross-database query' do
|
||||
with_cross_joins_prevented do
|
||||
|
|
@ -126,11 +129,10 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
end
|
||||
|
||||
describe '#exactly_one_group' do
|
||||
let(:group) { create(:group) }
|
||||
let(:runner) { create(:ci_runner, :group, groups: [group]) }
|
||||
|
||||
it 'disallows assigning group if already assigned to a group' do
|
||||
runner.runner_namespaces << create(:ci_runner_namespace)
|
||||
runner.runner_namespaces << create(:ci_runner_namespace, runner: runner)
|
||||
|
||||
expect(runner).not_to be_valid
|
||||
expect(runner.errors.full_messages).to include('Runner needs to be assigned to exactly one group')
|
||||
|
|
@ -138,11 +140,8 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
end
|
||||
|
||||
context 'runner_type validations' do
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
it 'disallows assigning group to project_type runner' do
|
||||
project_runner = build(:ci_runner, :project, groups: [group])
|
||||
project_runner = build(:ci_runner, :project, :without_projects, groups: [group])
|
||||
|
||||
expect(project_runner).not_to be_valid
|
||||
expect(project_runner.errors.full_messages).to include('Runner cannot have groups assigned')
|
||||
|
|
@ -222,7 +221,7 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
end
|
||||
|
||||
context 'when runner is not an instance type' do
|
||||
let(:runner) { create(:ci_runner, :group) }
|
||||
let(:runner) { create(:ci_runner, :group, groups: [group]) }
|
||||
|
||||
subject { runner.allowed_plan_ids = [default_plan.id] }
|
||||
|
||||
|
|
@ -269,8 +268,6 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
end
|
||||
|
||||
describe '.instance_type' do
|
||||
let(:group) { create(:group) }
|
||||
let(:project) { create(:project) }
|
||||
let!(:group_runner) { create(:ci_runner, :group, groups: [group]) }
|
||||
let!(:project_runner) { create(:ci_runner, :project, projects: [project]) }
|
||||
let!(:shared_runner) { create(:ci_runner, :instance) }
|
||||
|
|
@ -436,8 +433,7 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
end
|
||||
|
||||
describe '#only_for' do
|
||||
let_it_be_with_reload(:runner) { create(:ci_runner, :project) }
|
||||
let_it_be(:project) { runner.projects.first }
|
||||
let_it_be_with_reload(:runner) { create(:ci_runner, :project, projects: [project]) }
|
||||
|
||||
subject { runner.only_for?(project) }
|
||||
|
||||
|
|
@ -460,15 +456,15 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
end
|
||||
|
||||
describe '#assign_to' do
|
||||
let(:project) { create(:project) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
|
||||
subject { runner.assign_to(project) }
|
||||
subject(:assign_to) { runner.assign_to(project) }
|
||||
|
||||
context 'with shared_runner' do
|
||||
context 'with instance runner' do
|
||||
let(:runner) { create(:ci_runner, :instance) }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject }
|
||||
expect { assign_to }
|
||||
.to raise_error(ArgumentError, 'Transitioning an instance runner to a project runner is not supported')
|
||||
end
|
||||
end
|
||||
|
|
@ -478,17 +474,18 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
let(:runner) { create(:ci_runner, :group, groups: [group]) }
|
||||
|
||||
it 'raises an error' do
|
||||
expect { subject }
|
||||
expect { assign_to }
|
||||
.to raise_error(ArgumentError, 'Transitioning a group runner to a project runner is not supported')
|
||||
end
|
||||
end
|
||||
|
||||
context 'with project runner' do
|
||||
let(:other_project) { create(:project) }
|
||||
let_it_be(:other_project) { create(:project) }
|
||||
|
||||
let(:runner) { create(:ci_runner, :project, projects: [other_project]) }
|
||||
|
||||
it 'assigns runner to project' do
|
||||
expect(subject).to be_truthy
|
||||
expect(assign_to).to be_truthy
|
||||
|
||||
expect(runner).to be_project_type
|
||||
expect(runner.runner_projects.pluck(:project_id)).to contain_exactly(project.id, other_project.id)
|
||||
|
|
@ -1343,7 +1340,7 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
context 'deduplicates on runner_type' do
|
||||
before do
|
||||
create_list(:ci_runner, 2, :instance)
|
||||
create_list(:ci_runner, 2, :project)
|
||||
create_list(:ci_runner, 2, :project, projects: [project])
|
||||
end
|
||||
|
||||
it 'creates two matchers' do
|
||||
|
|
@ -2054,7 +2051,7 @@ RSpec.describe Ci::Runner, type: :model, feature_category: :runner do
|
|||
subject { described_class.with_runner_type(runner_type) }
|
||||
|
||||
let_it_be(:instance_runner) { create(:ci_runner, :instance) }
|
||||
let_it_be(:group_runner) { create(:ci_runner, :group) }
|
||||
let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) }
|
||||
let_it_be(:project_runner) { create(:ci_runner, :project, :without_projects) }
|
||||
|
||||
context 'with instance_type' do
|
||||
|
|
|
|||
|
|
@ -8555,12 +8555,15 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr
|
|||
end
|
||||
|
||||
shared_examples 'all_runners' do
|
||||
let_it_be_with_refind(:project) { create(:project, group: create(:group)) }
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be_with_refind(:project) { create(:project, group: group) }
|
||||
let_it_be(:other_group) { create(:group) }
|
||||
let_it_be(:other_project) { create(:project) }
|
||||
let_it_be(:instance_runner) { create(:ci_runner, :instance) }
|
||||
let_it_be(:group_runner) { create(:ci_runner, :group, groups: [project.group]) }
|
||||
let_it_be(:other_group_runner) { create(:ci_runner, :group) }
|
||||
let_it_be(:group_runner) { create(:ci_runner, :group, groups: [group]) }
|
||||
let_it_be(:other_group_runner) { create(:ci_runner, :group, groups: [other_group]) }
|
||||
let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) }
|
||||
let_it_be(:other_project_runner) { create(:ci_runner, :project) }
|
||||
let_it_be(:other_project_runner) { create(:ci_runner, :project, projects: [other_project]) }
|
||||
|
||||
subject { project.all_runners }
|
||||
|
||||
|
|
|
|||
|
|
@ -439,8 +439,8 @@ RSpec.describe API::Ci::Runners, :aggregate_failures, feature_category: :fleet_v
|
|||
|
||||
describe 'with ci_runner_machines' do
|
||||
before_all do
|
||||
version_ci_runner = create(:ci_runner, :project, description: 'Runner with machine')
|
||||
version_16_ci_runner = create(:ci_runner, :project, description: 'Runner with machine version 16')
|
||||
version_ci_runner = create(:ci_runner, description: 'Runner with machine')
|
||||
version_16_ci_runner = create(:ci_runner, description: 'Runner with machine version 16')
|
||||
create(:ci_runner_machine, runner: version_ci_runner, version: '15.0.3')
|
||||
create(:ci_runner_machine, runner: version_16_ci_runner, version: '16.0.1')
|
||||
end
|
||||
|
|
@ -2319,7 +2319,9 @@ RSpec.describe API::Ci::Runners, :aggregate_failures, feature_category: :fleet_v
|
|||
end
|
||||
|
||||
context 'user is not admin and does not have access to project runner' do
|
||||
let!(:new_project_runner) { create(:ci_runner, :project) }
|
||||
let_it_be(:project3) { create(:project) }
|
||||
let_it_be(:new_project_runner) { create(:ci_runner, :project, projects: [project3]) }
|
||||
|
||||
let(:runner) { new_project_runner }
|
||||
let(:current_user) { user }
|
||||
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@ RSpec.describe 'Query.runner(id)', :freeze_time, feature_category: :fleet_visibi
|
|||
let_it_be_with_refind(:project_runner) do
|
||||
create(
|
||||
:ci_runner, :project, :paused, :offline,
|
||||
projects: [project1],
|
||||
description: 'Runner 3',
|
||||
locked: false,
|
||||
access_level: 1,
|
||||
|
|
@ -702,7 +703,7 @@ RSpec.describe 'Query.runner(id)', :freeze_time, feature_category: :fleet_visibi
|
|||
describe 'for multiple runners' do
|
||||
let_it_be(:project2) { create(:project, :test_repo) }
|
||||
let_it_be(:project_runner1) { create(:ci_runner, :project, projects: [project1, project2], description: 'Runner 1') }
|
||||
let_it_be(:project_runner2) { create(:ci_runner, :project, projects: [], description: 'Runner 2') }
|
||||
let_it_be(:project_runner2) { create(:ci_runner, :project, :without_projects, description: 'Runner 2') }
|
||||
|
||||
let!(:job) { create(:ci_build, runner: project_runner1) }
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ RSpec.describe 'Query.runners', feature_category: :fleet_visibility do
|
|||
def create_ci_runner(version:, revision: nil, ip_address: nil, **args)
|
||||
runner_manager_args = { version: version, revision: revision, ip_address: ip_address }.compact
|
||||
|
||||
create(:ci_runner, :project, **args).tap do |runner|
|
||||
create(:ci_runner, **args).tap do |runner|
|
||||
create(:ci_runner_machine, runner: runner, **runner_manager_args)
|
||||
end
|
||||
end
|
||||
|
|
@ -186,7 +186,7 @@ RSpec.describe 'Query.runners', feature_category: :fleet_visibility do
|
|||
|
||||
context 'when filtered by creator' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:runner_created_by_user) { create(:ci_runner, :project, creator: user) }
|
||||
let_it_be(:runner_created_by_user) { create(:ci_runner, creator: user) }
|
||||
|
||||
let(:query) do
|
||||
%(
|
||||
|
|
@ -202,7 +202,7 @@ RSpec.describe 'Query.runners', feature_category: :fleet_visibility do
|
|||
let(:creator) { user }
|
||||
|
||||
before do
|
||||
create(:ci_runner, :project, creator: create(:user)) # Should not be returned
|
||||
create(:ci_runner, creator: create(:user)) # Should not be returned
|
||||
end
|
||||
|
||||
it_behaves_like 'a working graphql query returning expected runners' do
|
||||
|
|
|
|||
Loading…
Reference in New Issue