diff options
author | Mayra Cabrera <mcabrera@gitlab.com> | 2018-04-09 19:15:15 +0000 |
---|---|---|
committer | Mayra Cabrera <mcabrera@gitlab.com> | 2018-04-09 19:15:15 +0000 |
commit | 8c62f880715aac2f2bf1444d38f9e4d8367bf0ff (patch) | |
tree | 61fec5d009f13895afcf90e4005dbc76f4823884 | |
parent | 753d8514c95f059fca850085b45bfe30f3461113 (diff) | |
parent | 126551b7564c9e9e707e68f2349672e1c6e60d32 (diff) | |
download | gitlab-ce-8c62f880715aac2f2bf1444d38f9e4d8367bf0ff.tar.gz |
Merge branch '10-6-stable-patch-4' into '10-6-stable'
Prepare 10.6.4 release
See merge request gitlab-org/gitlab-ce!18252
52 files changed, 313 insertions, 67 deletions
diff --git a/app/assets/javascripts/boards/services/board_service.js b/app/assets/javascripts/boards/services/board_service.js index d78d4701974..7c90597f77c 100644 --- a/app/assets/javascripts/boards/services/board_service.js +++ b/app/assets/javascripts/boards/services/board_service.js @@ -19,7 +19,7 @@ export default class BoardService { } static generateIssuePath(boardId, id) { - return `${gon.relative_url_root}/-/boards/${boardId ? `/${boardId}` : ''}/issues${id ? `/${id}` : ''}`; + return `${gon.relative_url_root}/-/boards/${boardId ? `${boardId}` : ''}/issues${id ? `/${id}` : ''}`; } all() { diff --git a/app/assets/javascripts/notes/components/noteable_discussion.vue b/app/assets/javascripts/notes/components/noteable_discussion.vue index 76bb53eaf2f..c3f38c9ca13 100644 --- a/app/assets/javascripts/notes/components/noteable_discussion.vue +++ b/app/assets/javascripts/notes/components/noteable_discussion.vue @@ -292,10 +292,12 @@ Please check your network connection and try again.`; </button> </div> <div + v-if="note.resolvable" class="btn-group discussion-actions" - role="group"> + role="group" + > <div - v-if="note.resolvable && !discussionResolved" + v-if="!discussionResolved" class="btn-group" role="group"> <a diff --git a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue b/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue index 22248418c41..2bda2aeb3a1 100644 --- a/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue +++ b/app/assets/javascripts/pages/milestones/shared/components/promote_milestone_modal.vue @@ -19,15 +19,19 @@ type: String, required: true, }, + groupName: { + type: String, + required: true, + }, }, computed: { title() { return sprintf(s__('Milestones|Promote %{milestoneTitle} to group milestone?'), { milestoneTitle: this.milestoneTitle }); }, text() { - return s__(`Milestones|Promoting this milestone will make it available for all projects inside the group. + return sprintf(s__(`Milestones|Promoting %{milestoneTitle} will make it available for all projects inside %{groupName}. Existing project milestones with the same title will be merged. - This action cannot be reversed.`); + This action cannot be reversed.`), { milestoneTitle: this.milestoneTitle, groupName: this.groupName }); }, }, methods: { diff --git a/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js b/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js index d00f81c9094..8e79341e96a 100644 --- a/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js +++ b/app/assets/javascripts/pages/milestones/shared/promote_milestone_modal_init.js @@ -25,6 +25,7 @@ export default () => { const modalProps = { milestoneTitle: button.dataset.milestoneTitle, url: button.dataset.url, + groupName: button.dataset.groupName, }; eventHub.$once('promoteMilestoneModal.requestStarted', onRequestStarted); eventHub.$emit('promoteMilestoneModal.props', modalProps); @@ -54,6 +55,7 @@ export default () => { return { modalProps: { milestoneTitle: '', + groupName: '', url: '', }, }; diff --git a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue b/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue index 54695dfeb99..ad6df51bb7a 100644 --- a/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue +++ b/app/assets/javascripts/pages/projects/labels/components/promote_label_modal.vue @@ -1,4 +1,5 @@ <script> + import _ from 'underscore'; import axios from '~/lib/utils/axios_utils'; import createFlash from '~/flash'; import GlModal from '~/vue_shared/components/gl_modal.vue'; @@ -27,19 +28,26 @@ type: String, required: true, }, + groupName: { + type: String, + required: true, + }, }, computed: { text() { - return s__(`Milestones|Promoting this label will make it available for all projects inside the group. - Existing project labels with the same title will be merged. This action cannot be reversed.`); + return sprintf(s__(`Labels|Promoting %{labelTitle} will make it available for all projects inside %{groupName}. + Existing project labels with the same title will be merged. This action cannot be reversed.`), { + labelTitle: this.labelTitle, + groupName: this.groupName, + }); }, title() { const label = `<span class="label color-label" style="background-color: ${this.labelColor}; color: ${this.labelTextColor};" - >${this.labelTitle}</span>`; + >${_.escape(this.labelTitle)}</span>`; - return sprintf(s__('Labels|Promote label %{labelTitle} to Group Label?'), { + return sprintf(s__('Labels|<span>Promote label</span> %{labelTitle} <span>to Group Label?</span>'), { labelTitle: label, }, false); }, @@ -69,6 +77,7 @@ > <div slot="title" + class="modal-title-with-label" v-html="title" > {{ title }} diff --git a/app/assets/javascripts/pages/projects/labels/index/index.js b/app/assets/javascripts/pages/projects/labels/index/index.js index 2abcbfab1ed..03cfef61311 100644 --- a/app/assets/javascripts/pages/projects/labels/index/index.js +++ b/app/assets/javascripts/pages/projects/labels/index/index.js @@ -30,6 +30,7 @@ const initLabelIndex = () => { labelColor: button.dataset.labelColor, labelTextColor: button.dataset.labelTextColor, url: button.dataset.url, + groupName: button.dataset.groupName, }; eventHub.$once('promoteLabelModal.requestStarted', onRequestStarted); eventHub.$emit('promoteLabelModal.props', modalProps); @@ -62,6 +63,7 @@ const initLabelIndex = () => { labelColor: '', labelTextColor: '', url: '', + groupName: '', }, }; }, diff --git a/app/assets/stylesheets/framework/modal.scss b/app/assets/stylesheets/framework/modal.scss index 48b981dd31f..eb789cc64b0 100644 --- a/app/assets/stylesheets/framework/modal.scss +++ b/app/assets/stylesheets/framework/modal.scss @@ -4,9 +4,15 @@ .page-title, .modal-title { + .modal-title-with-label span { + vertical-align: middle; + display: inline-block; + } + .color-label { font-size: $gl-font-size; padding: $gl-vert-padding $label-padding-modal; + vertical-align: middle; } } diff --git a/app/controllers/projects/labels_controller.rb b/app/controllers/projects/labels_controller.rb index 99790b8e7e8..516198b1b8a 100644 --- a/app/controllers/projects/labels_controller.rb +++ b/app/controllers/projects/labels_controller.rb @@ -112,7 +112,7 @@ class Projects::LabelsController < Projects::ApplicationController begin return render_404 unless promote_service.execute(@label) - flash[:notice] = "#{@label.title} promoted to group label." + flash[:notice] = "#{@label.title} promoted to <a href=\"#{group_labels_path(@project.group)}\">group label</a>.".html_safe respond_to do |format| format.html do redirect_to(project_labels_path(@project), status: 303) diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb index ff93147d00f..3abbe7d45c3 100644 --- a/app/controllers/projects/milestones_controller.rb +++ b/app/controllers/projects/milestones_controller.rb @@ -70,9 +70,9 @@ class Projects::MilestonesController < Projects::ApplicationController end def promote - Milestones::PromoteService.new(project, current_user).execute(milestone) + promoted_milestone = Milestones::PromoteService.new(project, current_user).execute(milestone) - flash[:notice] = "#{milestone.title} promoted to group milestone" + flash[:notice] = "#{milestone.title} promoted to <a href=\"#{group_milestone_path(project.group, promoted_milestone.iid)}\">group milestone</a>.".html_safe respond_to do |format| format.html do redirect_to project_milestones_path(project) diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 49eb069016a..bfdfc5ae6fe 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -10,6 +10,7 @@ module Clusters Applications::Prometheus.application_name => Applications::Prometheus, Applications::Runner.application_name => Applications::Runner }.freeze + DEFAULT_ENVIRONMENT = '*'.freeze belongs_to :user @@ -50,6 +51,7 @@ module Clusters scope :enabled, -> { where(enabled: true) } scope :disabled, -> { where(enabled: false) } + scope :default_environment, -> { where(environment_scope: DEFAULT_ENVIRONMENT) } def status_name if provider diff --git a/app/models/concerns/deployment_platform.rb b/app/models/concerns/deployment_platform.rb index faa94204e33..52851b3d0b2 100644 --- a/app/models/concerns/deployment_platform.rb +++ b/app/models/concerns/deployment_platform.rb @@ -1,16 +1,24 @@ module DeploymentPlatform - # EE would override this and utilize the extra argument + # EE would override this and utilize environment argument + # rubocop:disable Gitlab/ModuleWithInstanceVariables def deployment_platform(environment: nil) - @deployment_platform ||= - find_cluster_platform_kubernetes || - find_kubernetes_service_integration || - build_cluster_and_deployment_platform + @deployment_platform ||= {} + + @deployment_platform[environment] ||= find_deployment_platform(environment) end private - def find_cluster_platform_kubernetes - clusters.find_by(enabled: true)&.platform_kubernetes + def find_deployment_platform(environment) + find_cluster_platform_kubernetes(environment: environment) || + find_kubernetes_service_integration || + build_cluster_and_deployment_platform + end + + # EE would override this and utilize environment argument + def find_cluster_platform_kubernetes(environment: nil) + clusters.enabled.default_environment + .last&.platform_kubernetes end def find_kubernetes_service_integration diff --git a/app/services/boards/issues/move_service.rb b/app/services/boards/issues/move_service.rb index 15fed7d17c1..3ceab209f3f 100644 --- a/app/services/boards/issues/move_service.rb +++ b/app/services/boards/issues/move_service.rb @@ -42,7 +42,10 @@ module Boards ) end - attrs[:move_between_ids] = move_between_ids if move_between_ids + if move_between_ids + attrs[:move_between_ids] = move_between_ids + attrs[:board_group_id] = board.group&.id + end attrs end diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb index d7aa7e2347e..4161932ad2a 100644 --- a/app/services/issues/update_service.rb +++ b/app/services/issues/update_service.rb @@ -55,9 +55,10 @@ module Issues return unless params[:move_between_ids] after_id, before_id = params.delete(:move_between_ids) + board_group_id = params.delete(:board_group_id) - issue_before = get_issue_if_allowed(issue.project, before_id) if before_id - issue_after = get_issue_if_allowed(issue.project, after_id) if after_id + issue_before = get_issue_if_allowed(before_id, board_group_id) + issue_after = get_issue_if_allowed(after_id, board_group_id) issue.move_between(issue_before, issue_after) end @@ -84,8 +85,16 @@ module Issues private - def get_issue_if_allowed(project, id) - issue = project.issues.find(id) + def get_issue_if_allowed(id, board_group_id = nil) + return unless id + + issue = + if board_group_id + IssuesFinder.new(current_user, group_id: board_group_id).find_by(id: id) + else + project.issues.find(id) + end + issue if can?(current_user, :update_issue, issue) end diff --git a/app/services/projects/update_pages_service.rb b/app/services/projects/update_pages_service.rb index 00fdd047208..bd740c7335c 100644 --- a/app/services/projects/update_pages_service.rb +++ b/app/services/projects/update_pages_service.rb @@ -31,15 +31,17 @@ module Projects # Check if we did extract public directory archive_public_path = File.join(archive_path, 'public') - raise FailedToExtractError, 'pages miss the public folder' unless Dir.exist?(archive_public_path) + raise InvaildStateError, 'pages miss the public folder' unless Dir.exist?(archive_public_path) raise InvaildStateError, 'pages are outdated' unless latest? deploy_page!(archive_public_path) success end - rescue InvaildStateError, FailedToExtractError => e - register_failure + rescue InvaildStateError => e error(e.message) + rescue => e + error(e.message, false) + raise e end private @@ -50,12 +52,13 @@ module Projects super end - def error(message, http_status = nil) + def error(message, allow_delete_artifact = true) + register_failure log_error("Projects::UpdatePagesService: #{message}") @status.allow_failure = !latest? @status.description = message @status.drop(:script_failure) - delete_artifact! + delete_artifact! if allow_delete_artifact super end @@ -76,7 +79,7 @@ module Projects elsif artifacts.ends_with?('.zip') extract_zip_archive!(temp_path) else - raise FailedToExtractError, 'unsupported artifacts format' + raise InvaildStateError, 'unsupported artifacts format' end end @@ -89,13 +92,13 @@ module Projects end def extract_zip_archive!(temp_path) - raise FailedToExtractError, 'missing artifacts metadata' unless build.artifacts_metadata? + raise InvaildStateError, 'missing artifacts metadata' unless build.artifacts_metadata? # Calculate page size after extract public_entry = build.artifacts_metadata_entry(SITE_PATH, recursive: true) if public_entry.total_size > max_size - raise FailedToExtractError, "artifacts for pages are too large: #{public_entry.total_size}" + raise InvaildStateError, "artifacts for pages are too large: #{public_entry.total_size}" end # Requires UnZip at least 6.00 Info-ZIP. @@ -174,6 +177,9 @@ module Projects def latest_sha project.commit(build.ref).try(:sha).to_s + ensure + # Close any file descriptors that were opened and free libgit2 buffers + project.cleanup end def sha diff --git a/app/services/verify_pages_domain_service.rb b/app/services/verify_pages_domain_service.rb index 86166047302..13cb53dee01 100644 --- a/app/services/verify_pages_domain_service.rb +++ b/app/services/verify_pages_domain_service.rb @@ -34,7 +34,8 @@ class VerifyPagesDomainService < BaseService # Prevent any pre-existing grace period from being truncated reverify = [domain.enabled_until, VERIFICATION_PERIOD.from_now].compact.max - domain.update!(verified_at: Time.now, enabled_until: reverify) + domain.assign_attributes(verified_at: Time.now, enabled_until: reverify) + domain.save!(validate: false) if was_disabled notify(:enabled) @@ -47,7 +48,9 @@ class VerifyPagesDomainService < BaseService def unverify_domain! if domain.verified? - domain.update!(verified_at: nil) + domain.assign_attributes(verified_at: nil) + domain.save!(validate: false) + notify(:verification_failed) end @@ -55,7 +58,8 @@ class VerifyPagesDomainService < BaseService end def disable_domain! - domain.update!(verified_at: nil, enabled_until: nil) + domain.assign_attributes(verified_at: nil, enabled_until: nil) + domain.save!(validate: false) notify(:disabled) diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml index b423888c875..5ec219fdf00 100644 --- a/app/views/projects/milestones/show.html.haml +++ b/app/views/projects/milestones/show.html.haml @@ -30,6 +30,7 @@ %button.js-promote-project-milestone-button.btn.btn-grouped{ data: { toggle: 'modal', target: '#promote-milestone-modal', milestone_title: @milestone.title, + group_name: @project.group.name, url: promote_project_milestone_path(@milestone.project, @milestone), container: 'body' }, disabled: true, diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml index 5afbc78df53..56403907844 100644 --- a/app/views/shared/_label.html.haml +++ b/app/views/shared/_label.html.haml @@ -55,6 +55,7 @@ label_title: label.title, label_color: label.color, label_text_color: label.text_color, + group_name: label.project.group.name, target: '#promote-label-modal', container: 'body', toggle: 'modal' } } diff --git a/app/views/shared/_recaptcha_form.html.haml b/app/views/shared/_recaptcha_form.html.haml index 93a4301f366..a0ba1afc284 100644 --- a/app/views/shared/_recaptcha_form.html.haml +++ b/app/views/shared/_recaptcha_form.html.haml @@ -10,7 +10,7 @@ = hidden_field(resource_name, field, value: value) = hidden_field_tag(:spam_log_id, spammable.spam_log.id) = hidden_field_tag(:recaptcha_verification, true) - = recaptcha_tags script: script, callback: 'recaptchaDialogCallback' + = recaptcha_tags script: script, callback: 'recaptchaDialogCallback' unless Rails.env.test? -# Yields a block with given extra params. = yield diff --git a/app/views/shared/milestones/_milestone.html.haml b/app/views/shared/milestones/_milestone.html.haml index 9db2a321526..48294032bc3 100644 --- a/app/views/shared/milestones/_milestone.html.haml +++ b/app/views/shared/milestones/_milestone.html.haml @@ -56,6 +56,7 @@ type: 'button', data: { url: promote_project_milestone_path(milestone.project, milestone), milestone_title: milestone.title, + group_name: @project.group.name, target: '#promote-milestone-modal', container: 'body', toggle: 'modal' } } diff --git a/changelogs/unreleased/43794-fix-domain-verification-validation-errors.yml b/changelogs/unreleased/43794-fix-domain-verification-validation-errors.yml new file mode 100644 index 00000000000..861820c7538 --- /dev/null +++ b/changelogs/unreleased/43794-fix-domain-verification-validation-errors.yml @@ -0,0 +1,5 @@ +--- +title: Avoid validation errors when running the Pages domain verification service +merge_request: 17992 +author: +type: fixed diff --git a/changelogs/unreleased/44649-reference-parsing-conflicting-with-auto-linking.yml b/changelogs/unreleased/44649-reference-parsing-conflicting-with-auto-linking.yml new file mode 100644 index 00000000000..a64b0efa1ed --- /dev/null +++ b/changelogs/unreleased/44649-reference-parsing-conflicting-with-auto-linking.yml @@ -0,0 +1,5 @@ +--- +title: Fix autolinking URLs containing ampersands +merge_request: 18045 +author: +type: fixed diff --git a/changelogs/unreleased/44717-no-resolve-issue.yml b/changelogs/unreleased/44717-no-resolve-issue.yml new file mode 100644 index 00000000000..ce23f4e6e9f --- /dev/null +++ b/changelogs/unreleased/44717-no-resolve-issue.yml @@ -0,0 +1,5 @@ +--- +title: Don't show Jump to Discussion button on Issues +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/45070-prometheus-integration-via-kubernetes-is-broken.yml b/changelogs/unreleased/45070-prometheus-integration-via-kubernetes-is-broken.yml new file mode 100644 index 00000000000..046785deb3f --- /dev/null +++ b/changelogs/unreleased/45070-prometheus-integration-via-kubernetes-is-broken.yml @@ -0,0 +1,5 @@ +--- +title: Work around Prometheus Helm chart name changes to fix integration +merge_request: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18206/ +author: joshlambert +type: fixed diff --git a/changelogs/unreleased/dm-refs-contains-sha-encoding.yml b/changelogs/unreleased/dm-refs-contains-sha-encoding.yml new file mode 100644 index 00000000000..cdd9ead5a65 --- /dev/null +++ b/changelogs/unreleased/dm-refs-contains-sha-encoding.yml @@ -0,0 +1,5 @@ +--- +title: Fix listing commit branch/tags that contain special characters +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/fix-gb-fix-background-pipeline-stages-migration.yml b/changelogs/unreleased/fix-gb-fix-background-pipeline-stages-migration.yml new file mode 100644 index 00000000000..63948f0c196 --- /dev/null +++ b/changelogs/unreleased/fix-gb-fix-background-pipeline-stages-migration.yml @@ -0,0 +1,5 @@ +--- +title: Fix exceptions raised when migrating pipeline stages in the background +merge_request: 18076 +author: +type: fixed diff --git a/changelogs/unreleased/issue_44551.yml b/changelogs/unreleased/issue_44551.yml new file mode 100644 index 00000000000..d5265667b00 --- /dev/null +++ b/changelogs/unreleased/issue_44551.yml @@ -0,0 +1,5 @@ +--- +title: Fix 404 in group boards when moving issue between lists +merge_request: +author: +type: fixed diff --git a/changelogs/unreleased/jivl-change-copy-text-promote-milestones-labels.yml b/changelogs/unreleased/jivl-change-copy-text-promote-milestones-labels.yml new file mode 100644 index 00000000000..fb3095552d3 --- /dev/null +++ b/changelogs/unreleased/jivl-change-copy-text-promote-milestones-labels.yml @@ -0,0 +1,5 @@ +--- +title: Correct copy text for the promote milestone and label modals +merge_request: 17726 +author: +type: fixed diff --git a/changelogs/unreleased/sh-cleanup-pages-worker.yml b/changelogs/unreleased/sh-cleanup-pages-worker.yml new file mode 100644 index 00000000000..c26e1342dd2 --- /dev/null +++ b/changelogs/unreleased/sh-cleanup-pages-worker.yml @@ -0,0 +1,5 @@ +--- +title: Free open file descriptors and libgit2 buffers in UpdatePagesService +merge_request: +author: +type: performance diff --git a/doc/ci/examples/code_climate.md b/doc/ci/examples/code_climate.md index ec5e5afb8c6..64a759a9a99 100644 --- a/doc/ci/examples/code_climate.md +++ b/doc/ci/examples/code_climate.md @@ -15,13 +15,8 @@ codequality: services: - docker:dind script: - - docker pull codeclimate/codeclimate - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') - - docker run - --env SOURCE_CODE="$PWD" \ - --volume "$PWD":/code \ - --volume /var/run/docker.sock:/var/run/docker.sock \ - "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code + - docker run --env SOURCE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code artifacts: paths: [codeclimate.json] ``` diff --git a/lib/banzai/filter/autolink_filter.rb b/lib/banzai/filter/autolink_filter.rb index ce401c1c31c..4a143baeef6 100644 --- a/lib/banzai/filter/autolink_filter.rb +++ b/lib/banzai/filter/autolink_filter.rb @@ -105,8 +105,12 @@ module Banzai end end - options = link_options.merge(href: match) - content_tag(:a, match.html_safe, options) + dropped + # match has come from node.to_html above, so we know it's encoded + # correctly. + html_safe_match = match.html_safe + options = link_options.merge(href: html_safe_match) + + content_tag(:a, html_safe_match, options) + dropped end def autolink_filter(text) diff --git a/lib/gitlab/background_migration/migrate_build_stage.rb b/lib/gitlab/background_migration/migrate_build_stage.rb index 8fe4f1a2289..242e3143e71 100644 --- a/lib/gitlab/background_migration/migrate_build_stage.rb +++ b/lib/gitlab/background_migration/migrate_build_stage.rb @@ -12,6 +12,7 @@ module Gitlab class Build < ActiveRecord::Base self.table_name = 'ci_builds' + self.inheritance_column = :_type_disabled def ensure_stage!(attempts: 2) find_stage || create_stage! diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb index d4f6b543daf..190e872fa9a 100644 --- a/lib/gitlab/git/repository.rb +++ b/lib/gitlab/git/repository.rb @@ -8,6 +8,7 @@ module Gitlab class Repository include Gitlab::Git::RepositoryMirroring include Gitlab::Git::Popen + include Gitlab::EncodingHelper ALLOWED_OBJECT_DIRECTORIES_VARIABLES = %w[ GIT_OBJECT_DIRECTORY @@ -1498,7 +1499,7 @@ module Gitlab names.lines.each do |line| next unless line.start_with?(refs_prefix) - refs << line.rstrip[left_slice_count..-1] + refs << encode_utf8(line.rstrip[left_slice_count..-1]) end refs diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb index 15ce418d0d6..82b20e12850 100644 --- a/spec/controllers/projects/clusters_controller_spec.rb +++ b/spec/controllers/projects/clusters_controller_spec.rb @@ -18,7 +18,7 @@ describe Projects::ClustersController do context 'when project has one or more clusters' do let(:project) { create(:project) } let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } - let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, projects: [project]) } + let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) } it 'lists available clusters' do go @@ -32,7 +32,7 @@ describe Projects::ClustersController do before do allow(Clusters::Cluster).to receive(:paginates_per).and_return(1) - create_list(:cluster, 2, :provided_by_gcp, projects: [project]) + create_list(:cluster, 2, :provided_by_gcp, :production_environment, projects: [project]) get :index, namespace_id: project.namespace, project_id: project, page: last_page end diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb index 306094f7ffb..bb46871b5d4 100644 --- a/spec/controllers/projects/milestones_controller_spec.rb +++ b/spec/controllers/projects/milestones_controller_spec.rb @@ -98,7 +98,7 @@ describe Projects::MilestonesController do it 'shows group milestone' do post :promote, namespace_id: project.namespace.id, project_id: project.id, id: milestone.iid - expect(flash[:notice]).to eq("#{milestone.title} promoted to group milestone") + expect(flash[:notice]).to eq("#{milestone.title} promoted to <a href=\"#{group_milestone_path(project.group, milestone.iid)}\">group milestone</a>.") expect(response).to redirect_to(project_milestones_path(project)) end end diff --git a/spec/factories/clusters/clusters.rb b/spec/factories/clusters/clusters.rb index 20d5580f0c2..98566f907f9 100644 --- a/spec/factories/clusters/clusters.rb +++ b/spec/factories/clusters/clusters.rb @@ -32,5 +32,9 @@ FactoryBot.define do trait :disabled do enabled false end + + trait :production_environment do + sequence(:environment_scope) { |n| "production#{n}/*" } + end end end diff --git a/spec/features/issues/spam_issues_spec.rb b/spec/features/issues/spam_issues_spec.rb index a75ca1d42b3..73022afbda2 100644 --- a/spec/features/issues/spam_issues_spec.rb +++ b/spec/features/issues/spam_issues_spec.rb @@ -34,9 +34,6 @@ describe 'New issue', :js do click_button 'Submit issue' - # reCAPTCHA alerts when it can't contact the server, so just accept it and move on - page.driver.browser.switch_to.alert.accept - # it is impossible to test recaptcha automatically and there is no possibility to fill in recaptcha # recaptcha verification is skipped in test environment and it always returns true expect(page).not_to have_content('issue title') diff --git a/spec/finders/clusters_finder_spec.rb b/spec/finders/clusters_finder_spec.rb index c10efac2432..da529e0670f 100644 --- a/spec/finders/clusters_finder_spec.rb +++ b/spec/finders/clusters_finder_spec.rb @@ -6,7 +6,7 @@ describe ClustersFinder do describe '#execute' do let(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } - let(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, projects: [project]) } + let(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) } subject { described_class.new(project, user, scope).execute } diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js index 19504e4f7c8..a6068e5ed1a 100644 --- a/spec/javascripts/notes/components/noteable_discussion_spec.js +++ b/spec/javascripts/notes/components/noteable_discussion_spec.js @@ -25,26 +25,34 @@ describe('issue_discussion component', () => { }); it('should render user avatar', () => { - expect(vm.$el.querySelector('.user-avatar-link')).toBeDefined(); + expect(vm.$el.querySelector('.user-avatar-link')).not.toBeNull(); }); it('should render discussion header', () => { - expect(vm.$el.querySelector('.discussion-header')).toBeDefined(); + expect(vm.$el.querySelector('.discussion-header')).not.toBeNull(); expect(vm.$el.querySelector('.notes').children.length).toEqual(discussionMock.notes.length); }); describe('actions', () => { it('should render reply button', () => { - expect(vm.$el.querySelector('.js-vue-discussion-reply').textContent.trim()).toEqual('Reply...'); + expect(vm.$el.querySelector('.js-vue-discussion-reply').textContent.trim()).toEqual( + 'Reply...', + ); }); it('should toggle reply form', (done) => { vm.$el.querySelector('.js-vue-discussion-reply').click(); Vue.nextTick(() => { - expect(vm.$refs.noteForm).toBeDefined(); + expect(vm.$refs.noteForm).not.toBeNull(); expect(vm.isReplying).toEqual(true); done(); }); }); + + it('does not render jump to discussion button', () => { + expect( + vm.$el.querySelector('*[data-original-title="Jump to next unresolved discussion"]'), + ).toBeNull(); + }); }); }); diff --git a/spec/javascripts/pages/labels/components/promote_label_modal_spec.js b/spec/javascripts/pages/labels/components/promote_label_modal_spec.js index ba2e07f02f7..3ecb3299836 100644 --- a/spec/javascripts/pages/labels/components/promote_label_modal_spec.js +++ b/spec/javascripts/pages/labels/components/promote_label_modal_spec.js @@ -12,6 +12,7 @@ describe('Promote label modal', () => { labelColor: '#5cb85c', labelTextColor: '#ffffff', url: `${gl.TEST_HOST}/dummy/promote/labels`, + groupName: 'group', }; describe('Modal title and description', () => { @@ -24,7 +25,7 @@ describe('Promote label modal', () => { }); it('contains the proper description', () => { - expect(vm.text).toContain('Promoting this label will make it available for all projects inside the group'); + expect(vm.text).toContain(`Promoting ${labelMockData.labelTitle} will make it available for all projects inside ${labelMockData.groupName}`); }); it('contains a label span with the color', () => { diff --git a/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js b/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js index bf044fe8fb5..fc5e7540b6f 100644 --- a/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js +++ b/spec/javascripts/pages/milestones/shared/components/promote_milestone_modal_spec.js @@ -10,6 +10,7 @@ describe('Promote milestone modal', () => { const milestoneMockData = { milestoneTitle: 'v1.0', url: `${gl.TEST_HOST}/dummy/promote/milestones`, + groupName: 'group', }; describe('Modal title and description', () => { @@ -22,7 +23,7 @@ describe('Promote milestone modal', () => { }); it('contains the proper description', () => { - expect(vm.text).toContain('Promoting this milestone will make it available for all projects inside the group.'); + expect(vm.text).toContain(`Promoting ${milestoneMockData.milestoneTitle} will make it available for all projects inside ${milestoneMockData.groupName}.`); }); it('contains the correct title', () => { diff --git a/spec/lib/banzai/filter/autolink_filter_spec.rb b/spec/lib/banzai/filter/autolink_filter_spec.rb index cbb0089bde7..a50329473ad 100644 --- a/spec/lib/banzai/filter/autolink_filter_spec.rb +++ b/spec/lib/banzai/filter/autolink_filter_spec.rb @@ -167,6 +167,15 @@ describe Banzai::Filter::AutolinkFilter do expect(actual).to eq(expected_complicated_link) end + it 'does not double-encode HTML entities' do + encoded_link = "#{link}?foo=bar&baz=quux" + expected_encoded_link = %Q{<a href="#{encoded_link}">#{encoded_link}</a>} + actual = unescape(filter(encoded_link).to_html) + + expect(actual).to eq(Rinku.auto_link(encoded_link)) + expect(actual).to eq(expected_encoded_link) + end + it 'does not include trailing HTML entities' do doc = filter("See <<<#{link}>>>") diff --git a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb index e112e9e9e3d..5ce84c61042 100644 --- a/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb +++ b/spec/lib/gitlab/background_migration/migrate_build_stage_spec.rb @@ -51,4 +51,20 @@ describe Gitlab::BackgroundMigration::MigrateBuildStage, :migration, schema: 201 expect { described_class.new.perform(1, 6) } .to raise_error ActiveRecord::RecordNotUnique end + + context 'when invalid class can be loaded due to single table inheritance' do + let(:commit_status) do + jobs.create!(id: 7, commit_id: 1, project_id: 123, stage_idx: 4, + stage: 'post-deploy', status: :failed) + end + + before do + commit_status.update_column(:type, 'SomeClass') + end + + it 'does ignore single table inheritance type' do + expect { described_class.new.perform(1, 7) }.not_to raise_error + expect(jobs.find(7)).to have_attributes(stage_id: (a_value > 0)) + end + end end diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb index 52c9876cbb6..1bc8f79614d 100644 --- a/spec/lib/gitlab/git/repository_spec.rb +++ b/spec/lib/gitlab/git/repository_spec.rb @@ -604,17 +604,20 @@ describe Gitlab::Git::Repository, seed_helper: true do shared_examples 'returning the right branches' do let(:head_id) { repository.rugged.head.target.oid } let(:new_branch) { head_id } + let(:utf8_branch) { 'branch-é' } before do repository.create_branch(new_branch, 'master') + repository.create_branch(utf8_branch, 'master') end after do repository.delete_branch(new_branch) + repository.delete_branch(utf8_branch) end it 'displays that branch' do - expect(repository.branch_names_contains_sha(head_id)).to include('master', new_branch) + expect(repository.branch_names_contains_sha(head_id)).to include('master', new_branch, utf8_branch) end end diff --git a/spec/presenters/project_presenter_spec.rb b/spec/presenters/project_presenter_spec.rb index f8c93d91ec5..55962f345d4 100644 --- a/spec/presenters/project_presenter_spec.rb +++ b/spec/presenters/project_presenter_spec.rb @@ -339,7 +339,7 @@ describe ProjectPresenter do it 'returns link to clusters page if more than one exists' do project.add_master(user) - create(:cluster, projects: [project]) + create(:cluster, :production_environment, projects: [project]) create(:cluster, projects: [project]) expect(presenter.kubernetes_cluster_anchor_data).to eq(OpenStruct.new(enabled: true, diff --git a/spec/services/boards/issues/move_service_spec.rb b/spec/services/boards/issues/move_service_spec.rb index 0a6b6d880d3..dd0ad5f11bd 100644 --- a/spec/services/boards/issues/move_service_spec.rb +++ b/spec/services/boards/issues/move_service_spec.rb @@ -48,7 +48,7 @@ describe Boards::Issues::MoveService do parent.add_developer(user) end - it_behaves_like 'issues move service' + it_behaves_like 'issues move service', true end end end diff --git a/spec/services/clusters/create_service_spec.rb b/spec/services/clusters/create_service_spec.rb index e2e64659dfa..1c2f9c5cf43 100644 --- a/spec/services/clusters/create_service_spec.rb +++ b/spec/services/clusters/create_service_spec.rb @@ -82,7 +82,7 @@ describe Clusters::CreateService do context 'when project has a cluster' do include_context 'valid params' - let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } + let!(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, projects: [project]) } it 'does not create a cluster' do expect(ClusterProvisionWorker).not_to receive(:perform_async) diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 41237dd7160..f95474208f3 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -97,6 +97,37 @@ describe Issues::UpdateService, :mailer do expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position) end + context 'when moving issue between issues from different projects' do + let(:group) { create(:group) } + let(:project_1) { create(:project, namespace: group) } + let(:project_2) { create(:project, namespace: group) } + let(:project_3) { create(:project, namespace: group) } + + let(:issue_1) { create(:issue, project: project_1) } + let(:issue_2) { create(:issue, project: project_2) } + let(:issue_3) { create(:issue, project: project_3) } + + before do + group.add_developer(user) + end + + it 'sorts issues as specified by parameters' do + # Moving all issues to end here like the last example won't work since + # all projects only have the same issue count + # so their relative_position will be the same. + issue_1.move_to_end + issue_2.move_after(issue_1) + issue_3.move_after(issue_2) + [issue_1, issue_2, issue_3].map(&:save) + + opts[:move_between_ids] = [issue_1.id, issue_2.id] + opts[:board_group_id] = group.id + + described_class.new(issue_3.project, user, opts).execute(issue_3) + expect(issue_2.relative_position).to be_between(issue_1.relative_position, issue_2.relative_position) + end + end + context 'when current user cannot admin issues in the project' do let(:guest) { create(:user) } before do diff --git a/spec/services/projects/update_pages_service_spec.rb b/spec/services/projects/update_pages_service_spec.rb index 934106627a9..dd31a677dfe 100644 --- a/spec/services/projects/update_pages_service_spec.rb +++ b/spec/services/projects/update_pages_service_spec.rb @@ -87,7 +87,8 @@ describe Projects::UpdatePagesService do it 'fails for empty file fails' do build.update_attributes(legacy_artifacts_file: empty_file) - expect(execute).not_to eq(:success) + expect { execute } + .to raise_error(Projects::UpdatePagesService::FailedToExtractError) end end end @@ -159,7 +160,8 @@ describe Projects::UpdatePagesService do it 'fails for empty file fails' do build.job_artifacts_archive.update_attributes(file: empty_file) - expect(execute).not_to eq(:success) + expect { execute } + .to raise_error(Projects::UpdatePagesService::FailedToExtractError) end context 'when timeout happens by DNS error' do @@ -172,7 +174,39 @@ describe Projects::UpdatePagesService do expect { execute }.to raise_error(SocketError) build.reload - expect(build.artifacts?).to eq(true) + expect(deploy_status).to be_failed + expect(build.artifacts?).to be_truthy + end + end + + context 'when failed to extract zip artifacts' do + before do + allow_any_instance_of(described_class) + .to receive(:extract_zip_archive!) + .and_raise(Projects::UpdatePagesService::FailedToExtractError) + end + + it 'raises an error' do + expect { execute } + .to raise_error(Projects::UpdatePagesService::FailedToExtractError) + + build.reload + expect(deploy_status).to be_failed + expect(build.artifacts?).to be_truthy + end + end + + context 'when missing artifacts metadata' do + before do + allow(build).to receive(:artifacts_metadata?).and_return(false) + end + + it 'does not raise an error and remove artifacts as failed job' do + execute + + build.reload + expect(deploy_status).to be_failed + expect(build.artifacts?).to be_falsey end end end diff --git a/spec/services/verify_pages_domain_service_spec.rb b/spec/services/verify_pages_domain_service_spec.rb index 576db1dde2d..d974cc0226f 100644 --- a/spec/services/verify_pages_domain_service_spec.rb +++ b/spec/services/verify_pages_domain_service_spec.rb @@ -93,6 +93,25 @@ describe VerifyPagesDomainService do expect(domain).not_to be_enabled end end + + context 'invalid domain' do + let(:domain) { build(:pages_domain, :expired, :with_missing_chain) } + + before do + domain.save(validate: false) + end + + it 'can be disabled' do + error_status[:message] += '. It is now disabled.' + + stub_resolver + + expect(service.execute).to eq(error_status) + + expect(domain).not_to be_verified + expect(domain).not_to be_enabled + end + end end context 'timeout behaviour' do diff --git a/spec/support/migrations_helpers.rb b/spec/support/migrations_helpers.rb index 6bf976a2cf9..5d6f662e8fe 100644 --- a/spec/support/migrations_helpers.rb +++ b/spec/support/migrations_helpers.rb @@ -1,6 +1,9 @@ module MigrationsHelpers def table(name) - Class.new(ActiveRecord::Base) { self.table_name = name } + Class.new(ActiveRecord::Base) do + self.table_name = name + self.inheritance_column = :_type_disabled + end end def migrations_paths diff --git a/spec/support/shared_examples/services/boards/issues_move_service.rb b/spec/support/shared_examples/services/boards/issues_move_service.rb index 4a4fbaa3a0e..737863ea411 100644 --- a/spec/support/shared_examples/services/boards/issues_move_service.rb +++ b/spec/support/shared_examples/services/boards/issues_move_service.rb @@ -1,4 +1,4 @@ -shared_examples 'issues move service' do +shared_examples 'issues move service' do |group| context 'when moving an issue between lists' do let(:issue) { create(:labeled_issue, project: project, labels: [bug, development]) } let(:params) { { board_id: board1.id, from_list_id: list1.id, to_list_id: list2.id } } @@ -83,5 +83,18 @@ shared_examples 'issues move service' do expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position) end + + if group + context 'when on a group board' do + it 'sends the board_group_id parameter' do + params.merge!(move_after_id: issue1.id, move_before_id: issue2.id) + + match_params = { move_between_ids: [issue1.id, issue2.id], board_group_id: parent.id } + expect(Issues::UpdateService).to receive(:new).with(issue.project, user, match_params).and_return(double(execute: build(:issue))) + + described_class.new(parent, user, params).execute(issue) + end + end + end end end diff --git a/vendor/prometheus/values.yaml b/vendor/prometheus/values.yaml index 859f2ad82a4..c432be72163 100644 --- a/vendor/prometheus/values.yaml +++ b/vendor/prometheus/values.yaml @@ -14,6 +14,7 @@ rbac: create: false server: + fullnameOverride: "prometheus-prometheus-server" image: tag: v2.1.0 |