diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-13 03:19:10 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-04-13 03:19:10 +0300 |
commit | fa1b90364dc73f27dc78b9d27114e4a197f2cfcb (patch) | |
tree | f72d9e2a7355687d977bfe0c01bdb42238e98d27 /app | |
parent | ac48f7c24110a7a1e0a0aa49fc7838ab03c28374 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
16 files changed, 212 insertions, 53 deletions
diff --git a/app/assets/javascripts/ci/runner/components/runner_create_form.vue b/app/assets/javascripts/ci/runner/components/runner_create_form.vue index 5d2a3c53842..2bad08b4f48 100644 --- a/app/assets/javascripts/ci/runner/components/runner_create_form.vue +++ b/app/assets/javascripts/ci/runner/components/runner_create_form.vue @@ -4,7 +4,7 @@ import RunnerFormFields from '~/ci/runner/components/runner_form_fields.vue'; import runnerCreateMutation from '~/ci/runner/graphql/new/runner_create.mutation.graphql'; import { modelToUpdateMutationVariables } from 'ee_else_ce/ci/runner/runner_update_form_utils'; import { captureException } from '../sentry_utils'; -import { DEFAULT_ACCESS_LEVEL } from '../constants'; +import { DEFAULT_ACCESS_LEVEL, INSTANCE_TYPE } from '../constants'; export default { name: 'RunnerCreateForm', @@ -17,6 +17,7 @@ export default { return { saving: false, runner: { + runnerType: INSTANCE_TYPE, description: '', maintenanceNote: '', paused: false, diff --git a/app/assets/javascripts/members/components/table/role_dropdown.vue b/app/assets/javascripts/members/components/table/role_dropdown.vue index e066b023fbb..a85bb09e17b 100644 --- a/app/assets/javascripts/members/components/table/role_dropdown.vue +++ b/app/assets/javascripts/members/components/table/role_dropdown.vue @@ -81,19 +81,18 @@ export default { return; } - this.updateMemberRole({ - memberId: this.member.id, - accessLevel: { integerValue: newRoleValue, stringValue: newRoleName }, - }) - .then(() => { - this.$toast.show(s__('Members|Role updated successfully.')); - }) - .catch((error) => { - Sentry.captureException(error); - }) - .finally(() => { - this.busy = false; + try { + await this.updateMemberRole({ + memberId: this.member.id, + accessLevel: { integerValue: newRoleValue, stringValue: newRoleName }, }); + + this.$toast.show(s__('Members|Role updated successfully.')); + } catch (error) { + Sentry.captureException(error); + } finally { + this.busy = false; + } }, }, }; diff --git a/app/assets/javascripts/repository/components/blob_content_viewer.vue b/app/assets/javascripts/repository/components/blob_content_viewer.vue index 236351005e7..60df042529a 100644 --- a/app/assets/javascripts/repository/components/blob_content_viewer.vue +++ b/app/assets/javascripts/repository/components/blob_content_viewer.vue @@ -34,6 +34,7 @@ export default { ForkSuggestion, WebIdeLink, CodeIntelligence, + AiGenie: () => import('ee_component/ai/components/ai_genie.vue'), }, mixins: [getRefMixin, glFeatureFlagMixin()], inject: { @@ -142,6 +143,9 @@ export default { }; }, computed: { + shouldRenderGenie() { + return this.glFeatures.explainCode && this.glFeatures.explainCodeSnippet; + }, isLoggedIn() { return isLoggedIn(); }, @@ -316,9 +320,9 @@ export default { </script> <template> - <div> + <div class="gl-relative"> <gl-loading-icon v-if="isLoading" size="sm" /> - <div v-if="blobInfo && !isLoading" class="file-holder"> + <div v-if="blobInfo && !isLoading" id="fileHolder" class="file-holder"> <blob-header :blob="blobInfo" :hide-viewer-switcher="!hasRichViewer || isBinaryFileType || isUsingLfs" @@ -393,5 +397,11 @@ export default { :wrap-text-nodes="glFeatures.highlightJs" /> </div> + <ai-genie + v-if="shouldRenderGenie" + container-id="fileHolder" + :file-path="path" + class="gl-ml-7" + /> </div> </template> diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue b/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue index 1690e666d3c..f121e84e1de 100644 --- a/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue +++ b/app/assets/javascripts/vue_shared/components/source_viewer/components/chunk_line.vue @@ -38,7 +38,7 @@ export default { class="gl-p-0! gl-absolute gl-z-index-3 diff-line-num gl-border-r gl-display-flex line-links line-numbers" > <a - class="gl-user-select-none gl-shadow-none! file-line-blame" + class="gl-user-select-none gl-shadow-none! file-line-blame gl-mx-n2 gl-flex-grow-1" :href="`${blamePath}${pageSearchString}#L${number}`" ></a> <a diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index 0631c02355e..367417ba840 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -19,6 +19,8 @@ class Projects::TreeController < Projects::ApplicationController before_action do push_frontend_feature_flag(:highlight_js, @project) push_frontend_feature_flag(:synchronize_fork, @project.fork_source) + push_frontend_feature_flag(:explain_code_snippet, current_user) + push_licensed_feature(:explain_code, @project) if @project.licensed_feature_available?(:explain_code) push_licensed_feature(:file_locks) if @project.licensed_feature_available?(:file_locks) end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index a6bc754d09e..be30255ec4e 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -39,8 +39,10 @@ class ProjectsController < Projects::ApplicationController before_action do push_frontend_feature_flag(:highlight_js, @project) push_frontend_feature_flag(:synchronize_fork, @project&.fork_source) + push_frontend_feature_flag(:explain_code_snippet, current_user) push_licensed_feature(:file_locks) if @project.present? && @project.licensed_feature_available?(:file_locks) push_licensed_feature(:security_orchestration_policies) if @project.present? && @project.licensed_feature_available?(:security_orchestration_policies) + push_licensed_feature(:explain_code, @project) if @project.present? && @project.licensed_feature_available?(:explain_code) push_force_frontend_feature_flag(:work_items, @project&.work_items_feature_flag_enabled?) push_force_frontend_feature_flag(:work_items_mvc, @project&.work_items_mvc_feature_flag_enabled?) push_force_frontend_feature_flag(:work_items_mvc_2, @project&.work_items_mvc_2_feature_flag_enabled?) diff --git a/app/graphql/mutations/ci/runner/common_mutation_arguments.rb b/app/graphql/mutations/ci/runner/common_mutation_arguments.rb index bfeed4881c6..f4fbd0a38c7 100644 --- a/app/graphql/mutations/ci/runner/common_mutation_arguments.rb +++ b/app/graphql/mutations/ci/runner/common_mutation_arguments.rb @@ -38,11 +38,6 @@ module Mutations argument :tag_list, [GraphQL::Types::String], required: false, description: 'Tags associated with the runner.' - - argument :associated_projects, [::Types::GlobalIDType[::Project]], - required: false, - description: 'Projects associated with the runner. Available only for project runners.', - prepare: ->(global_ids, _ctx) { global_ids&.filter_map { |gid| gid.model_id.to_i } } end end end diff --git a/app/graphql/mutations/ci/runner/create.rb b/app/graphql/mutations/ci/runner/create.rb index 98300ee4c38..7eca6c27d10 100644 --- a/app/graphql/mutations/ci/runner/create.rb +++ b/app/graphql/mutations/ci/runner/create.rb @@ -10,25 +10,49 @@ module Mutations include Mutations::Ci::Runner::CommonMutationArguments + argument :runner_type, ::Types::Ci::RunnerTypeEnum, + required: true, + description: 'Type of the runner to create.' + + argument :group_id, ::Types::GlobalIDType[Group], + required: false, + description: 'Global ID of the group that the runner is created in (valid only for group runner).' + + argument :project_id, ::Types::GlobalIDType[Project], + required: false, + description: 'Global ID of the project that the runner is created in (valid only for project runner).' + field :runner, Types::Ci::RunnerType, null: true, description: 'Runner after mutation.' - def resolve(**args) - if Feature.disabled?(:create_runner_workflow_for_admin, current_user) - raise Gitlab::Graphql::Errors::ResourceNotAvailable, - '`create_runner_workflow_for_admin` feature flag is disabled.' + def ready?(**args) + case args[:runner_type] + when 'group_type' + raise Gitlab::Graphql::Errors::ArgumentError, '`group_id` is missing' unless args[:group_id].present? + when 'project_type' + raise Gitlab::Graphql::Errors::ArgumentError, '`project_id` is missing' unless args[:project_id].present? end - create_runner(args) + parse_gid(**args) + + check_feature_flag(**args) + + super end - private + def resolve(**args) + case args[:runner_type] + when 'group_type', 'project_type' + args[:scope] = authorized_find!(**args) + args.except!(:group_id, :project_id) + else + raise_resource_not_available_error! unless current_user.can?(:create_instance_runner) + end - def create_runner(params) response = { runner: nil, errors: [] } - result = ::Ci::Runners::CreateRunnerService.new(user: current_user, type: nil, params: params).execute + result = ::Ci::Runners::CreateRunnerService.new(user: current_user, params: args).execute if result.success? response[:runner] = result.payload[:runner] @@ -38,6 +62,45 @@ module Mutations response end + + private + + def find_object(**args) + obj = parse_gid(**args) + + GitlabSchema.find_by_gid(obj) if obj + end + + def parse_gid(runner_type:, **args) + case runner_type + when 'group_type' + GitlabSchema.parse_gid(args[:group_id], expected_type: ::Group) + when 'project_type' + GitlabSchema.parse_gid(args[:project_id], expected_type: ::Project) + end + end + + def check_feature_flag(**args) + case args[:runner_type] + when 'instance_type' + if Feature.disabled?(:create_runner_workflow_for_admin, current_user) + raise Gitlab::Graphql::Errors::ResourceNotAvailable, + '`create_runner_workflow_for_admin` feature flag is disabled.' + end + when 'group_type' + namespace = find_object(**args).sync + if Feature.disabled?(:create_runner_workflow_for_namespace, namespace) + raise Gitlab::Graphql::Errors::ResourceNotAvailable, + '`create_runner_workflow_for_namespace` feature flag is disabled.' + end + when 'project_type' + project = find_object(**args).sync + if project && Feature.disabled?(:create_runner_workflow_for_namespace, project.namespace) + raise Gitlab::Graphql::Errors::ResourceNotAvailable, + '`create_runner_workflow_for_namespace` feature flag is disabled.' + end + end + end end end end diff --git a/app/graphql/mutations/ci/runner/update.rb b/app/graphql/mutations/ci/runner/update.rb index 00865b177a8..da28397bb71 100644 --- a/app/graphql/mutations/ci/runner/update.rb +++ b/app/graphql/mutations/ci/runner/update.rb @@ -21,6 +21,11 @@ module Mutations description: 'Indicates the runner is allowed to receive jobs.', deprecated: { reason: :renamed, replacement: 'paused', milestone: '14.8' } + argument :associated_projects, [::Types::GlobalIDType[::Project]], + required: false, + description: 'Projects associated with the runner. Available only for project runners.', + prepare: ->(global_ids, _ctx) { global_ids&.filter_map { |gid| gid.model_id.to_i } } + field :runner, Types::Ci::RunnerType, null: true, diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb index b64e7e16433..09e41e0bfbf 100644 --- a/app/policies/global_policy.rb +++ b/app/policies/global_policy.rb @@ -121,11 +121,11 @@ class GlobalPolicy < BasePolicy enable :approve_user enable :reject_user enable :read_usage_trends_measurement - enable :create_instance_runners + enable :create_instance_runner end rule { ~create_runner_workflow_enabled }.policy do - prevent :create_instance_runners + prevent :create_instance_runner end # We can't use `read_statistics` because the user may have different permissions for different projects diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb index 5d4f8478377..a285a8e361b 100644 --- a/app/policies/group_policy.rb +++ b/app/policies/group_policy.rb @@ -214,7 +214,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy enable :read_group_runners enable :admin_group_runners enable :register_group_runners - enable :create_group_runners + enable :create_runner enable :set_note_created_at enable :set_emails_disabled @@ -325,7 +325,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy rule { ~admin & ~group_runner_registration_allowed }.policy do prevent :register_group_runners - prevent :create_group_runners + prevent :create_runner end rule { migration_bot }.policy do @@ -342,7 +342,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy end rule { ~create_runner_workflow_enabled }.policy do - prevent :create_group_runners + prevent :create_runner end # Should be matched with ProjectPolicy#read_internal_note diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb index 95cdbd65055..5f743f3713e 100644 --- a/app/policies/project_policy.rb +++ b/app/policies/project_policy.rb @@ -535,7 +535,7 @@ class ProjectPolicy < BasePolicy enable :destroy_freeze_period enable :admin_feature_flags_client enable :register_project_runners - enable :create_project_runners + enable :create_runner enable :admin_project_runners enable :read_project_runners enable :update_runners_registration_token @@ -844,7 +844,7 @@ class ProjectPolicy < BasePolicy rule { ~admin & ~project_runner_registration_allowed }.policy do prevent :register_project_runners - prevent :create_project_runners + prevent :create_runner end rule { can?(:admin_project_member) }.policy do @@ -870,7 +870,7 @@ class ProjectPolicy < BasePolicy end rule { ~create_runner_workflow_enabled }.policy do - prevent :create_project_runners + prevent :create_runner end # Should be matched with GroupPolicy#read_internal_note diff --git a/app/services/ci/runners/create_runner_service.rb b/app/services/ci/runners/create_runner_service.rb index 5906cdce99d..fcb664500a9 100644 --- a/app/services/ci/runners/create_runner_service.rb +++ b/app/services/ci/runners/create_runner_service.rb @@ -5,23 +5,25 @@ module Ci class CreateRunnerService RUNNER_CLASS_MAPPING = { 'instance_type' => Ci::Runners::RunnerCreationStrategies::InstanceRunnerStrategy, - nil => Ci::Runners::RunnerCreationStrategies::InstanceRunnerStrategy + 'group_type' => Ci::Runners::RunnerCreationStrategies::GroupRunnerStrategy, + 'project_type' => Ci::Runners::RunnerCreationStrategies::ProjectRunnerStrategy }.freeze - attr_accessor :user, :type, :params, :strategy - - def initialize(user:, type:, params:) + def initialize(user:, params:) @user = user - @type = type @params = params - @strategy = RUNNER_CLASS_MAPPING[type].new(user: user, type: type, params: params) + @strategy = RUNNER_CLASS_MAPPING[params[:runner_type]].new(user: user, params: params) end def execute normalize_params - return ServiceResponse.error(message: 'Validation error') unless strategy.validate_params - return ServiceResponse.error(message: 'Insufficient permissions') unless strategy.authorized_user? + error = strategy.validate_params + return ServiceResponse.error(message: error, reason: :validation_error) if error + + unless strategy.authorized_user? + return ServiceResponse.error(message: _('Insufficient permissions'), reason: :forbidden) + end runner = ::Ci::Runner.new(params) @@ -32,12 +34,15 @@ module Ci def normalize_params params[:registration_type] = :authenticated_user - params[:runner_type] = type params[:active] = !params.delete(:paused) if params.key?(:paused) params[:creator] = user strategy.normalize_params end + + private + + attr_reader :user, :params, :strategy end end end diff --git a/app/services/ci/runners/runner_creation_strategies/group_runner_strategy.rb b/app/services/ci/runners/runner_creation_strategies/group_runner_strategy.rb new file mode 100644 index 00000000000..2eae5069046 --- /dev/null +++ b/app/services/ci/runners/runner_creation_strategies/group_runner_strategy.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Ci + module Runners + module RunnerCreationStrategies + class GroupRunnerStrategy + include Gitlab::Utils::StrongMemoize + + def initialize(user:, params:) + @user = user + @params = params + end + + def normalize_params + params[:runner_type] = 'group_type' + params[:groups] = [scope] + end + + def validate_params + _('Missing/invalid scope') unless scope.present? + end + + def authorized_user? + user.present? && user.can?(:create_runner, scope) + end + + private + + attr_reader :user, :params + + def scope + params.delete(:scope) + end + strong_memoize_attr :scope + end + end + end +end diff --git a/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb b/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb index f195c3e88f9..39719ad806f 100644 --- a/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb +++ b/app/services/ci/runners/runner_creation_strategies/instance_runner_strategy.rb @@ -4,25 +4,26 @@ module Ci module Runners module RunnerCreationStrategies class InstanceRunnerStrategy - attr_accessor :user, :type, :params - - def initialize(user:, type:, params:) + def initialize(user:, params:) @user = user - @type = type @params = params end def normalize_params - params[:runner_type] = :instance_type + params[:runner_type] = 'instance_type' end def validate_params - true + _('Unexpected scope') if params[:scope] end def authorized_user? - user.present? && user.can?(:create_instance_runners) + user.present? && user.can?(:create_instance_runner) end + + private + + attr_reader :user, :params end end end diff --git a/app/services/ci/runners/runner_creation_strategies/project_runner_strategy.rb b/app/services/ci/runners/runner_creation_strategies/project_runner_strategy.rb new file mode 100644 index 00000000000..487da996513 --- /dev/null +++ b/app/services/ci/runners/runner_creation_strategies/project_runner_strategy.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Ci + module Runners + module RunnerCreationStrategies + class ProjectRunnerStrategy + include Gitlab::Utils::StrongMemoize + + def initialize(user:, params:) + @user = user + @params = params + end + + def normalize_params + params[:runner_type] = 'project_type' + params[:projects] = [scope] + end + + def validate_params + _('Missing/invalid scope') unless scope.present? + end + + def authorized_user? + user.present? && user.can?(:create_runner, scope) + end + + private + + attr_reader :user, :params + + def scope + params.delete(:scope) + end + strong_memoize_attr :scope + end + end + end +end |