Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Better: Prepend .gitconfig with random hash to allow concurrency #9219

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
18 changes: 11 additions & 7 deletions common/lib/dependabot/shared_helpers.rb
Expand Up @@ -10,6 +10,7 @@
require "shellwords"
require "sorbet-runtime"
require "tmpdir"
require "securerandom"

require "dependabot/credential"
require "dependabot/simple_instrumentor"
Expand All @@ -22,7 +23,6 @@ module Dependabot
module SharedHelpers
extend T::Sig

GIT_CONFIG_GLOBAL_PATH = T.let(File.expand_path(".gitconfig", Utils::BUMP_TMP_DIR_PATH), String)
USER_AGENT = T.let(
"dependabot-core/#{Dependabot::VERSION} " \
"#{Excon::USER_AGENT} ruby/#{RUBY_VERSION} " \
Expand Down Expand Up @@ -258,18 +258,19 @@ def self.with_git_configured(credentials:, &_block)
FileUtils.mkdir_p(Utils::BUMP_TMP_DIR_PATH)

previous_config = ENV.fetch("GIT_CONFIG_GLOBAL", nil)
git_config_global_path = File.expand_path("#{SecureRandom.hex(16)}.gitconfig", Utils::BUMP_TMP_DIR_PATH)
ylecuyer marked this conversation as resolved.
Show resolved Hide resolved

begin
ENV["GIT_CONFIG_GLOBAL"] = GIT_CONFIG_GLOBAL_PATH
configure_git_to_use_https_with_credentials(credentials, safe_directories)
ENV["GIT_CONFIG_GLOBAL"] = git_config_global_path
configure_git_to_use_https_with_credentials(credentials, safe_directories, git_config_global_path)
yield
ensure
ENV["GIT_CONFIG_GLOBAL"] = previous_config
end
rescue Errno::ENOSPC => e
raise Dependabot::OutOfDisk, e.message
ensure
FileUtils.rm_f(GIT_CONFIG_GLOBAL_PATH)
FileUtils.rm_f(T.must(git_config_global_path))
end

# Handle SCP-style git URIs
Expand All @@ -286,9 +287,12 @@ def self.credential_helper_path
end

# rubocop:disable Metrics/PerceivedComplexity
sig { params(credentials: T::Array[Dependabot::Credential], safe_directories: T::Array[String]).void }
def self.configure_git_to_use_https_with_credentials(credentials, safe_directories)
File.open(GIT_CONFIG_GLOBAL_PATH, "w") do |file|
sig do
params(credentials: T::Array[Dependabot::Credential], safe_directories: T::Array[String],
git_config_global_path: String).void
end
def self.configure_git_to_use_https_with_credentials(credentials, safe_directories, git_config_global_path)
File.open(git_config_global_path, "w") do |file|
file << "# Generated by dependabot/dependabot-core"
end

Expand Down
9 changes: 6 additions & 3 deletions common/spec/dependabot/shared_helpers_spec.rb
Expand Up @@ -409,7 +409,10 @@ def with_git_configured(&block)
Dependabot::SharedHelpers.with_git_configured(credentials: credentials, &block)
end

let(:git_config_path) { File.expand_path(".gitconfig", tmp) }
before do
allow(SecureRandom).to receive(:hex).and_return("XXXXXXXXXXXXXXXX")
end
let(:git_config_path) { File.expand_path("XXXXXXXXXXXXXXXX.gitconfig", tmp) }
let(:configured_git_config) { with_git_configured { `cat #{git_config_path}` } }
let(:configured_git_credentials) { with_git_configured { `cat #{Dir.pwd}/git.store` } }

Expand Down Expand Up @@ -553,10 +556,10 @@ def with_git_configured(&block)
context "when the host has run out of disk space" do
before do
allow(File).to receive(:open)
.with(described_class::GIT_CONFIG_GLOBAL_PATH, anything)
.with(git_config_path, anything)
.and_raise(Errno::ENOSPC)
allow(FileUtils).to receive(:rm_f)
.with(described_class::GIT_CONFIG_GLOBAL_PATH)
.with(git_config_path)
end

specify { expect { configured_git_config }.to raise_error(Dependabot::OutOfDisk) }
Expand Down