Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-05-25 09:08:47 +00:00
parent e83b20c4f3
commit f71f0f5307
25 changed files with 108 additions and 161 deletions

View File

@ -1 +1 @@
5aa9d4d29c49ebe427a4a895158e195725cda2da
47335e9fa13b0185b9d479a9e8bffc535eed6a7c

View File

@ -1 +1 @@
14.7.0
14.7.1

View File

@ -12,6 +12,6 @@ export default class EditorExtension {
}
get api() {
return this.obj.provides?.();
return this.obj.provides?.() || {};
}
}

View File

@ -417,6 +417,7 @@ export default {
}
this.isMakingRequest = true;
this.editCommitMessage = false;
if (!useAutoMerge) {
this.mr.transitionStateMachine({ transition: MERGE });
@ -663,7 +664,11 @@ export default {
<gl-sprintf v-else :message="mergeDisabledText" />
</div>
<template v-if="glFeatures.restructuredMrWidget">
<div v-show="editCommitMessage" class="gl-w-full gl-order-n1">
<div
v-if="editCommitMessage"
class="gl-w-full gl-order-n1"
data-testid="edit_commit_message"
>
<ul
:class="{
'content-list': !glFeatures.restructuredMrWidget,

View File

@ -743,3 +743,14 @@ $tabs-holder-z-index: 250;
grid-gap: 5%;
}
}
.container-fluid:not(.container-limited) {
.detail-page-header,
.detail-page-description,
.merge-request-tabs-container {
&.is-merge-request {
@include gl-mx-auto;
max-width: $fixed-layout-width - ($gl-padding * 2);
}
}
}

View File

@ -25,6 +25,7 @@ class ApplicationController < ActionController::Base
include FlocOptOut
include CheckRateLimit
before_action :limit_session_time, if: -> { !current_user }
before_action :authenticate_user!, except: [:route_not_found]
before_action :enforce_terms!, if: :should_enforce_terms?
before_action :validate_user_service_ticket!
@ -43,7 +44,6 @@ class ApplicationController < ActionController::Base
# Make sure the `auth_user` is memoized so it can be logged, we do this after
# all other before filters that could have set the user.
before_action :auth_user
before_action :limit_session_time, if: -> { !current_user }
prepend_around_action :set_current_context

View File

@ -1,5 +1,7 @@
.detail-page-description.py-2
- if Feature.enabled?(:updated_mr_header, @project)
- updated_mr_header = Feature.enabled?(:updated_mr_header, @project)
.detail-page-description.py-2{ class: "#{'is-merge-request' if updated_mr_header && !fluid_layout}" }
- if updated_mr_header
= render 'shared/issuable/status_box', issuable: @merge_request
= merge_request_header(@project, @merge_request)
- else

View File

@ -3,7 +3,7 @@
- can_reopen_merge_request = can?(current_user, :reopen_merge_request, @merge_request)
- are_close_and_open_buttons_hidden = merge_request_button_hidden?(@merge_request, true) && merge_request_button_hidden?(@merge_request, false)
- updated_mr_header_enabled = Feature.enabled?(:updated_mr_header, @project)
- cache_key = [@project, @merge_request, can_update_merge_request, can_reopen_merge_request, are_close_and_open_buttons_hidden, current_user&.preferred_language, updated_mr_header_enabled]
- cache_key = [@project, @merge_request, can_update_merge_request, can_reopen_merge_request, are_close_and_open_buttons_hidden, current_user&.preferred_language, "1.1-#{updated_mr_header_enabled}"]
= cache(cache_key, expires_in: 1.day) do
- if @merge_request.closed_or_merged_without_fork?
@ -13,7 +13,7 @@
= c.body do
= _('The source project of this merge request has been removed.')
.detail-page-header.border-bottom-0.pt-0.pb-0{ class: "#{'gl-display-block gl-md-display-flex!' if updated_mr_header_enabled}" }
.detail-page-header.border-bottom-0.pt-0.pb-0{ class: "#{'gl-display-block gl-md-display-flex!' if updated_mr_header_enabled} #{'is-merge-request' if updated_mr_header_enabled && !fluid_layout}" }
.detail-page-header-body
- unless updated_mr_header_enabled
= render "shared/issuable/status_box", issuable: @merge_request

