diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-12 00:09:00 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-02-12 00:09:00 +0300 |
commit | bf217da41b429d80da49287b84dadcbf499ac22c (patch) | |
tree | b3499733d7e1abb88a3f0975333c85d00a80fd96 /app | |
parent | 559d99e40299e67969023a1afd23d084fbf23ed1 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
17 files changed, 132 insertions, 159 deletions
diff --git a/app/assets/javascripts/jobs/components/empty_state.vue b/app/assets/javascripts/jobs/components/empty_state.vue index 0ee8cd6c5ad..35b16d73cc7 100644 --- a/app/assets/javascripts/jobs/components/empty_state.vue +++ b/app/assets/javascripts/jobs/components/empty_state.vue @@ -85,7 +85,7 @@ export default { <gl-link :href="action.path" :data-method="action.method" - class="btn btn-primary" + class="btn gl-button btn-confirm gl-text-decoration-none!" data-testid="job-empty-state-action" >{{ action.button_title }}</gl-link > diff --git a/app/assets/javascripts/jobs/components/sidebar.vue b/app/assets/javascripts/jobs/components/sidebar.vue index 83eddc232a1..c51a3f459c7 100644 --- a/app/assets/javascripts/jobs/components/sidebar.vue +++ b/app/assets/javascripts/jobs/components/sidebar.vue @@ -46,9 +46,9 @@ export default { ...mapGetters(['hasForwardDeploymentFailure']), ...mapState(['job', 'stages', 'jobs', 'selectedStage']), retryButtonClass() { - let className = 'btn btn-retry'; + let className = 'btn gl-button gl-text-decoration-none!'; className += - this.job.status && this.job.recoverable ? ' btn-primary' : ' btn-inverted-secondary'; + this.job.status && this.job.recoverable ? ' btn-confirm' : ' btn-confirm-secondary'; return className; }, hasArtifact() { @@ -94,7 +94,7 @@ export default { <gl-link v-if="job.cancel_path" :href="job.cancel_path" - class="btn btn-default" + class="btn gl-button btn-default gl-text-decoration-none!" data-method="post" data-testid="cancel-button" rel="nofollow" @@ -115,7 +115,7 @@ export default { <gl-link v-if="job.new_issue_path" :href="job.new_issue_path" - class="btn btn-success btn-inverted float-left mr-2" + class="btn gl-button btn-success-secondary float-left mr-2 gl-text-decoration-none!" data-testid="job-new-issue" >{{ $options.i18n.newIssue }} </gl-link> diff --git a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue index 232de605e07..85789cd1fdf 100644 --- a/app/assets/javascripts/performance_bar/components/performance_bar_app.vue +++ b/app/assets/javascripts/performance_bar/components/performance_bar_app.vue @@ -30,10 +30,6 @@ export default { type: String, required: true, }, - statsUrl: { - type: String, - required: true, - }, }, detailedMetrics: [ { @@ -173,9 +169,6 @@ export default { class="ml-auto" @change-current-request="changeCurrentRequest" /> - <div v-if="statsUrl" id="peek-stats" class="view"> - <a class="gl-text-blue-300" :href="statsUrl">{{ s__('PerformanceBar|Stats') }}</a> - </div> </div> </div> </template> diff --git a/app/assets/javascripts/performance_bar/index.js b/app/assets/javascripts/performance_bar/index.js index 9a9b4325fee..0d5c294ea56 100644 --- a/app/assets/javascripts/performance_bar/index.js +++ b/app/assets/javascripts/performance_bar/index.js @@ -30,7 +30,6 @@ const initPerformanceBar = (el) => { requestId: performanceBarData.requestId, peekUrl: performanceBarData.peekUrl, profileUrl: performanceBarData.profileUrl, - statsUrl: performanceBarData.statsUrl, }; }, mounted() { @@ -121,7 +120,6 @@ const initPerformanceBar = (el) => { requestId: this.requestId, peekUrl: this.peekUrl, profileUrl: this.profileUrl, - statsUrl: this.statsUrl, }, on: { 'add-request': this.addRequestManually, diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue index 5231fe0b112..9fdba93f50a 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue @@ -12,11 +12,6 @@ import PipelineUrl from './pipeline_url.vue'; import PipelineTriggerer from './pipeline_triggerer.vue'; import PipelinesTimeago from './time_ago.vue'; -/** - * Pipeline table row. - * - * Given the received object renders a table row in the pipelines' table. - */ export default { i18n: { cancelTitle: __('Cancel'), @@ -127,116 +122,30 @@ export default { return commitAuthorInformation; }, - - /** - * If provided, returns the commit tag. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ commitTag() { - if (this.pipeline.ref && this.pipeline.ref.tag) { - return this.pipeline.ref.tag; - } - return undefined; + return this.pipeline?.ref?.tag; }, - - /** - * If provided, returns the commit ref. - * Needed to render the commit component column. - * - * Matches `path` prop sent in the API to `ref_url` prop needed - * in the commit component. - * - * @returns {Object|Undefined} - */ commitRef() { - if (this.pipeline.ref) { - return Object.keys(this.pipeline.ref).reduce((accumulator, prop) => { - if (prop === 'path') { - accumulator.ref_url = this.pipeline.ref[prop]; - } else { - accumulator[prop] = this.pipeline.ref[prop]; - } - return accumulator; - }, {}); - } - - return undefined; + return this.pipeline?.ref; }, - - /** - * If provided, returns the commit url. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ commitUrl() { - if (this.pipeline.commit && this.pipeline.commit.commit_path) { - return this.pipeline.commit.commit_path; - } - return undefined; + return this.pipeline?.commit?.commit_path; }, - - /** - * If provided, returns the commit short sha. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ commitShortSha() { - if (this.pipeline.commit && this.pipeline.commit.short_id) { - return this.pipeline.commit.short_id; - } - return undefined; + return this.pipeline?.commit?.short_id; }, - - /** - * If provided, returns the commit title. - * Needed to render the commit component column. - * - * @returns {String|Undefined} - */ commitTitle() { - if (this.pipeline.commit && this.pipeline.commit.title) { - return this.pipeline.commit.title; - } - return undefined; + return this.pipeline?.commit?.title; }, - - /** - * Timeago components expects a number - * - * @return {type} description - */ pipelineDuration() { - if (this.pipeline.details && this.pipeline.details.duration) { - return this.pipeline.details.duration; - } - - return 0; + return this.pipeline?.details?.duration ?? 0; }, - - /** - * Timeago component expects a String. - * - * @return {String} - */ pipelineFinishedAt() { - if (this.pipeline.details && this.pipeline.details.finished_at) { - return this.pipeline.details.finished_at; - } - - return ''; + return this.pipeline?.details?.finished_at ?? ''; }, - pipelineStatus() { - if (this.pipeline.details && this.pipeline.details.status) { - return this.pipeline.details.status; - } - return {}; + return this.pipeline?.details?.status ?? {}; }, - displayPipelineActions() { return ( this.pipeline.flags.retryable || @@ -245,11 +154,9 @@ export default { this.pipeline.details.artifacts.length ); }, - isChildView() { return this.viewType === 'child'; }, - isCancelling() { return this.cancelingPipeline === this.pipeline.id; }, @@ -355,7 +262,7 @@ export default { :title="$options.i18n.redeployTitle" :disabled="isRetrying" :loading="isRetrying" - class="js-pipelines-retry-button btn-retry" + class="js-pipelines-retry-button" data-qa-selector="pipeline_retry_button" icon="repeat" variant="default" diff --git a/app/assets/javascripts/vue_shared/components/commit.vue b/app/assets/javascripts/vue_shared/components/commit.vue index deca934e283..27f136059fa 100644 --- a/app/assets/javascripts/vue_shared/components/commit.vue +++ b/app/assets/javascripts/vue_shared/components/commit.vue @@ -133,6 +133,9 @@ export default { ? sprintf(__("%{username}'s avatar"), { username: this.author.username }) : null; }, + refUrl() { + return this.commitRef.ref_url || this.commitRef.path; + }, }, }; </script> @@ -156,9 +159,10 @@ export default { <gl-link v-else v-gl-tooltip - :href="commitRef.ref_url" + :href="refUrl" :title="commitRef.name" class="ref-name" + data-testid="ref-name" >{{ commitRef.name }}</gl-link > </template> diff --git a/app/controllers/help_controller.rb b/app/controllers/help_controller.rb index 5a5200452de..e995562f0c4 100644 --- a/app/controllers/help_controller.rb +++ b/app/controllers/help_controller.rb @@ -84,7 +84,16 @@ class HelpController < ApplicationController end def documentation_base_url - @documentation_base_url ||= Gitlab::CurrentSettings.current_application_settings.help_page_documentation_base_url.presence + @documentation_base_url ||= documentation_base_url_from_yml_configuration || documentation_base_url_from_db + end + + # DEPRECATED + def documentation_base_url_from_db + Gitlab::CurrentSettings.current_application_settings.help_page_documentation_base_url.presence + end + + def documentation_base_url_from_yml_configuration + ::Gitlab.config.gitlab_docs.host.presence if ::Gitlab.config.gitlab_docs.enabled end def documentation_file_path diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index c8bdbe548c8..2816977277a 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -145,9 +145,6 @@ class Projects::IssuesController < Projects::ApplicationController format.html do recaptcha_check_with_fallback { render :new } end - format.js do - @link = @issue.attachment.url.to_js - end end end diff --git a/app/graphql/types/event_action_enum.rb b/app/graphql/types/event_action_enum.rb new file mode 100644 index 00000000000..79931fa48cb --- /dev/null +++ b/app/graphql/types/event_action_enum.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Types + class EventActionEnum < BaseEnum + graphql_name 'EventAction' + description 'Event action' + + ::Event.actions.keys.each do |target_type| + value target_type.upcase, value: target_type, description: "#{target_type.titleize} action" + end + end +end diff --git a/app/graphql/types/event_type.rb b/app/graphql/types/event_type.rb new file mode 100644 index 00000000000..2a4c2e7c60a --- /dev/null +++ b/app/graphql/types/event_type.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Types + class EventType < BaseObject + graphql_name 'Event' + description 'Representing an event' + + present_using EventPresenter + + authorize :read_event + + field :id, GraphQL::ID_TYPE, + description: 'ID of the event.', + null: false + + field :author, Types::UserType, + description: 'Author of this event.', + null: false + + field :action, Types::EventActionEnum, + description: 'Action of the event.', + null: false + + field :created_at, Types::TimeType, + description: 'When this event was created.', + null: false + + field :updated_at, Types::TimeType, + description: 'When this event was updated.', + null: false + + def author + Gitlab::Graphql::Loaders::BatchModelLoader.new(User, object.author_id).find + end + end +end diff --git a/app/graphql/types/eventable_type.rb b/app/graphql/types/eventable_type.rb new file mode 100644 index 00000000000..eba2154e7fa --- /dev/null +++ b/app/graphql/types/eventable_type.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module Types + module EventableType + include Types::BaseInterface + + field :events, Types::EventType.connection_type, null: true, description: 'A list of events associated with the object.' + end +end diff --git a/app/models/concerns/enums/ci/pipeline.rb b/app/models/concerns/enums/ci/pipeline.rb index e1f07fa162c..e1cf579eefc 100644 --- a/app/models/concerns/enums/ci/pipeline.rb +++ b/app/models/concerns/enums/ci/pipeline.rb @@ -10,6 +10,9 @@ module Enums unknown_failure: 0, config_error: 1, external_validation_failure: 2, + activity_limit_exceeded: 20, + size_limit_exceeded: 21, + job_activity_limit_exceeded: 22, deployments_limit_exceeded: 23 } end @@ -77,5 +80,3 @@ module Enums end end end - -Enums::Ci::Pipeline.prepend_if_ee('EE::Enums::Ci::Pipeline') diff --git a/app/policies/event_policy.rb b/app/policies/event_policy.rb new file mode 100644 index 00000000000..5587956855e --- /dev/null +++ b/app/policies/event_policy.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +class EventPolicy < BasePolicy # rubocop:disable Gitlab/NamespacedClass + condition(:visible_to_user) do + subject.visible_to_user?(user) + end + + rule { visible_to_user }.enable :read_event +end diff --git a/app/services/pages/migrate_from_legacy_storage_service.rb b/app/services/pages/migrate_from_legacy_storage_service.rb index d805ae2418c..9b36b3f11b4 100644 --- a/app/services/pages/migrate_from_legacy_storage_service.rb +++ b/app/services/pages/migrate_from_legacy_storage_service.rb @@ -2,10 +2,11 @@ module Pages class MigrateFromLegacyStorageService - def initialize(logger, migration_threads, batch_size) + def initialize(logger, migration_threads:, batch_size:, ignore_invalid_entries:) @logger = logger @migration_threads = migration_threads @batch_size = batch_size + @ignore_invalid_entries = ignore_invalid_entries @migrated = 0 @errored = 0 @@ -59,19 +60,19 @@ module Pages def migrate_project(project) result = nil time = Benchmark.realtime do - result = ::Pages::MigrateLegacyStorageToDeploymentService.new(project).execute + result = ::Pages::MigrateLegacyStorageToDeploymentService.new(project, ignore_invalid_entries: @ignore_invalid_entries).execute end if result[:status] == :success - @logger.info("project_id: #{project.id} #{project.pages_path} has been migrated in #{time} seconds") + @logger.info("project_id: #{project.id} #{project.pages_path} has been migrated in #{time.round(2)} seconds") @counters_lock.synchronize { @migrated += 1 } else - @logger.error("project_id: #{project.id} #{project.pages_path} failed to be migrated in #{time} seconds: #{result[:message]}") + @logger.error("project_id: #{project.id} #{project.pages_path} failed to be migrated in #{time.round(2)} seconds: #{result[:message]}") @counters_lock.synchronize { @errored += 1 } end rescue => e @counters_lock.synchronize { @errored += 1 } - @logger.error("#{e.message} project_id: #{project&.id}") + @logger.error("project_id: #{project&.id} #{project&.pages_path} failed to be migrated: #{e.message}") Gitlab::ErrorTracking.track_exception(e, project_id: project&.id) end end diff --git a/app/services/pages/migrate_legacy_storage_to_deployment_service.rb b/app/services/pages/migrate_legacy_storage_to_deployment_service.rb index dac994b2ccc..63410b9fe4a 100644 --- a/app/services/pages/migrate_legacy_storage_to_deployment_service.rb +++ b/app/services/pages/migrate_legacy_storage_to_deployment_service.rb @@ -9,8 +9,9 @@ module Pages attr_reader :project - def initialize(project) + def initialize(project, ignore_invalid_entries: false) @project = project + @ignore_invalid_entries = ignore_invalid_entries end def execute @@ -26,7 +27,7 @@ module Pages private def execute_unsafe - zip_result = ::Pages::ZipDirectoryService.new(project.pages_path).execute + zip_result = ::Pages::ZipDirectoryService.new(project.pages_path, ignore_invalid_entries: @ignore_invalid_entries).execute if zip_result[:status] == :error if !project.pages_metadatum&.reload&.pages_deployment && diff --git a/app/services/pages/zip_directory_service.rb b/app/services/pages/zip_directory_service.rb index ba7a8571e88..ae08d40ee37 100644 --- a/app/services/pages/zip_directory_service.rb +++ b/app/services/pages/zip_directory_service.rb @@ -10,12 +10,17 @@ module Pages PUBLIC_DIR = 'public' - def initialize(input_dir) + attr_reader :public_dir, :real_dir + + def initialize(input_dir, ignore_invalid_entries: false) @input_dir = input_dir + @ignore_invalid_entries = ignore_invalid_entries end def execute - return error("Can not find valid public dir in #{@input_dir}") unless valid_path?(public_dir) + unless resolve_public_dir + return error("Can not find valid public dir in #{@input_dir}") + end output_file = File.join(real_dir, "@migrated.zip") # '@' to avoid any name collision with groups or projects @@ -35,24 +40,36 @@ module Pages private + def resolve_public_dir + @real_dir = File.realpath(@input_dir) + @public_dir = File.join(real_dir, PUBLIC_DIR) + + valid_path?(public_dir) + rescue Errno::ENOENT + false + end + def write_entry(zipfile, zipfile_path) disk_file_path = File.join(real_dir, zipfile_path) unless valid_path?(disk_file_path) # archive with invalid entry will just have this entry missing - raise InvalidEntryError + raise InvalidEntryError, "#{disk_file_path} is invalid, input_dir: #{@input_dir}" end - case File.lstat(disk_file_path).ftype + ftype = File.lstat(disk_file_path).ftype + case ftype when 'directory' recursively_zip_directory(zipfile, disk_file_path, zipfile_path) when 'file', 'link' zipfile.add(zipfile_path, disk_file_path) else - raise InvalidEntryError + raise InvalidEntryError, "#{disk_file_path} has invalid ftype: #{ftype}, input_dir: #{@input_dir}" end - rescue InvalidEntryError => e + rescue Errno::ENOENT, Errno::ELOOP, InvalidEntryError => e Gitlab::ErrorTracking.track_exception(e, input_dir: @input_dir, disk_file_path: disk_file_path) + + raise e unless @ignore_invalid_entries end def recursively_zip_directory(zipfile, disk_file_path, zipfile_path) @@ -70,31 +87,11 @@ module Pages end end - # that should never happen, but we want to be safer - # in theory without this we would allow to use symlinks - # to pack any directory on disk - # it isn't possible because SafeZip doesn't extract such archives + # SafeZip was introduced only recently, + # so we have invalid entries on disk def valid_path?(disk_file_path) realpath = File.realpath(disk_file_path) - realpath == public_dir || realpath.start_with?(public_dir + "/") - # happens if target of symlink isn't there - rescue => e - Gitlab::ErrorTracking.track_exception(e, input_dir: real_dir, disk_file_path: disk_file_path) - - false - end - - def real_dir - strong_memoize(:real_dir) do - File.realpath(@input_dir) rescue nil - end - end - - def public_dir - strong_memoize(:public_dir) do - File.join(real_dir, PUBLIC_DIR) rescue nil - end end end end diff --git a/app/views/peek/_bar.html.haml b/app/views/peek/_bar.html.haml index 8914bfab336..9725f640be9 100644 --- a/app/views/peek/_bar.html.haml +++ b/app/views/peek/_bar.html.haml @@ -2,6 +2,5 @@ #js-peek{ data: { env: Peek.env, request_id: peek_request_id, - stats_url: ENV.fetch('GITLAB_PERFORMANCE_BAR_STATS_URL', ''), peek_url: "#{peek_routes_path}/results" }, class: Peek.env } |