diff --git a/ee/lib/ee/gitlab/checks/push_rule_check.rb b/ee/lib/ee/gitlab/checks/push_rule_check.rb index 441aeafa4a1012785398af02f1a6b1c8d13644a6..abfa27c89d44812b8da0d4a6e9b8782a3be9c859 100644 --- a/ee/lib/ee/gitlab/checks/push_rule_check.rb +++ b/ee/lib/ee/gitlab/checks/push_rule_check.rb @@ -41,18 +41,23 @@ def run_checks_in_sequence! check_file_size! end - # Run the checks in separate threads for performance benefits + # Run the checks in separate threads for performance benefits. + # + # The git hook environment is currently set in the current thread + # in lib/api/internal/base.rb. This needs to be passed into the + # child threads we spawn here. # # @return [Nil] returns nil unless an error is raised # @raise [Gitlab::GitAccess::ForbiddenError] if any check fails def run_checks_in_parallel! + git_env = ::Gitlab::Git::HookEnv.all(project.repository.gl_repository) @threads = [] - parallelize do + parallelize(git_env) do check_tag_or_branch! end - parallelize do + parallelize(git_env) do check_file_size! end @@ -73,8 +78,9 @@ def run_checks_in_parallel! # Runs a block inside a new thread. This thread will # exit immediately upon an exception being raised. # + # @param git_env [Hash] the current git environment # @raise [Gitlab::GitAccess::ForbiddenError] - def parallelize + def parallelize(git_env) @threads << Thread.new do Thread.current.tap do |t| t.name = "push_rule_check" @@ -82,7 +88,11 @@ def parallelize t.report_on_exception = false end - yield + ::Gitlab::WithRequestStore.with_request_store do + ::Gitlab::Git::HookEnv.set(project.repository.gl_repository, git_env) + + yield + end ensure # rubocop: disable Layout/RescueEnsureAlignment ActiveRecord::Base.clear_active_connections! end diff --git a/ee/spec/lib/ee/gitlab/checks/push_rule_check_spec.rb b/ee/spec/lib/ee/gitlab/checks/push_rule_check_spec.rb index bb860b111a9e1decc4b3b94e7514df2f4cd4bbdc..053e272c0dc67ee1a1c1ea9d17553c5c074da198 100644 --- a/ee/spec/lib/ee/gitlab/checks/push_rule_check_spec.rb +++ b/ee/spec/lib/ee/gitlab/checks/push_rule_check_spec.rb @@ -59,7 +59,24 @@ end describe '#validate!' do - it_behaves_like "push checks" + context "parallel push checks" do + it_behaves_like "push checks" + + before do + ::Gitlab::Git::HookEnv.set(project.repository.gl_repository, + "GIT_OBJECT_DIRECTORY_RELATIVE" => "objects", + "GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE" => []) + end + + it "sets the git env correctly for all hooks", :request_store do + expect(Gitaly::Repository).to receive(:new) + .with(a_hash_including(git_object_directory: "objects")) + .and_call_original + + # This push fails because of the commit message check + expect { subject.validate! }.to raise_error(Gitlab::GitAccess::ForbiddenError) + end + end context ":parallel_push_checks feature is disabled" do before do