View File

@ -21,7 +21,7 @@
.merge-request-details.issuable-details{ data: { id: @merge_request.project.id } }
= render "projects/merge_requests/mr_box"
.merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
.merge-request-tabs-container
.merge-request-tabs-container{ class: "#{'is-merge-request' if Feature.enabled?(:updated_mr_header, @project) && !fluid_layout}" }
%ul.merge-request-tabs.nav-tabs.nav.nav-links
= render "projects/merge_requests/tabs/tab", class: "notes-tab", qa_selector: "notes_tab" do
= tab_link_for @merge_request, :show, force_link: @commit.present? do

View File

@ -1614,24 +1614,6 @@
:weight: 1
:idempotent: true
:tags: []
- :name: pipeline_cache:expire_job_cache
:worker_name: ExpireJobCacheWorker
:feature_category: :continuous_integration
:has_external_dependencies:
:urgency: :high
:resource_boundary: :unknown
:weight: 3
:idempotent: true
:tags: []
- :name: pipeline_cache:expire_pipeline_cache
:worker_name: ExpirePipelineCacheWorker
:feature_category: :continuous_integration
:has_external_dependencies:
:urgency: :high
:resource_boundary: :cpu
:weight: 3
:idempotent:
:tags: []
- :name: pipeline_creation:ci_external_pull_requests_create_pipeline
:worker_name: Ci::ExternalPullRequests::CreatePipelineWorker
:feature_category: :continuous_integration

View File

@ -1,22 +0,0 @@
# frozen_string_literal: true
class ExpireJobCacheWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
data_consistency :delayed
sidekiq_options retry: 3
include PipelineQueue
queue_namespace :pipeline_cache
urgency :high
idempotent!
def perform(job_id)
job = CommitStatus.find_by_id(job_id)
return unless job
job.expire_etag_cache!
ExpirePipelineCacheWorker.perform_async(job.pipeline_id)
end
end

View File

@ -1,27 +0,0 @@
# frozen_string_literal: true
# rubocop: disable Scalability/IdempotentWorker
class ExpirePipelineCacheWorker
include ApplicationWorker
sidekiq_options retry: 3
include PipelineQueue
queue_namespace :pipeline_cache
urgency :high
worker_resource_boundary :cpu
data_consistency :delayed
# This worker _should_ be idempotent, but due to us moving this to data_consistency :delayed
# and an ongoing incompatibility between the two switches, we need to disable this.
# Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is resolved
# idempotent!
def perform(pipeline_id)
pipeline = Ci::Pipeline.find_by_id(pipeline_id)
return unless pipeline
Ci::ExpirePipelineCacheService.new.execute(pipeline)
end
end
# rubocop:enable Scalability/IdempotentWorker

View File

@ -329,8 +329,6 @@
- 1
- - pipeline_background
- 1
- - pipeline_cache
- 3
- - pipeline_creation
- 4
- - pipeline_default

View File

