Commit e61325ff authored by Alejandro Rodríguez's avatar Alejandro Rodríguez

Expand components version specification format to allow branches

Currently we specify versions for Gitlab-Shell, Workhorse and Gitaly
using version strings, to which we prepend 'v' and assume are tags.
These changes allow branches or tags with other name formats to be
specified by prepending '=' to the version string (á la govendor).

We also simplify the process to reset to the given version (now a
branch or tag): Right now there's a check to supposedly try to avoid
fetching from the remote the version if it already exist locally. But
the previous logic already clones if the directory doesn't exist or
fetches if it does, so this check is pointless. We can safely assume the
version exists once we get to the reset stage.
parent 0fa00e84
...@@ -7,10 +7,10 @@ namespace :gitlab do ...@@ -7,10 +7,10 @@ namespace :gitlab do
abort %(Please specify the directory where you want to install gitaly:\n rake "gitlab:gitaly:install[/home/git/gitaly]") abort %(Please specify the directory where you want to install gitaly:\n rake "gitlab:gitaly:install[/home/git/gitaly]")
end end
tag = "v#{Gitlab::GitalyClient.expected_server_version}" version = Gitlab::GitalyClient.expected_server_version
repo = 'https://gitlab.com/gitlab-org/gitaly.git' repo = 'https://gitlab.com/gitlab-org/gitaly.git'
checkout_or_clone_tag(tag: tag, repo: repo, target_dir: args.dir) checkout_or_clone_version(version: version, repo: repo, target_dir: args.dir)
_, status = Gitlab::Popen.popen(%w[which gmake]) _, status = Gitlab::Popen.popen(%w[which gmake])
command = status.zero? ? 'gmake' : 'make' command = status.zero? ? 'gmake' : 'make'
......
namespace :gitlab do namespace :gitlab do
namespace :shell do namespace :shell do
desc "GitLab | Install or upgrade gitlab-shell" desc "GitLab | Install or upgrade gitlab-shell"
task :install, [:tag, :repo] => :environment do |t, args| task :install, [:repo] => :environment do |t, args|
warn_user_is_not_gitlab warn_user_is_not_gitlab
default_version = Gitlab::Shell.version_required default_version = Gitlab::Shell.version_required
default_version_tag = "v#{default_version}" args.with_defaults(repo: 'https://gitlab.com/gitlab-org/gitlab-shell.git')
args.with_defaults(tag: default_version_tag, repo: 'https://gitlab.com/gitlab-org/gitlab-shell.git')
gitlab_url = Gitlab.config.gitlab.url gitlab_url = Gitlab.config.gitlab.url
# gitlab-shell requires a / at the end of the url # gitlab-shell requires a / at the end of the url
gitlab_url += '/' unless gitlab_url.end_with?('/') gitlab_url += '/' unless gitlab_url.end_with?('/')
target_dir = Gitlab.config.gitlab_shell.path target_dir = Gitlab.config.gitlab_shell.path
checkout_or_clone_tag(tag: default_version_tag, repo: args.repo, target_dir: target_dir) checkout_or_clone_version(version: default_version, repo: args.repo, target_dir: target_dir)
# Make sure we're on the right tag # Make sure we're on the right tag
Dir.chdir(target_dir) do Dir.chdir(target_dir) do
......
...@@ -147,41 +147,30 @@ module Gitlab ...@@ -147,41 +147,30 @@ module Gitlab
Rails.env.test? ? Rails.root.join('tmp/tests') : Gitlab.config.gitlab.user_home Rails.env.test? ? Rails.root.join('tmp/tests') : Gitlab.config.gitlab.user_home
end end
def checkout_or_clone_tag(tag:, repo:, target_dir:) def checkout_or_clone_version(version:, repo:, target_dir:)
if Dir.exist?(target_dir) version =
checkout_tag(tag, target_dir) if version.starts_with?("=")
else version.sub(/\A=/, '') # tag or branch
clone_repo(repo, target_dir) else
end "v#{version}" # tag
end
reset_to_tag(tag, target_dir) clone_repo(repo, target_dir) unless Dir.exist?(target_dir)
checkout_version(version, target_dir)
reset_to_version(version, target_dir)
end end
def clone_repo(repo, target_dir) def clone_repo(repo, target_dir)
run_command!(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{target_dir}]) run_command!(%W[#{Gitlab.config.git.bin_path} clone -- #{repo} #{target_dir}])
end end
def checkout_tag(tag, target_dir) def checkout_version(version, target_dir)
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} fetch --tags --quiet]) run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} fetch --quiet])
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} checkout --quiet #{tag}]) run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} checkout --quiet #{version}])
end end
def reset_to_tag(tag_wanted, target_dir) def reset_to_version(version, target_dir)
tag = run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} reset --hard #{version}])
begin
# First try to checkout without fetching
# to avoid stalling tests if the Internet is down.
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- #{tag_wanted}])
rescue Gitlab::TaskFailedError
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} fetch origin])
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} describe -- origin/#{tag_wanted}])
end
if tag
run_command!(%W[#{Gitlab.config.git.bin_path} -C #{target_dir} reset --hard #{tag.strip}])
else
raise Gitlab::TaskFailedError
end
end end
end end
end end
...@@ -7,10 +7,10 @@ namespace :gitlab do ...@@ -7,10 +7,10 @@ namespace :gitlab do
abort %(Please specify the directory where you want to install gitlab-workhorse:\n rake "gitlab:workhorse:install[/home/git/gitlab-workhorse]") abort %(Please specify the directory where you want to install gitlab-workhorse:\n rake "gitlab:workhorse:install[/home/git/gitlab-workhorse]")
end end
tag = "v#{Gitlab::Workhorse.version}" version = Gitlab::Workhorse.version
repo = 'https://gitlab.com/gitlab-org/gitlab-workhorse.git' repo = 'https://gitlab.com/gitlab-org/gitlab-workhorse.git'
checkout_or_clone_tag(tag: tag, repo: repo, target_dir: args.dir) checkout_or_clone_version(version: version, repo: repo, target_dir: args.dir)
_, status = Gitlab::Popen.popen(%w[which gmake]) _, status = Gitlab::Popen.popen(%w[which gmake])
command = status.zero? ? 'gmake' : 'make' command = status.zero? ? 'gmake' : 'make'
......
...@@ -8,7 +8,7 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -8,7 +8,7 @@ describe 'gitlab:gitaly namespace rake task' do
describe 'install' do describe 'install' do
let(:repo) { 'https://gitlab.com/gitlab-org/gitaly.git' } let(:repo) { 'https://gitlab.com/gitlab-org/gitaly.git' }
let(:clone_path) { Rails.root.join('tmp/tests/gitaly').to_s } let(:clone_path) { Rails.root.join('tmp/tests/gitaly').to_s }
let(:tag) { "v#{File.read(Rails.root.join(Gitlab::GitalyClient::SERVER_VERSION_FILE)).chomp}" } let(:version) { File.read(Rails.root.join(Gitlab::GitalyClient::SERVER_VERSION_FILE)).chomp }
context 'no dir given' do context 'no dir given' do
it 'aborts and display a help message' do it 'aborts and display a help message' do
...@@ -21,7 +21,7 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -21,7 +21,7 @@ describe 'gitlab:gitaly namespace rake task' do
context 'when an underlying Git command fail' do context 'when an underlying Git command fail' do
it 'aborts and display a help message' do it 'aborts and display a help message' do
expect_any_instance_of(Object). expect_any_instance_of(Object).
to receive(:checkout_or_clone_tag).and_raise 'Git error' to receive(:checkout_or_clone_version).and_raise 'Git error'
expect { run_rake_task('gitlab:gitaly:install', clone_path) }.to raise_error 'Git error' expect { run_rake_task('gitlab:gitaly:install', clone_path) }.to raise_error 'Git error'
end end
...@@ -32,9 +32,9 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -32,9 +32,9 @@ describe 'gitlab:gitaly namespace rake task' do
expect(Dir).to receive(:chdir).with(clone_path) expect(Dir).to receive(:chdir).with(clone_path)
end end
it 'calls checkout_or_clone_tag with the right arguments' do it 'calls checkout_or_clone_version with the right arguments' do
expect_any_instance_of(Object). expect_any_instance_of(Object).
to receive(:checkout_or_clone_tag).with(tag: tag, repo: repo, target_dir: clone_path) to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
run_rake_task('gitlab:gitaly:install', clone_path) run_rake_task('gitlab:gitaly:install', clone_path)
end end
...@@ -48,7 +48,7 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -48,7 +48,7 @@ describe 'gitlab:gitaly namespace rake task' do
context 'gmake is available' do context 'gmake is available' do
before do before do
expect_any_instance_of(Object).to receive(:checkout_or_clone_tag) expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
allow_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true) allow_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
end end
...@@ -62,7 +62,7 @@ describe 'gitlab:gitaly namespace rake task' do ...@@ -62,7 +62,7 @@ describe 'gitlab:gitaly namespace rake task' do
context 'gmake is not available' do context 'gmake is not available' do
before do before do
expect_any_instance_of(Object).to receive(:checkout_or_clone_tag) expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
allow_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true) allow_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
end end
......
...@@ -10,19 +10,38 @@ describe Gitlab::TaskHelpers do ...@@ -10,19 +10,38 @@ describe Gitlab::TaskHelpers do
let(:repo) { 'https://gitlab.com/gitlab-org/gitlab-test.git' } let(:repo) { 'https://gitlab.com/gitlab-org/gitlab-test.git' }
let(:clone_path) { Rails.root.join('tmp/tests/task_helpers_tests').to_s } let(:clone_path) { Rails.root.join('tmp/tests/task_helpers_tests').to_s }
let(:version) { '1.1.0' }
let(:tag) { 'v1.1.0' } let(:tag) { 'v1.1.0' }
describe '#checkout_or_clone_tag' do describe '#checkout_or_clone_version' do
before do before do
allow(subject).to receive(:run_command!) allow(subject).to receive(:run_command!)
expect(subject).to receive(:reset_to_tag).with(tag, clone_path)
end end
context 'target_dir does not exist' do it 'checkout the version and reset to it' do
it 'clones the repo, retrieve the tag from origin, and checkout the tag' do expect(subject).to receive(:checkout_version).with(tag, clone_path)
expect(subject).to receive(:reset_to_version).with(tag, clone_path)
subject.checkout_or_clone_version(version: version, repo: repo, target_dir: clone_path)
end
context 'with a branch version' do
let(:version) { '=branch_name' }
let(:branch) { 'branch_name' }
it 'checkout the version and reset to it with a branch name' do
expect(subject).to receive(:checkout_version).with(branch, clone_path)
expect(subject).to receive(:reset_to_version).with(branch, clone_path)
subject.checkout_or_clone_version(version: version, repo: repo, target_dir: clone_path)
end
end
context "target_dir doesn't exist" do
it 'clones the repo' do
expect(subject).to receive(:clone_repo).with(repo, clone_path) expect(subject).to receive(:clone_repo).with(repo, clone_path)
subject.checkout_or_clone_tag(tag: tag, repo: repo, target_dir: clone_path) subject.checkout_or_clone_version(version: version, repo: repo, target_dir: clone_path)
end end
end end
...@@ -31,10 +50,10 @@ describe Gitlab::TaskHelpers do ...@@ -31,10 +50,10 @@ describe Gitlab::TaskHelpers do
expect(Dir).to receive(:exist?).and_return(true) expect(Dir).to receive(:exist?).and_return(true)
end end
it 'fetch and checkout the tag' do it "doesn't clone the repository" do
expect(subject).to receive(:checkout_tag).with(tag, clone_path) expect(subject).not_to receive(:clone_repo)
subject.checkout_or_clone_tag(tag: tag, repo: repo, target_dir: clone_path) subject.checkout_or_clone_version(version: version, repo: repo, target_dir: clone_path)
end end
end end
end end
...@@ -48,49 +67,23 @@ describe Gitlab::TaskHelpers do ...@@ -48,49 +67,23 @@ describe Gitlab::TaskHelpers do
end end
end end
describe '#checkout_tag' do describe '#checkout_version' do
it 'clones the repo in the target dir' do it 'clones the repo in the target dir' do
expect(subject). expect(subject).
to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --tags --quiet]) to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch --quiet])
expect(subject). expect(subject).
to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}]) to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} checkout --quiet #{tag}])
subject.checkout_tag(tag, clone_path) subject.checkout_version(tag, clone_path)
end end
end end
describe '#reset_to_tag' do describe '#reset_to_version' do
let(:tag) { 'v1.1.0' } it 'resets --hard to the given version' do
before do
expect(subject). expect(subject).
to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}]) to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} reset --hard #{tag}])
end
context 'when the tag is not checked out locally' do subject.reset_to_version(tag, clone_path)
before do
expect(subject).
to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_raise(Gitlab::TaskFailedError)
end
it 'fetch origin, ensure the tag exists, and resets --hard to the given tag' do
expect(subject).
to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} fetch origin])
expect(subject).
to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- origin/#{tag}]).and_return(tag)
subject.reset_to_tag(tag, clone_path)
end
end
context 'when the tag is checked out locally' do
before do
expect(subject).
to receive(:run_command!).with(%W[#{Gitlab.config.git.bin_path} -C #{clone_path} describe -- #{tag}]).and_return(tag)
end
it 'resets --hard to the given tag' do
subject.reset_to_tag(tag, clone_path)
end
end end
end end
end end
...@@ -8,7 +8,7 @@ describe 'gitlab:workhorse namespace rake task' do ...@@ -8,7 +8,7 @@ describe 'gitlab:workhorse namespace rake task' do
describe 'install' do describe 'install' do
let(:repo) { 'https://gitlab.com/gitlab-org/gitlab-workhorse.git' } let(:repo) { 'https://gitlab.com/gitlab-org/gitlab-workhorse.git' }
let(:clone_path) { Rails.root.join('tmp/tests/gitlab-workhorse').to_s } let(:clone_path) { Rails.root.join('tmp/tests/gitlab-workhorse').to_s }
let(:tag) { "v#{File.read(Rails.root.join(Gitlab::Workhorse::VERSION_FILE)).chomp}" } let(:version) { File.read(Rails.root.join(Gitlab::Workhorse::VERSION_FILE)).chomp }
context 'no dir given' do context 'no dir given' do
it 'aborts and display a help message' do it 'aborts and display a help message' do
...@@ -21,7 +21,7 @@ describe 'gitlab:workhorse namespace rake task' do ...@@ -21,7 +21,7 @@ describe 'gitlab:workhorse namespace rake task' do
context 'when an underlying Git command fail' do context 'when an underlying Git command fail' do
it 'aborts and display a help message' do it 'aborts and display a help message' do
expect_any_instance_of(Object). expect_any_instance_of(Object).
to receive(:checkout_or_clone_tag).and_raise 'Git error' to receive(:checkout_or_clone_version).and_raise 'Git error'
expect { run_rake_task('gitlab:workhorse:install', clone_path) }.to raise_error 'Git error' expect { run_rake_task('gitlab:workhorse:install', clone_path) }.to raise_error 'Git error'
end end
...@@ -32,9 +32,9 @@ describe 'gitlab:workhorse namespace rake task' do ...@@ -32,9 +32,9 @@ describe 'gitlab:workhorse namespace rake task' do
expect(Dir).to receive(:chdir).with(clone_path) expect(Dir).to receive(:chdir).with(clone_path)
end end
it 'calls checkout_or_clone_tag with the right arguments' do it 'calls checkout_or_clone_version with the right arguments' do
expect_any_instance_of(Object). expect_any_instance_of(Object).
to receive(:checkout_or_clone_tag).with(tag: tag, repo: repo, target_dir: clone_path) to receive(:checkout_or_clone_version).with(version: version, repo: repo, target_dir: clone_path)
run_rake_task('gitlab:workhorse:install', clone_path) run_rake_task('gitlab:workhorse:install', clone_path)
end end
...@@ -48,7 +48,7 @@ describe 'gitlab:workhorse namespace rake task' do ...@@ -48,7 +48,7 @@ describe 'gitlab:workhorse namespace rake task' do
context 'gmake is available' do context 'gmake is available' do
before do before do
expect_any_instance_of(Object).to receive(:checkout_or_clone_tag) expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
allow_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true) allow_any_instance_of(Object).to receive(:run_command!).with(['gmake']).and_return(true)
end end
...@@ -62,7 +62,7 @@ describe 'gitlab:workhorse namespace rake task' do ...@@ -62,7 +62,7 @@ describe 'gitlab:workhorse namespace rake task' do
context 'gmake is not available' do context 'gmake is not available' do
before do before do
expect_any_instance_of(Object).to receive(:checkout_or_clone_tag) expect_any_instance_of(Object).to receive(:checkout_or_clone_version)
allow_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true) allow_any_instance_of(Object).to receive(:run_command!).with(['make']).and_return(true)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment