diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 15:10:29 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 15:10:29 +0300 |
commit | a84766a28a87c0342c6b048f5ea2eab2f3216fcf (patch) | |
tree | c929643b8b21e05da13692620bd508a869d6fbe7 /app | |
parent | f5f1f221ba08228dbbdd7080509028a7cac2fce2 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
19 files changed, 79 insertions, 57 deletions
diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue index 9914bfc6026..623e7799493 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/dropdown_contents_labels_view.vue @@ -132,6 +132,9 @@ export default { } else if (e.keyCode === ENTER_KEY_CODE && this.currentHighlightItem > -1) { this.updateSelectedLabels([this.visibleLabels[this.currentHighlightItem]]); this.searchKey = ''; + + // Prevent parent form submission upon hitting enter. + e.preventDefault(); } else if (e.keyCode === ESC_KEY_CODE) { this.toggleDropdownContents(); } diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue index 87af3ffc52c..3d7e6185fee 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/labels_select_root.vue @@ -315,7 +315,7 @@ export default { </dropdown-value> <dropdown-button v-show="dropdownButtonVisible" class="gl-mt-2" /> <dropdown-contents - v-show="dropdownButtonVisible && showDropdownContents" + v-if="dropdownButtonVisible && showDropdownContents" ref="dropdownContents" :render-on-top="!contentIsOnViewport" /> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js index 178be0f6da0..3bf78f07a83 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/actions.js @@ -20,7 +20,11 @@ export const receiveLabelsFailure = ({ commit }) => { message: __('Error fetching labels.'), }); }; -export const fetchLabels = ({ state, dispatch }) => { +export const fetchLabels = ({ state, dispatch }, options) => { + if (state.labelsFetched && (!options || !options.refetch)) { + return Promise.resolve(); + } + dispatch('requestLabels'); return axios .get(state.labelsFetchPath) @@ -46,6 +50,7 @@ export const createLabel = ({ state, dispatch }, label) => { }) .then(({ data }) => { if (data.id) { + dispatch('fetchLabels', { refetch: true }); dispatch('receiveCreateLabelSuccess'); dispatch('toggleDropdownContentsCreateView'); } else { diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js index 2e0a57f15dd..16c6b20a1f5 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/mutations.js @@ -36,6 +36,7 @@ export default { // selectedLabels array. const selectedLabelIds = state.selectedLabels.map((label) => label.id); state.labelsFetchInProgress = false; + state.labelsFetched = true; state.labels = labels.reduce((allLabels, label) => { allLabels.push({ ...label, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js index d66cfed4163..0185d5f88e1 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_vue/store/state.js @@ -1,6 +1,7 @@ export default () => ({ // Initial Data labels: [], + labelsFetched: false, selectedLabels: [], labelsListTitle: '', labelsCreateTitle: '', diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue index 87f36a5bb72..6cc14def14b 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue @@ -330,7 +330,7 @@ export default { </dropdown-value> <dropdown-button v-show="dropdownButtonVisible" class="gl-mt-2" /> <dropdown-contents - v-show="dropdownButtonVisible && showDropdownContents" + v-if="dropdownButtonVisible && showDropdownContents" ref="dropdownContents" :render-on-top="!contentIsOnViewport" :labels-create-title="labelsCreateTitle" diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss index 10334d771b8..8c46a0fc3bf 100644 --- a/app/assets/stylesheets/utilities.scss +++ b/app/assets/stylesheets/utilities.scss @@ -87,12 +87,6 @@ padding-bottom: $gl-spacing-scale-8; } -// Will be moved to @gitlab/ui in https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1495 -.gl-py-13 { - padding-top: $gl-spacing-scale-13; - padding-bottom: $gl-spacing-scale-13; -} - .gl-transition-property-stroke-opacity { transition-property: stroke-opacity; } diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index b4196878c4f..ce93ac285a8 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -68,20 +68,22 @@ class Projects::PipelinesController < Projects::ApplicationController end def create - @pipeline = Ci::CreatePipelineService + service_response = Ci::CreatePipelineService .new(project, current_user, create_params) .execute(:web, ignore_skip_ci: true, save_on_errors: false) + @pipeline = service_response.payload + respond_to do |format| format.html do - if @pipeline.created_successfully? + if service_response.success? redirect_to project_pipeline_path(project, @pipeline) else render 'new', status: :bad_request end end format.json do - if @pipeline.created_successfully? + if service_response.success? render json: PipelineSerializer .new(project: project, current_user: current_user) .represent(@pipeline), diff --git a/app/finders/security/jobs_finder.rb b/app/finders/security/jobs_finder.rb index 99bcf97f43c..6c2090e0509 100644 --- a/app/finders/security/jobs_finder.rb +++ b/app/finders/security/jobs_finder.rb @@ -38,11 +38,7 @@ module Security def execute return [] if @job_types.empty? - if Feature.enabled?(:ci_build_metadata_config, pipeline.project, default_enabled: :yaml) - find_jobs - else - find_jobs_legacy - end + find_jobs end private @@ -51,19 +47,6 @@ module Security @pipeline.builds.with_secure_reports_from_config_options(@job_types) end - def find_jobs_legacy - # the query doesn't guarantee accuracy, so we verify it here - legacy_jobs_query.select do |job| - @job_types.find { |job_type| job.options.dig(:artifacts, :reports, job_type) } - end - end - - def legacy_jobs_query - @job_types.map do |job_type| - @pipeline.builds.with_secure_reports_from_options(job_type) - end.reduce(&:or) - end - def valid_job_types?(job_types) (job_types - self.class.allowed_job_types).empty? end diff --git a/app/models/concerns/ci/metadatable.rb b/app/models/concerns/ci/metadatable.rb index 114435d5a21..ec86746ae54 100644 --- a/app/models/concerns/ci/metadatable.rb +++ b/app/models/concerns/ci/metadatable.rb @@ -76,14 +76,8 @@ module Ci end def write_metadata_attribute(legacy_key, metadata_key, value) - # save to metadata or this model depending on the state of feature flag - if Feature.enabled?(:ci_build_metadata_config, project, default_enabled: :yaml) - ensure_metadata.write_attribute(metadata_key, value) - write_attribute(legacy_key, nil) - else - write_attribute(legacy_key, value) - metadata&.write_attribute(metadata_key, nil) - end + ensure_metadata.write_attribute(metadata_key, value) + write_attribute(legacy_key, nil) end end end diff --git a/app/services/ci/create_downstream_pipeline_service.rb b/app/services/ci/create_downstream_pipeline_service.rb index e9ec2338171..a65c22e273c 100644 --- a/app/services/ci/create_downstream_pipeline_service.rb +++ b/app/services/ci/create_downstream_pipeline_service.rb @@ -33,8 +33,9 @@ module Ci current_user, pipeline_params.fetch(:target_revision)) - downstream_pipeline = service.execute( - pipeline_params.fetch(:source), **pipeline_params[:execute_params]) + downstream_pipeline = service + .execute(pipeline_params.fetch(:source), **pipeline_params[:execute_params]) + .payload downstream_pipeline.tap do |pipeline| update_bridge_status!(@bridge, pipeline) diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index c039f31aafc..bc95e601e6c 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -87,12 +87,16 @@ module Ci if pipeline.persisted? schedule_head_pipeline_update create_namespace_onboarding_action + else + # If pipeline is not persisted, try to recover IID + pipeline.reset_project_iid end - # If pipeline is not persisted, try to recover IID - pipeline.reset_project_iid unless pipeline.persisted? - - pipeline + if error_message = pipeline.full_error_messages.presence || pipeline.failure_reason.presence + ServiceResponse.error(message: error_message, payload: pipeline) + else + ServiceResponse.success(payload: pipeline) + end end # rubocop: enable Metrics/ParameterLists @@ -100,8 +104,8 @@ module Ci source = args[0] params = Hash(args[1]) - execute(source, **params, &block).tap do |pipeline| - unless pipeline.persisted? + execute(source, **params, &block).tap do |response| + unless response.payload.persisted? raise CreateError, pipeline.full_error_messages end end diff --git a/app/services/ci/external_pull_requests/create_pipeline_service.rb b/app/services/ci/external_pull_requests/create_pipeline_service.rb index 78be94bfb41..83499524a8e 100644 --- a/app/services/ci/external_pull_requests/create_pipeline_service.rb +++ b/app/services/ci/external_pull_requests/create_pipeline_service.rb @@ -7,7 +7,8 @@ module Ci module ExternalPullRequests class CreatePipelineService < BaseService def execute(pull_request) - return unless pull_request.open? && pull_request.actual_branch_head? + return pull_request_not_open_error unless pull_request.open? + return pull_request_branch_error unless pull_request.actual_branch_head? create_pipeline_for(pull_request) end @@ -26,6 +27,14 @@ module Ci target_sha: pull_request.target_sha } end + + def pull_request_not_open_error + ServiceResponse.error(message: 'The pull request is not opened', payload: nil) + end + + def pull_request_branch_error + ServiceResponse.error(message: 'The source sha is not the head of the source branch', payload: nil) + end end end end diff --git a/app/services/ci/pipeline_trigger_service.rb b/app/services/ci/pipeline_trigger_service.rb index 62c4d6b4599..7746382b845 100644 --- a/app/services/ci/pipeline_trigger_service.rb +++ b/app/services/ci/pipeline_trigger_service.rb @@ -27,13 +27,13 @@ module Ci # this check is to not leak the presence of the project if user cannot read it return unless trigger.project == project - pipeline = Ci::CreatePipelineService + response = Ci::CreatePipelineService .new(project, trigger.owner, ref: params[:ref], variables_attributes: variables) .execute(:trigger, ignore_skip_ci: true) do |pipeline| pipeline.trigger_requests.build(trigger: trigger) end - pipeline_service_response(pipeline) + pipeline_service_response(response.payload) end def pipeline_service_response(pipeline) @@ -57,7 +57,7 @@ module Ci # this check is to not leak the presence of the project if user cannot read it return unless can?(job.user, :read_project, project) - pipeline = Ci::CreatePipelineService + response = Ci::CreatePipelineService .new(project, job.user, ref: params[:ref], variables_attributes: variables) .execute(:pipeline, ignore_skip_ci: true) do |pipeline| source = job.sourced_pipelines.build( @@ -69,7 +69,7 @@ module Ci pipeline.source_pipeline = source end - pipeline_service_response(pipeline) + pipeline_service_response(response.payload) end def job_from_token diff --git a/app/services/merge_requests/create_pipeline_service.rb b/app/services/merge_requests/create_pipeline_service.rb index ebeba0ee5b8..6b032545230 100644 --- a/app/services/merge_requests/create_pipeline_service.rb +++ b/app/services/merge_requests/create_pipeline_service.rb @@ -3,7 +3,7 @@ module MergeRequests class CreatePipelineService < MergeRequests::BaseService def execute(merge_request) - return unless can_create_pipeline_for?(merge_request) + return cannot_create_pipeline_error unless can_create_pipeline_for?(merge_request) create_detached_merge_request_pipeline(merge_request) end @@ -60,6 +60,10 @@ module MergeRequests ::Gitlab::UserAccess.new(current_user, container: merge_request.target_project) .can_update_branch?(merge_request.source_branch_ref) end + + def cannot_create_pipeline_error + ServiceResponse.error(message: 'Cannot create a pipeline for this merge request.', payload: nil) + end end end diff --git a/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb b/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb index 75106297043..b4872cd9442 100644 --- a/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb +++ b/app/services/projects/lfs_pointers/lfs_object_download_list_service.rb @@ -31,7 +31,7 @@ module Projects # LfsDownloadLinkListService .new(project, remote_uri: current_endpoint_uri) - .execute(lfs_pointers_in_repository) + .execute(missing_lfs_files) rescue LfsDownloadLinkListService::DownloadLinksError => e raise LfsObjectDownloadListError, "The LFS objects download list couldn't be imported. Error: #{e.message}" end @@ -53,6 +53,22 @@ module Projects @lfs_pointers_in_repository ||= LfsListService.new(project).execute end + def existing_lfs_objects + project.lfs_objects + end + + def existing_lfs_objects_hash + {}.tap do |hash| + existing_lfs_objects.find_each do |lfs_object| + hash[lfs_object.oid] = lfs_object.size + end + end + end + + def missing_lfs_files + lfs_pointers_in_repository.except(*existing_lfs_objects_hash.keys) + end + def lfsconfig_endpoint_uri strong_memoize(:lfsconfig_endpoint_uri) do # Retrieveing the blob data from the .lfsconfig file diff --git a/app/views/admin/application_settings/_repository_static_objects.html.haml b/app/views/admin/application_settings/_repository_static_objects.html.haml index f8ec04003fa..d962d050ebc 100644 --- a/app/views/admin/application_settings/_repository_static_objects.html.haml +++ b/app/views/admin/application_settings/_repository_static_objects.html.haml @@ -7,12 +7,12 @@ = _('External storage URL') = f.text_field :static_objects_external_storage_url, class: 'form-control gl-form-input' %span.form-text.text-muted#static_objects_external_storage_url_help_block - = _('URL of the external storage that will serve the repository static objects (e.g. archives, blobs, ...).') + = _('URL of the external storage to serve the repository static objects.') .form-group = f.label :static_objects_external_storage_auth_token, class: 'label-bold' do = _('External storage authentication token') = f.text_field :static_objects_external_storage_auth_token, class: 'form-control gl-form-input' %span.form-text.text-muted#static_objects_external_storage_auth_token_help_block - = _('A secure token that identifies an external storage request.') + = _('Secure token that identifies an external storage request.') = f.submit _('Save changes'), class: "gl-button btn btn-confirm" diff --git a/app/views/admin/application_settings/repository.html.haml b/app/views/admin/application_settings/repository.html.haml index 2a9fba1aef6..ac200002cd2 100644 --- a/app/views/admin/application_settings/repository.html.haml +++ b/app/views/admin/application_settings/repository.html.haml @@ -55,10 +55,11 @@ %section.settings.as-repository-static-objects.no-animate#js-repository-static-objects-settings{ class: ('expanded' if expanded_by_default?) } .settings-header %h4 - = _('Repository static objects') + = _('External storage for repository static objects') %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' } = expanded_by_default? ? _('Collapse') : _('Expand') %p - = _('Serve repository static objects (e.g. archives, blobs, ...) from an external storage (e.g. a CDN).') + = _('Serve repository static objects (for example, archives and blobs) from external storage.') + = link_to s_('Learn more.'), help_page_path('administration/static_objects_external_storage.md'), target: '_blank', rel: 'noopener noreferrer' .settings-content = render 'repository_static_objects' diff --git a/app/workers/concerns/application_worker.rb b/app/workers/concerns/application_worker.rb index e158ae0c298..6cc6c30c5e9 100644 --- a/app/workers/concerns/application_worker.rb +++ b/app/workers/concerns/application_worker.rb @@ -54,6 +54,10 @@ module ApplicationWorker subclass.after_set_class_attribute { subclass.set_queue } end + def generated_queue_name + Gitlab::SidekiqConfig::WorkerRouter.queue_name_from_worker_name(self) + end + override :validate_worker_attributes! def validate_worker_attributes! super |