@ -357,7 +357,10 @@ To add seats to a subscription:
A payment receipt is emailed to you, which you can also access in the Customers Portal under [**View invoices**](https://customers.gitlab.com/receipts).
For subscriptions that use cloud licensing, the additional seats are reflected on your instance immediately and no further action is needed. If you're using a legacy license, you receive an updated license file. [Add this license](../../user/admin_area/license.md) to your instance to use it.
If your subscription was activated with an activation code, the additional seats are reflected in
your instance immediately. If you're using a license file, you receive an updated file.
To add the seats, [add the license file](../../user/admin_area/license_file.md)
to your instance.
### Renew a subscription

View File

@ -6,6 +6,9 @@ module Gitlab
class BaseDoorkeeperController < ActionController::Base
include Gitlab::Allowable
include EnforcesTwoFactorAuthentication
include SessionsHelper
before_action :limit_session_time, if: -> { !current_user }
helper_method :can?
end

View File

@ -9,3 +9,5 @@ module Gitlab
end
end
end
Gitlab::DeviseFailure.prepend_mod

View File

@ -195,22 +195,22 @@ RSpec.describe Gitlab::SidekiqCluster::CLI, stub_settings_source: true do # rubo
},
'high urgency CI queues' => {
query: 'feature_category=continuous_integration&urgency=high',
included_queues: %w(pipeline_cache:expire_job_cache pipeline_cache:expire_pipeline_cache),
included_queues: %w(pipeline_default:ci_drop_pipeline),
excluded_queues: %w(merge)
},
'CPU-bound high urgency CI queues' => {
query: 'feature_category=continuous_integration&urgency=high&resource_boundary=cpu',
included_queues: %w(pipeline_cache:expire_pipeline_cache),
excluded_queues: %w(pipeline_cache:expire_job_cache merge)
included_queues: %w(pipeline_default:ci_create_downstream_pipeline),
excluded_queues: %w(pipeline_default:ci_drop_pipeline merge)
},
'CPU-bound high urgency non-CI queues' => {
query: 'feature_category!=continuous_integration&urgency=high&resource_boundary=cpu',
included_queues: %w(new_issue),
excluded_queues: %w(pipeline_cache:expire_pipeline_cache)
excluded_queues: %w(pipeline_default:ci_create_downstream_pipeline)
},
'CI and SCM queues' => {
query: 'feature_category=continuous_integration|feature_category=source_code_management',
included_queues: %w(pipeline_cache:expire_job_cache merge),
included_queues: %w(pipeline_default:ci_drop_pipeline merge),
excluded_queues: %w(mailers)
}
}

View File

@ -105,10 +105,6 @@ RSpec.describe ApplicationController do
describe 'session expiration' do
controller(described_class) do
# The anonymous controller will report 401 and fail to run any actions.
# Normally, GitLab will just redirect you to sign in.
skip_before_action :authenticate_user!, only: :index
def index
render html: 'authenticated'
end

View File

@ -195,6 +195,24 @@ RSpec.describe Oauth::AuthorizationsController do
end
end
end
context 'when the user is not signed in' do
before do
sign_out(user)
end
it 'sets a lower session expiry and redirects to the sign in page' do
subject
expect(request.env['rack.session.options'][:expire_after]).to eq(
Settings.gitlab['unauthenticated_session_expire_delay']
)
expect(request.session['user_return_to']).to eq("/oauth/authorize?#{params.to_query}")
expect(response).to have_gitlab_http_status(:found)
expect(response).to redirect_to(new_user_session_path)
end
end
end
describe 'POST #create' do

View File

