Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-02-12 00:09:00 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-02-12 00:09:00 +0300
commitbf217da41b429d80da49287b84dadcbf499ac22c (patch)
treeb3499733d7e1abb88a3f0975333c85d00a80fd96 /app
parent559d99e40299e67969023a1afd23d084fbf23ed1 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/jobs/components/empty_state.vue2
-rw-r--r--app/assets/javascripts/jobs/components/sidebar.vue8
-rw-r--r--app/assets/javascripts/performance_bar/components/performance_bar_app.vue7
-rw-r--r--app/assets/javascripts/performance_bar/index.js2
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/pipelines_table_row.vue111
-rw-r--r--app/assets/javascripts/vue_shared/components/commit.vue6
-rw-r--r--app/controllers/help_controller.rb11
-rw-r--r--app/controllers/projects/issues_controller.rb3
-rw-r--r--app/graphql/types/event_action_enum.rb12
-rw-r--r--app/graphql/types/event_type.rb36
-rw-r--r--app/graphql/types/eventable_type.rb9
-rw-r--r--app/models/concerns/enums/ci/pipeline.rb5
-rw-r--r--app/policies/event_policy.rb9
-rw-r--r--app/services/pages/migrate_from_legacy_storage_service.rb11
-rw-r--r--app/services/pages/migrate_legacy_storage_to_deployment_service.rb5
-rw-r--r--app/services/pages/zip_directory_service.rb53
-rw-r--r--app/views/peek/_bar.html.haml1
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 }