Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-09-30 06:15:32 +00:00
parent 8d49a2afd7
commit c4478b724a
17 changed files with 83 additions and 65 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -64883,9 +64883,7 @@ msgid "function name"
msgstr ""
msgid "group"
msgid_plural "groups"
msgstr[0] ""
msgstr[1] ""
msgstr ""
msgid "group access token"
msgstr ""

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 }

View File

@ -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 }

View File

@ -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) }

View File

@ -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