@ -49,6 +49,12 @@ export const SEConstExt = () => {
};
};
export const SEExtWithoutAPI = () => {
return {
extensionName: 'SEExtWithoutAPI',
};
};
export class SEWithSetupExt {
static get extensionName() {
return 'SEWithSetupExt';

View File

@ -54,6 +54,7 @@ describe('Editor Extension', () => {
${helpers.SEClassExtension} | ${['shared', 'classExtMethod']}
${helpers.SEFnExtension} | ${['fnExtMethod']}
${helpers.SEConstExt} | ${['constExtMethod']}
${helpers.SEExtWithoutAPI} | ${[]}
`('correctly returns API for $definition', ({ definition, expectedKeys }) => {
const extension = new EditorExtension({ definition });
const expectedApi = Object.fromEntries(

View File

@ -87,7 +87,11 @@ const createReadyToMergeResponse = (customMr) => {
});
};
const createComponent = (customConfig = {}, mergeRequestWidgetGraphql = false) => {
const createComponent = (
customConfig = {},
mergeRequestWidgetGraphql = false,
restructuredMrWidget = false,
) => {
wrapper = shallowMount(ReadyToMerge, {
localVue,
propsData: {
@ -97,6 +101,7 @@ const createComponent = (customConfig = {}, mergeRequestWidgetGraphql = false) =
provide: {
glFeatures: {
mergeRequestWidgetGraphql,
restructuredMrWidget,
},
},
stubs: {
@ -307,6 +312,20 @@ describe('ReadyToMerge', () => {
},
});
beforeEach(() => {
readyToMergeResponseSpy = jest
.fn()
.mockResolvedValueOnce(createReadyToMergeResponse({ squash: true, squashOnMerge: true }))
.mockResolvedValue(
createReadyToMergeResponse({
squash: true,
squashOnMerge: true,
defaultMergeCommitMessage: '',
defaultSquashCommitMessage: '',
}),
);
});
it('should handle merge when pipeline succeeds', async () => {
createComponent();
@ -379,6 +398,27 @@ describe('ReadyToMerge', () => {
expect(params.should_remove_source_branch).toBeTruthy();
expect(params.auto_merge_strategy).toBeUndefined();
});
it('hides edit commit message', async () => {
createComponent({}, true, true);
await waitForPromises();
jest.spyOn(eventHub, '$emit').mockImplementation(() => {});
jest.spyOn(wrapper.vm.service, 'merge').mockResolvedValue(response('success'));
await wrapper
.findComponent('[data-testid="widget_edit_commit_message"]')
.vm.$emit('input', true);
expect(wrapper.findComponent('[data-testid="edit_commit_message"]').exists()).toBe(true);
wrapper.vm.handleMergeButtonClick();
await waitForPromises();
expect(wrapper.findComponent('[data-testid="edit_commit_message"]').exists()).toBe(false);
});
});
describe('initiateRemoveSourceBranchPolling', () => {

View File

@ -227,8 +227,6 @@ RSpec.describe 'Every Sidekiq worker' do
'Epics::UpdateEpicsDatesWorker' => 3,
'ErrorTrackingIssueLinkWorker' => 3,
'Experiments::RecordConversionEventWorker' => 3,
'ExpireJobCacheWorker' => 3,
'ExpirePipelineCacheWorker' => 3,
'ExportCsvWorker' => 3,
'ExternalServiceReactiveCachingWorker' => 3,
'FileHookWorker' => false,

View File

@ -1,31 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ExpireJobCacheWorker do
let_it_be(:pipeline) { create(:ci_empty_pipeline) }
let(:project) { pipeline.project }
describe '#perform' do
context 'with a job in the pipeline' do
let_it_be(:job) { create(:ci_build, pipeline: pipeline) }
let(:job_args) { job.id }
it_behaves_like 'an idempotent worker'
it_behaves_like 'worker with data consistency',
described_class,
data_consistency: :delayed
end
context 'when there is no job in the pipeline' do
it 'does not change the etag store' do
expect(Gitlab::EtagCaching::Store).not_to receive(:new)
perform_multiple(non_existing_record_id)
end
end
end
end

View File

@ -1,38 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe ExpirePipelineCacheWorker do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
subject { described_class.new }
describe '#perform' do
it 'executes the service' do
expect_next_instance_of(Ci::ExpirePipelineCacheService) do |instance|
expect(instance).to receive(:execute).with(pipeline).and_call_original
end
subject.perform(pipeline.id)
end
it "doesn't do anything if the pipeline not exist" do
expect_any_instance_of(Ci::ExpirePipelineCacheService).not_to receive(:execute)
expect_any_instance_of(Gitlab::EtagCaching::Store).not_to receive(:touch)
subject.perform(617748)
end
skip "with https://gitlab.com/gitlab-org/gitlab/-/issues/325291 resolved" do
it_behaves_like 'an idempotent worker' do
let(:job_args) { [pipeline.id] }
end
end
it_behaves_like 'worker with data consistency',
described_class,
data_consistency: :delayed
end
end