Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
3396d8eca0
commit
fb28ad5316
|
|
@ -3734,7 +3734,6 @@ Layout/LineLength:
|
|||
- 'spec/lib/gitlab/email/failure_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_issue_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_note_on_issuable_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/service_desk_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb'
|
||||
|
|
|
|||
|
|
@ -1739,7 +1739,6 @@ RSpec/ContextWording:
|
|||
- 'spec/lib/gitlab/email/failure_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_issue_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/service_desk_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler_spec.rb'
|
||||
|
|
|
|||
|
|
@ -3337,7 +3337,6 @@ RSpec/FeatureCategory:
|
|||
- 'spec/lib/gitlab/email/failure_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_issue_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_note_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/create_note_on_issuable_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/service_desk_handler_spec.rb'
|
||||
- 'spec/lib/gitlab/email/handler/unsubscribe_handler_spec.rb'
|
||||
|
|
|
|||
|
|
@ -45,7 +45,12 @@ module Ci
|
|||
has_one :pending_state, class_name: 'Ci::BuildPendingState', foreign_key: :build_id, inverse_of: :build
|
||||
has_one :queuing_entry, class_name: 'Ci::PendingBuild', foreign_key: :build_id, inverse_of: :build
|
||||
has_one :runtime_metadata, class_name: 'Ci::RunningBuild', foreign_key: :build_id, inverse_of: :build
|
||||
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id, inverse_of: :build
|
||||
has_many :trace_chunks,
|
||||
->(build) { in_partition(build) },
|
||||
class_name: 'Ci::BuildTraceChunk',
|
||||
foreign_key: :build_id,
|
||||
inverse_of: :build,
|
||||
partition_foreign_key: :partition_id
|
||||
has_many :report_results, class_name: 'Ci::BuildReportResult', foreign_key: :build_id, inverse_of: :build
|
||||
has_one :namespace, through: :project
|
||||
|
||||
|
|
@ -55,7 +60,12 @@ module Ci
|
|||
# Details: https://gitlab.com/gitlab-org/gitlab/-/issues/24644#note_689472685
|
||||
has_many :job_artifacts, class_name: 'Ci::JobArtifact', foreign_key: :job_id, dependent: :destroy, inverse_of: :job # rubocop:disable Cop/ActiveRecordDependent
|
||||
has_many :job_variables, class_name: 'Ci::JobVariable', foreign_key: :job_id, inverse_of: :job
|
||||
has_many :job_annotations, class_name: 'Ci::JobAnnotation', foreign_key: :job_id, inverse_of: :job
|
||||
has_many :job_annotations,
|
||||
->(build) { in_partition(build) },
|
||||
class_name: 'Ci::JobAnnotation',
|
||||
foreign_key: :job_id,
|
||||
partition_foreign_key: :partition_id,
|
||||
inverse_of: :job
|
||||
has_many :sourced_pipelines, class_name: 'Ci::Sources::Pipeline', foreign_key: :source_job_id, inverse_of: :build
|
||||
|
||||
has_many :pages_deployments, foreign_key: :ci_build_id, inverse_of: :ci_build
|
||||
|
|
@ -64,7 +74,12 @@ module Ci
|
|||
has_one :"job_artifacts_#{key}", -> { where(file_type: value) }, class_name: 'Ci::JobArtifact', foreign_key: :job_id, inverse_of: :job
|
||||
end
|
||||
|
||||
has_one :runner_manager_build, class_name: 'Ci::RunnerManagerBuild', foreign_key: :build_id, inverse_of: :build,
|
||||
has_one :runner_manager_build,
|
||||
->(build) { in_partition(build) },
|
||||
class_name: 'Ci::RunnerManagerBuild',
|
||||
foreign_key: :build_id,
|
||||
inverse_of: :build,
|
||||
partition_foreign_key: :partition_id,
|
||||
autosave: true
|
||||
has_one :runner_manager, foreign_key: :runner_machine_id, through: :runner_manager_build, class_name: 'Ci::RunnerManager'
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,12 @@
|
|||
class Ci::BuildPendingState < Ci::ApplicationRecord
|
||||
include Ci::Partitionable
|
||||
|
||||
belongs_to :build, class_name: 'Ci::Build', foreign_key: :build_id, inverse_of: :pending_state
|
||||
belongs_to :build,
|
||||
->(pending_state) { in_partition(pending_state) },
|
||||
class_name: 'Ci::Build',
|
||||
foreign_key: :build_id,
|
||||
partition_foreign_key: :partition_id,
|
||||
inverse_of: :pending_state
|
||||
|
||||
partitionable scope: :build
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,12 @@ module Ci
|
|||
include ::Gitlab::ExclusiveLeaseHelpers
|
||||
include ::Gitlab::OptimisticLocking
|
||||
|
||||
belongs_to :build, class_name: "Ci::Build", foreign_key: :build_id, inverse_of: :trace_chunks
|
||||
belongs_to :build,
|
||||
->(trace_chunks) { in_partition(trace_chunks) },
|
||||
class_name: 'Ci::Build',
|
||||
foreign_key: :build_id,
|
||||
partition_foreign_key: :partition_id,
|
||||
inverse_of: :trace_chunks
|
||||
|
||||
partitionable scope: :build
|
||||
|
||||
|
|
|
|||
|
|
@ -168,6 +168,7 @@ module Ci
|
|||
def ensure_pending_state
|
||||
build_state = Ci::BuildPendingState.safe_find_or_create_by(
|
||||
build_id: build.id,
|
||||
partition_id: build.partition_id,
|
||||
state: params.fetch(:state),
|
||||
trace_checksum: trace_checksum,
|
||||
trace_bytesize: trace_bytesize,
|
||||
|
|
|
|||
|
|
@ -2712,6 +2712,15 @@
|
|||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: ci_low_urgency_cancel_redundant_pipelines
|
||||
:worker_name: Ci::LowUrgencyCancelRedundantPipelinesWorker
|
||||
:feature_category: :continuous_integration
|
||||
:has_external_dependencies: false
|
||||
:urgency: :low
|
||||
:resource_boundary: :unknown
|
||||
:weight: 1
|
||||
:idempotent: true
|
||||
:tags: []
|
||||
- :name: ci_parse_secure_file_metadata
|
||||
:worker_name: Ci::ParseSecureFileMetadataWorker
|
||||
:feature_category: :mobile_devops
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
# Scheduled pipelines rarely cancel other pipelines and we don't need to
|
||||
# use high urgency
|
||||
class LowUrgencyCancelRedundantPipelinesWorker < CancelRedundantPipelinesWorker
|
||||
urgency :low
|
||||
idempotent!
|
||||
end
|
||||
end
|
||||
|
|
@ -165,6 +165,8 @@
|
|||
- 1
|
||||
- - ci_llm_generate_config
|
||||
- 1
|
||||
- - ci_low_urgency_cancel_redundant_pipelines
|
||||
- 1
|
||||
- - ci_parse_secure_file_metadata
|
||||
- 1
|
||||
- - ci_runners_process_runner_version_update
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# This is noisy for draft MRs, so let's ignore this cop in draft mode since we have
|
||||
# rubocop watching this as well.
|
||||
return if helper.draft_mr?
|
||||
|
||||
# Danger should not comment when inline disables are added in the following files.
|
||||
no_suggestions_for_extensions = %w[.md]
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddReopenIssueOnExternalParticipantNoteToServiceDeskSettings < Gitlab::Database::Migration[2.2]
|
||||
milestone '16.7'
|
||||
|
||||
enable_lock_retries!
|
||||
|
||||
def change
|
||||
add_column :service_desk_settings, :reopen_issue_on_external_participant_note, :boolean, null: false, default: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
b05062e183719785e3d1313c4f1f59fce8b19c8f86ddb0ba53abcde96cb4ca03
|
||||
|
|
@ -23520,6 +23520,7 @@ CREATE TABLE service_desk_settings (
|
|||
custom_email text,
|
||||
service_desk_enabled boolean DEFAULT true NOT NULL,
|
||||
add_external_participants_from_cc boolean DEFAULT false NOT NULL,
|
||||
reopen_issue_on_external_participant_note boolean DEFAULT false NOT NULL,
|
||||
CONSTRAINT check_57a79552e1 CHECK ((char_length(custom_email) <= 255))
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -184,10 +184,10 @@ are available:
|
|||
|
||||
| Urgency | Duration in seconds | Notes |
|
||||
|------------|---------------------|-----------------------------------------------|
|
||||
| `:high` | 0.25s | |
|
||||
| `:medium` | 0.5s | |
|
||||
| `:default` | 1s | The default when nothing is specified. |
|
||||
| `:low` | 5s | |
|
||||
| `:high` | [0.25s](https://gitlab.com/gitlab-org/gitlab/-/blob/2f7a38fe48934b78f04233c4d2c81cde88a06da7/lib/gitlab/endpoint_attributes/config.rb#L8) | |
|
||||
| `:medium` | [0.5s](https://gitlab.com/gitlab-org/gitlab/-/blob/2f7a38fe48934b78f04233c4d2c81cde88a06da7/lib/gitlab/endpoint_attributes/config.rb#L9) | |
|
||||
| `:default` | [1s](https://gitlab.com/gitlab-org/gitlab/-/blob/2f7a38fe48934b78f04233c4d2c81cde88a06da7/lib/gitlab/endpoint_attributes/config.rb#L10) | The default when nothing is specified. |
|
||||
| `:low` | [5s](https://gitlab.com/gitlab-org/gitlab/-/blob/2f7a38fe48934b78f04233c4d2c81cde88a06da7/lib/gitlab/endpoint_attributes/config.rb#L11) | |
|
||||
|
||||
### Rails controller
|
||||
|
||||
|
|
|
|||
|
|
@ -277,6 +277,10 @@ declaring the subscription in `ee/lib/ee/gitlab/event_store.rb`.
|
|||
Subscriptions are stored in memory when the Rails app is loaded and they are immediately frozen.
|
||||
It's not possible to modify subscriptions at runtime.
|
||||
|
||||
NOTE:
|
||||
Before creating a subscription, make sure that the worker is already deployed to GitLab.com as the
|
||||
newly introduced workers are [not compatible with canary deployments](sidekiq/compatibility_across_updates.md#adding-new-workers).
|
||||
|
||||
### Conditional dispatch of events
|
||||
|
||||
A subscription can specify a condition when to accept an event:
|
||||
|
|
|
|||
|
|
@ -46,6 +46,8 @@ For more information on:
|
|||
gitlab_rails['omniauth_auto_link_saml_user'] = true
|
||||
```
|
||||
|
||||
Only the GitLab account's primary email address is matched against the email in the SAML response.
|
||||
|
||||
Alternatively, a user can manually link their SAML identity to an existing GitLab
|
||||
account by [enabling OmniAuth for an existing user](omniauth.md#enable-omniauth-for-an-existing-user).
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ Experimental features are:
|
|||
- UX not finalized, might be just quick action access.
|
||||
- Not announced in a release post.
|
||||
- Can be promoted in the user interface through [discovery moments](https://design.gitlab.com/usability/feature-management#discovery-moments), if needed.
|
||||
- Feedback issue to engage with team.
|
||||
|
||||
## Beta
|
||||
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ panels:
|
|||
For an overview of editing label filters in the configuration file, see [GitLab Value Streams Dashboard - Label filters demo](https://www.youtube.com/watch?v=4qDAHCxCfik).
|
||||
|
||||
Label filters are appended as query parameters to the URL of the drill-down report of each eligible metric and automatically applied.
|
||||
If the comparison panel from the configuration file is enabled with `filter_labels`, the drill-down links inherit the labels from the panel filter.
|
||||
|
||||
## Dashboard metrics and drill-down reports
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,11 @@ module Gitlab
|
|||
module Chain
|
||||
class CancelPendingPipelines < Chain::Base
|
||||
def perform!
|
||||
::Ci::CancelRedundantPipelinesWorker.perform_async(pipeline.id)
|
||||
if pipeline.schedule?
|
||||
::Ci::LowUrgencyCancelRedundantPipelinesWorker.perform_async(pipeline.id)
|
||||
else
|
||||
::Ci::CancelRedundantPipelinesWorker.perform_async(pipeline.id)
|
||||
end
|
||||
end
|
||||
|
||||
def break?
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ module Gitlab
|
|||
record: create_note,
|
||||
invalid_exception: InvalidNoteError,
|
||||
record_name: 'comment')
|
||||
|
||||
reopen_issue_on_external_participant_note
|
||||
end
|
||||
|
||||
def metrics_event
|
||||
|
|
@ -71,6 +73,34 @@ module Gitlab
|
|||
|
||||
raise UserNotFoundError unless from_address && author.verified_email?(from_address)
|
||||
end
|
||||
|
||||
def reopen_issue_on_external_participant_note
|
||||
return unless noteable.closed?
|
||||
return unless author == Users::Internal.support_bot
|
||||
return unless project.service_desk_setting&.reopen_issue_on_external_participant_note?
|
||||
|
||||
::Notes::CreateService.new(
|
||||
project,
|
||||
Users::Internal.support_bot,
|
||||
noteable: noteable,
|
||||
note: build_reopen_message,
|
||||
confidential: true
|
||||
).execute
|
||||
end
|
||||
|
||||
def build_reopen_message
|
||||
translated_text = s_(
|
||||
"ServiceDesk|This issue has been reopened because it received a new comment from an external participant."
|
||||
)
|
||||
|
||||
"#{assignees_references} :wave: #{translated_text}\n/reopen".lstrip
|
||||
end
|
||||
|
||||
def assignees_references
|
||||
return unless noteable.assignees.any?
|
||||
|
||||
noteable.assignees.map(&:to_reference).join(' ')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -44743,6 +44743,9 @@ msgstr ""
|
|||
msgid "ServiceDesk|The verification email wasn't received in time. There is a 30 minutes timeframe for verification emails to appear in your instance's Service Desk. Make sure that you have set up email forwarding correctly."
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|This issue has been reopened because it received a new comment from an external participant."
|
||||
msgstr ""
|
||||
|
||||
msgid "ServiceDesk|To enable Service Desk on this instance, an instance administrator must first set up incoming email."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ Contact: https://about.gitlab.com/security/disclosure/
|
|||
|
||||
Policy: https://hackerone.com/gitlab/
|
||||
|
||||
Acknowledgments: https://hackerone.com/gitlab/
|
||||
Acknowledgments: https://hackerone.com/gitlab/thanks
|
||||
Acknowledgments: https://about.gitlab.com/security/vulnerability-acknowledgements/
|
||||
|
||||
Canonical: https://gitlab.com/gitlab-org/gitlab/-/blob/master/security.txt
|
||||
|
|
@ -13,4 +13,6 @@ Canonical: https://gitlab.com/gitlab-org/gitlab/-/blob/master/security.txt
|
|||
Preferred-Languages: en
|
||||
Hiring: https://about.gitlab.com/jobs/
|
||||
|
||||
Expires: 2023-07-31T00:00:00Z
|
||||
Expires: 2024-12-31T00:00:00Z
|
||||
|
||||
# This file uses the format described at https://securitytxt.org/
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ require 'spec_helper'
|
|||
RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines, feature_category: :continuous_integration do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
|
||||
let_it_be_with_reload(:pipeline) { create(:ci_pipeline, project: project) }
|
||||
let_it_be(:command) { Gitlab::Ci::Pipeline::Chain::Command.new(project: project, current_user: user) }
|
||||
let_it_be(:step) { described_class.new(pipeline, command) }
|
||||
|
||||
|
|
@ -17,5 +17,18 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::CancelPendingPipelines, feature_cate
|
|||
|
||||
subject
|
||||
end
|
||||
|
||||
context 'with scheduled pipelines' do
|
||||
before do
|
||||
pipeline.source = :schedule
|
||||
end
|
||||
|
||||
it 'enqueues LowUrgencyCancelRedundantPipelinesWorker' do
|
||||
expect(Ci::LowUrgencyCancelRedundantPipelinesWorker)
|
||||
.to receive(:perform_async).with(pipeline.id)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Email::Handler::CreateNoteHandler do
|
||||
RSpec.describe Gitlab::Email::Handler::CreateNoteHandler, feature_category: :shared do
|
||||
include_context 'email shared context'
|
||||
|
||||
let_it_be(:user) { create(:user, email: 'jake@adventuretime.ooo') }
|
||||
let_it_be(:project) { create(:project, :public, :repository) }
|
||||
let_it_be_with_reload(:user) { create(:user, email: 'jake@adventuretime.ooo') }
|
||||
let_it_be(:project) { create(:project, :public, :repository) }
|
||||
|
||||
let(:noteable) { note.noteable }
|
||||
let(:note) { create(:diff_note_on_merge_request, project: project) }
|
||||
|
|
@ -133,14 +133,16 @@ RSpec.describe Gitlab::Email::Handler::CreateNoteHandler do
|
|||
end
|
||||
end
|
||||
|
||||
context 'mail key is in the References header' do
|
||||
context 'when mail key is in the References header' do
|
||||
let(:email_raw) { fixture_file('emails/reply_without_subaddressing_and_key_inside_references.eml') }
|
||||
|
||||
it_behaves_like 'an email that contains a mail key', 'References'
|
||||
end
|
||||
|
||||
context 'mail key is in the References header with a comma' do
|
||||
let(:email_raw) { fixture_file('emails/reply_without_subaddressing_and_key_inside_references_with_a_comma.eml') }
|
||||
context 'when mail key is in the References header with a comma' do
|
||||
let(:email_raw) do
|
||||
fixture_file('emails/reply_without_subaddressing_and_key_inside_references_with_a_comma.eml')
|
||||
end
|
||||
|
||||
it_behaves_like 'an email that contains a mail key', 'References'
|
||||
end
|
||||
|
|
@ -228,4 +230,96 @@ RSpec.describe Gitlab::Email::Handler::CreateNoteHandler do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when issue is closed' do
|
||||
let_it_be(:noteable) { create(:issue, :closed, :confidential, project: project) }
|
||||
let_it_be(:note) { create(:note, noteable: noteable, project: project) }
|
||||
|
||||
let!(:sent_notification) do
|
||||
allow(Gitlab::ServiceDesk).to receive(:enabled?).with(project: project).and_return(true)
|
||||
SentNotification.record_note(note, Users::Internal.support_bot.id)
|
||||
end
|
||||
|
||||
let(:reply_address) { "support+#{sent_notification.reply_key}@example.com" }
|
||||
let(:reopen_note) { noteable.notes.last }
|
||||
let(:email_raw) do
|
||||
<<~EMAIL
|
||||
From: from@example.com
|
||||
To: #{reply_address}
|
||||
Subject: Issue title
|
||||
|
||||
Issue description
|
||||
EMAIL
|
||||
end
|
||||
|
||||
before do
|
||||
stub_incoming_email_setting(enabled: true, address: 'support+%{key}@example.com')
|
||||
end
|
||||
|
||||
it 'does not reopen issue but adds external participants comment' do
|
||||
# Only 1 from received email
|
||||
expect { receiver.execute }.to change { noteable.notes.count }.by(1)
|
||||
expect(noteable).to be_closed
|
||||
end
|
||||
|
||||
context 'when reopen_issue_on_external_participant_note is true' do
|
||||
shared_examples 'an automatically reopened issue' do
|
||||
it 'reopens issue, adds external participants comment and reopen comment' do
|
||||
# 1 from received email and 1 reopen comment
|
||||
expect { receiver.execute }.to change { noteable.notes.count }.by(2)
|
||||
expect(noteable.reset).to be_open
|
||||
|
||||
expect(reopen_note).to be_confidential
|
||||
expect(reopen_note.author).to eq(Users::Internal.support_bot)
|
||||
expect(reopen_note.note).to include(reopen_comment_body)
|
||||
end
|
||||
end
|
||||
|
||||
let!(:settings) do
|
||||
create(:service_desk_setting, project: project, reopen_issue_on_external_participant_note: true)
|
||||
end
|
||||
|
||||
let(:reopen_comment_body) do
|
||||
s_(
|
||||
"ServiceDesk|This issue has been reopened because it received a new comment from an external participant."
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'an automatically reopened issue'
|
||||
|
||||
it 'does not contain an assignee mention' do
|
||||
receiver.execute
|
||||
expect(reopen_note.note).not_to include("@")
|
||||
end
|
||||
|
||||
context 'when issue is assigned to a user' do
|
||||
before do
|
||||
noteable.update!(assignees: [user])
|
||||
end
|
||||
|
||||
it_behaves_like 'an automatically reopened issue'
|
||||
|
||||
it 'contains an assignee mention' do
|
||||
receiver.execute
|
||||
expect(reopen_note.note).to include(user.to_reference)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when issue is assigned to multiple users' do
|
||||
let_it_be(:another_user) { create(:user) }
|
||||
|
||||
before do
|
||||
noteable.update!(assignees: [user, another_user])
|
||||
end
|
||||
|
||||
it_behaves_like 'an automatically reopened issue'
|
||||
|
||||
it 'contains two assignee mentions' do
|
||||
receiver.execute
|
||||
expect(reopen_note.note).to include(user.to_reference)
|
||||
expect(reopen_note.note).to include(another_user.to_reference)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Gitlab::Git::Compare do
|
||||
RSpec.describe Gitlab::Git::Compare, feature_category: :source_code_management do
|
||||
let_it_be(:repository) { create(:project, :repository).repository.raw }
|
||||
|
||||
let(:compare) { described_class.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: false) }
|
||||
|
|
|
|||
|
|
@ -196,5 +196,6 @@ build_service_desk_setting: # service_desk_setting
|
|||
- encrypted_custom_email_smtp_password_iv
|
||||
- custom_email_smtp_password
|
||||
- add_external_participants_from_cc
|
||||
- reopen_issue_on_external_participant_note
|
||||
remapped_attributes:
|
||||
project_key: service_desk_address
|
||||
|
|
|
|||
|
|
@ -5994,7 +5994,6 @@
|
|||
- './spec/lib/gitlab/email/failure_handler_spec.rb'
|
||||
- './spec/lib/gitlab/email/handler/create_issue_handler_spec.rb'
|
||||
- './spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb'
|
||||
- './spec/lib/gitlab/email/handler/create_note_handler_spec.rb'
|
||||
- './spec/lib/gitlab/email/handler/create_note_on_issuable_handler_spec.rb'
|
||||
- './spec/lib/gitlab/email/handler/service_desk_handler_spec.rb'
|
||||
- './spec/lib/gitlab/email/handler_spec.rb'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::LowUrgencyCancelRedundantPipelinesWorker, feature_category: :continuous_integration do
|
||||
it 'is labeled as low urgency' do
|
||||
expect(described_class.get_urgency).to eq(:low)
|
||||
end
|
||||
end
|
||||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
|
|
@ -157,12 +158,32 @@ func (p *Injector) newUploadRequest(ctx context.Context, params *entryParams, or
|
|||
func (p *Injector) unpackParams(sendData string) (*entryParams, error) {
|
||||
var params entryParams
|
||||
if err := p.Unpack(¶ms, sendData); err != nil {
|
||||
return nil, fmt.Errorf("dependency proxy: unpack sendData: %v", err)
|
||||
return nil, fmt.Errorf("dependency proxy: unpack sendData: %w", err)
|
||||
}
|
||||
|
||||
if err := p.validateParams(params); err != nil {
|
||||
return nil, fmt.Errorf("dependency proxy: invalid params: %w", err)
|
||||
}
|
||||
|
||||
return ¶ms, nil
|
||||
}
|
||||
|
||||
func (p *Injector) validateParams(params entryParams) error {
|
||||
var uploadMethod = params.UploadConfig.Method
|
||||
if uploadMethod != "" && uploadMethod != http.MethodPost && uploadMethod != http.MethodPut {
|
||||
return fmt.Errorf("invalid upload method %s", uploadMethod)
|
||||
}
|
||||
|
||||
var uploadUrl = params.UploadConfig.Url
|
||||
if uploadUrl != "" {
|
||||
if _, err := url.ParseRequestURI(uploadUrl); err != nil {
|
||||
return fmt.Errorf("invalid upload url %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Injector) uploadMethodFrom(params *entryParams) string {
|
||||
if params.UploadConfig.Method != "" {
|
||||
return params.UploadConfig.Method
|
||||
|
|
|
|||
|
|
@ -261,6 +261,20 @@ func TestInvalidUploadConfiguration(t *testing.T) {
|
|||
sendData map[string]interface{}
|
||||
}{
|
||||
{
|
||||
desc: "with an invalid overriden method",
|
||||
sendData: mergeMap(baseSendData, map[string]interface{}{
|
||||
"UploadConfig": map[string]string{
|
||||
"Method": "TEAPOT",
|
||||
},
|
||||
}),
|
||||
}, {
|
||||
desc: "with an invalid url",
|
||||
sendData: mergeMap(baseSendData, map[string]interface{}{
|
||||
"UploadConfig": map[string]string{
|
||||
"Url": "invalid_url",
|
||||
},
|
||||
}),
|
||||
}, {
|
||||
desc: "with an invalid headers",
|
||||
sendData: mergeMap(baseSendData, map[string]interface{}{
|
||||
"UploadConfig": map[string]interface{}{
|
||||
|
|
|
|||
|
|
@ -5,14 +5,23 @@ import (
|
|||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper"
|
||||
"gitlab.com/gitlab-org/gitlab/workhorse/internal/helper/nginx"
|
||||
)
|
||||
|
||||
const (
|
||||
// matches the default size used in httputil.ReverseProxy
|
||||
bufferPoolSize = 32 * 1024
|
||||
)
|
||||
|
||||
var (
|
||||
defaultTarget = helper.URLMustParse("http://localhost")
|
||||
|
||||
// pool is a buffer pool that is shared across all Proxy instances to maximize buffer reuse.
|
||||
pool = newBufferPool()
|
||||
)
|
||||
|
||||
type Proxy struct {
|
||||
|
|
@ -46,6 +55,7 @@ func NewProxy(myURL *url.URL, version string, roundTripper http.RoundTripper, op
|
|||
u.Path = ""
|
||||
p.reverseProxy = httputil.NewSingleHostReverseProxy(&u)
|
||||
p.reverseProxy.Transport = roundTripper
|
||||
p.reverseProxy.BufferPool = pool
|
||||
chainDirector(p.reverseProxy, func(r *http.Request) {
|
||||
r.Header.Set("Gitlab-Workhorse", p.Version)
|
||||
r.Header.Set("Gitlab-Workhorse-Proxy-Start", fmt.Sprintf("%d", time.Now().UnixNano()))
|
||||
|
|
@ -104,3 +114,25 @@ func (p *Proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
p.reverseProxy.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
type bufferPool struct {
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
func newBufferPool() *bufferPool {
|
||||
return &bufferPool{
|
||||
pool: sync.Pool{
|
||||
New: func() any {
|
||||
return make([]byte, bufferPoolSize)
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (bp *bufferPool) Get() []byte {
|
||||
return bp.pool.Get().([]byte)
|
||||
}
|
||||
|
||||
func (bp *bufferPool) Put(v []byte) {
|
||||
bp.pool.Put(v) //lint:ignore SA6002 we either allocate manually to satisfy the linter or let the compiler allocate for us and silence the linter
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBufferPool(t *testing.T) {
|
||||
bp := newBufferPool()
|
||||
|
||||
b := bp.Get()
|
||||
assert.Len(t, b, bufferPoolSize)
|
||||
|
||||
bp.Put(b) // just test that it doesn't panic or something like that
|
||||
}
|
||||
Loading…
Reference in New Issue