diff --git a/lib/gitlab/build/info.rb b/lib/gitlab/build/info.rb index ea165a3cdc9db44649cce76db8b49e1d5f09fe5b_bGliL2dpdGxhYi9idWlsZC9pbmZvLnJi..65fe06b881d29ca5ec3a5d6754a8d067afee803e_bGliL2dpdGxhYi9idWlsZC9pbmZvLnJi 100644 --- a/lib/gitlab/build/info.rb +++ b/lib/gitlab/build/info.rb @@ -9,8 +9,6 @@ module Build class Info - TagsNotFoundError = Class.new(StandardError) - DEPLOYER_OS_MAPPING = { 'AUTO_DEPLOY_ENVIRONMENT' => 'ubuntu-xenial', 'PATCH_DEPLOY_ENVIRONMENT' => 'ubuntu-bionic', @@ -72,6 +70,10 @@ "#{semver}-#{Gitlab::BuildIteration.new.build_iteration}" end + def sorted_tags_for_edition + `git -c versionsort.prereleaseSuffix=rc tag -l '#{Info.tag_match_pattern}' --sort=-v:refname`.split("\n") + end + # TODO, merge latest_tag with latest_stable_tag # TODO, add tests, needs a repo clone def latest_tag @@ -79,5 +81,7 @@ return fact_from_file end - version = branch_name.delete_suffix('-stable').tr('-', '.') if Build::Check.on_stable_branch? + tags = sorted_tags_for_edition + + return if tags.empty? @@ -83,5 +87,10 @@ - `git -c versionsort.prereleaseSuffix=rc tag -l '#{version}#{Info.tag_match_pattern}' --sort=-v:refname | head -1`.chomp + version = branch_name.delete_suffix('-stable').tr('-', '.') if Build::Check.on_stable_branch? + output = tags.find { |t| t.start_with?(version) } if version + + # If no tags corresponding to the stable branch version was found, we + # fall back to the latest available tag + output || tags.first end def latest_stable_tag(level: 1) @@ -89,5 +98,10 @@ return fact_from_file end + # Exclude RC tags so that we only have stable tags. + stable_tags = sorted_tags_for_edition.reject { |t| t.include?('rc') } + + return if stable_tags.empty? + version = branch_name.delete_suffix('-stable').tr('-', '.') if Build::Check.on_stable_branch? @@ -92,4 +106,14 @@ version = branch_name.delete_suffix('-stable').tr('-', '.') if Build::Check.on_stable_branch? + results = stable_tags.select { |t| t.start_with?(version) } if version + + # If no tags corresponding to the stable branch version was found, we + # fall back to the latest available stable tag + output = if results.nil? || results.empty? + stable_tags + else + results + end + # Level decides tag at which position you want. Level one gives you # latest stable tag, two gives you the one just before it and so on. @@ -94,16 +118,13 @@ # Level decides tag at which position you want. Level one gives you # latest stable tag, two gives you the one just before it and so on. - output = `git -c versionsort.prereleaseSuffix=rc tag -l '#{version}#{Info.tag_match_pattern}' --sort=-v:refname | awk '!/rc/' | head -#{level}`&.split("\n")&.last - - # If no tags exist that start with the specified version, we need to - # fall back to the available latest stable tag. For that, we run the - # same command without the version in the filter argument. - raise TagsNotFoundError if output.nil? - - output - rescue TagsNotFoundError - puts "No tags found in #{version}.x series. Falling back to latest available tag." - `git -c versionsort.prereleaseSuffix=rc tag -l '#{Info.tag_match_pattern}' --sort=-v:refname | awk '!/rc/' | head -#{level}`.split("\n").last + # Since arrays start from 0, we subtract 1 from the specified level to + # get the index. If the specified level is more than the number of + # tags, we return the last tag. + if level >= output.length + output.last + else + output[level - 1] + end end def docker_tag diff --git a/spec/lib/gitlab/build/info_spec.rb b/spec/lib/gitlab/build/info_spec.rb index ea165a3cdc9db44649cce76db8b49e1d5f09fe5b_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2luZm9fc3BlYy5yYg==..65fe06b881d29ca5ec3a5d6754a8d067afee803e_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2luZm9fc3BlYy5yYg== 100644 --- a/spec/lib/gitlab/build/info_spec.rb +++ b/spec/lib/gitlab/build/info_spec.rb @@ -7,6 +7,11 @@ stub_default_package_version stub_env_var('GITLAB_ALTERNATIVE_REPO', nil) stub_env_var('ALTERNATIVE_PRIVATE_TOKEN', nil) + + ce_tags = "16.1.1+ce.0\n16.0.0+rc42.ce.0\n15.11.1+ce.0\n15.11.0+ce.0\n15.10.0+ce.0\n15.10.0+rc42.ce.0" + ee_tags = "16.1.1+ee.0\n16.0.0+rc42.ee.0\n15.11.1+ee.0\n15.11.0+ee.0\n15.10.0+ee.0\n15.10.0+rc42.ee.0" + allow(described_class).to receive(:`).with(/git -c versionsort.*ce/).and_return(ce_tags) + allow(described_class).to receive(:`).with(/git -c versionsort.*ee/).and_return(ee_tags) end describe '.package' do @@ -86,7 +91,4 @@ end end - # Specs for latest_tag and for latest_stable_tag are not really useful since - # we are stubbing out shell out to git. However, they are showing what we - # expect to see. describe '.latest_tag' do @@ -92,4 +94,4 @@ describe '.latest_tag' do - context 'when running against stable branches' do + context 'on CE edition' do before do stub_is_ee(false) @@ -94,7 +96,4 @@ before do stub_is_ee(false) - stub_env_var('CI_COMMIT_BRANCH', '14-10-stable') - allow(described_class).to receive(:`).with(/git describe --exact-match/).and_return('12.121.12+rc7.ce.0') - allow(described_class).to receive(:`).with(/git -c versionsort.prereleaseSuffix=rc tag -l /).and_return('12.121.12+rc7.ce.0') end @@ -99,5 +98,18 @@ end - it 'calls the shell command with correct arguments' do - expect(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '14.10*[+.]ce.*' --sort=-v:refname | head -1") + context 'on stable branch' do + context 'when tags already exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '15-10-stable') + end + + it 'returns the latest tag in the stable version series' do + expect(described_class.latest_tag).to eq('15.10.0+ce.0') + end + end + + context 'when tags does not exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-5-stable') + end @@ -103,5 +115,28 @@ - described_class.latest_tag + it 'returns the latest available tag' do + expect(described_class.latest_tag).to eq('16.1.1+ce.0') + end + end + + context 'when latest tag in the series is an RC tag' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-0-stable') + end + + it 'returns the RC tag' do + expect(described_class.latest_tag).to eq('16.0.0+rc42.ce.0') + end + end + end + + context 'on feature branch' do + before do + stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + end + + it 'returns the latest available tag' do + expect(described_class.latest_tag).to eq('16.1.1+ce.0') + end end end @@ -105,5 +140,5 @@ end end - describe 'for CE' do + context 'on EE edition' do before do @@ -109,11 +144,4 @@ before do - stub_env_var('CI_COMMIT_BRANCH', 'foo-feature-branch') - stub_is_ee(false) - allow(described_class).to receive(:`).with("git describe --exact-match 2>/dev/null").and_return('12.121.12+rc7.ce.0') - allow(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '*[+.]ce.*' --sort=-v:refname | head -1").and_return('12.121.12+rc7.ce.0') - end - - it 'returns the version of correct edition' do - expect(described_class.latest_tag).to eq('12.121.12+rc7.ce.0') + stub_is_ee(true) end @@ -118,5 +146,13 @@ end - it 'calls the shell command with correct arguments' do - expect(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '*[+.]ce.*' --sort=-v:refname | head -1") + context 'on stable branch' do + context 'when tags already exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '15-10-stable') + end + + it 'returns the latest tag in the stable version series' do + expect(described_class.latest_tag).to eq('15.10.0+ee.0') + end + end @@ -122,5 +158,11 @@ - described_class.latest_tag - end - end + context 'when tags does not exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-5-stable') + end + + it 'returns the latest available tag' do + expect(described_class.latest_tag).to eq('16.1.1+ee.0') + end + end @@ -126,8 +168,12 @@ - describe 'for EE' do - before do - stub_env_var('CI_COMMIT_BRANCH', 'foo-feature-branch') - stub_is_ee(true) - allow(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '*[+.]ee.*' --sort=-v:refname | head -1").and_return('12.121.12+rc7.ee.0') + context 'when latest tag in the series is an RC tag' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-0-stable') + end + + it 'returns the RC tag' do + expect(described_class.latest_tag).to eq('16.0.0+rc42.ee.0') + end + end end @@ -132,9 +178,15 @@ end - it 'returns the version of correct edition' do - expect(described_class.latest_tag).to eq('12.121.12+rc7.ee.0') + context 'on feature branch' do + before do + stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + end + + it 'returns the latest available tag' do + expect(described_class.latest_tag).to eq('16.1.1+ee.0') + end end end end describe '.latest_stable_tag' do @@ -136,7 +188,7 @@ end end end describe '.latest_stable_tag' do - describe 'for CE' do + context 'on CE edition' do before do @@ -142,7 +194,4 @@ before do - stub_env_var('CI_COMMIT_BRANCH', 'foo-feature-branch') - stub_is_ee(nil) - allow(described_class).to receive(:`).with("git describe --exact-match 2>/dev/null").and_return('12.121.12+ce.0') - allow(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '*[+.]ce.*' --sort=-v:refname | awk '!/rc/' | head -1").and_return('12.121.12+ce.0') + stub_is_ee(false) end @@ -147,7 +196,13 @@ end - it 'returns the version of correct edition' do - expect(described_class.latest_stable_tag).to eq('12.121.12+ce.0') - end - end + context 'on stable branch' do + context 'when tags already exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '15-10-stable') + end + + it 'returns the latest tag in the stable version series' do + expect(described_class.latest_stable_tag).to eq('15.10.0+ce.0') + end + end @@ -153,8 +208,22 @@ - describe 'for EE' do - before do - stub_env_var('CI_COMMIT_BRANCH', 'foo-feature-branch') - stub_is_ee(true) - allow(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '*[+.]ee.*' --sort=-v:refname | awk '!/rc/' | head -1").and_return('12.121.12+ee.0') + context 'when tags does not exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-5-stable') + end + + it 'returns the latest available tag' do + expect(described_class.latest_stable_tag).to eq('16.1.1+ce.0') + end + end + + context 'when latest tag in the series is an RC tag' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-0-stable') + end + + it 'skips the RC tag and returns the latest available tag' do + expect(described_class.latest_stable_tag).to eq('16.1.1+ce.0') + end + end end @@ -159,7 +228,13 @@ end - it 'returns the version of correct edition' do - expect(described_class.latest_stable_tag).to eq('12.121.12+ee.0') + context 'on feature branch' do + before do + stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + end + + it 'returns the latest available tag' do + expect(described_class.latest_stable_tag).to eq('16.1.1+ce.0') + end end end @@ -163,5 +238,5 @@ end end - describe 'on stable branches' do + context 'on EE edition' do before do @@ -167,5 +242,4 @@ before do - stub_env_var('CI_COMMIT_BRANCH', '15-11-stable') - stub_is_ee(false) + stub_is_ee(true) end @@ -170,7 +244,13 @@ end - context 'when no tags exist in the stable branch' do - before do - allow(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '15.11*[+.]ce.*' --sort=-v:refname | awk '!/rc/' | head -1").and_return(nil) + context 'on stable branch' do + context 'when tags already exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '15-10-stable') + end + + it 'returns the latest tag in the stable version series' do + expect(described_class.latest_stable_tag).to eq('15.10.0+ee.0') + end end @@ -175,9 +255,7 @@ end - it 'returns the latest available stable tag' do - # Twice because we are calling the method two times - once to check - # the return value and another time to check if the message is - # printed - expect(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '15.11*[+.]ce.*' --sort=-v:refname | awk '!/rc/' | head -1").twice - expect(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '*[+.]ce.*' --sort=-v:refname | awk '!/rc/' | head -1").twice.and_return('15.10.3+ce.0') + context 'when tags does not exist in the stable version series' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-5-stable') + end @@ -183,6 +261,17 @@ - expect(described_class.latest_stable_tag).to eq('15.10.3+ce.0') - expect { described_class.latest_stable_tag }.to output(/No tags found in 15.11.x series/).to_stdout + it 'returns the latest available tag' do + expect(described_class.latest_stable_tag).to eq('16.1.1+ee.0') + end + end + + context 'when latest tag in the series is an RC tag' do + before do + stub_env_var('CI_COMMIT_BRANCH', '16-0-stable') + end + + it 'skips the RC tag and returns the latest available tag' do + expect(described_class.latest_stable_tag).to eq('16.1.1+ee.0') + end end end @@ -186,5 +275,5 @@ end end - context 'when tags exist in the stable branch' do + context 'on feature branch' do before do @@ -190,4 +279,4 @@ before do - allow(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '15.11*[+.]ce.*' --sort=-v:refname | awk '!/rc/' | head -1").and_return('15.11.0+ce.0') + stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') end @@ -192,9 +281,31 @@ end - it 'returns the latest available stable tag' do - expect(described_class).to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '15.11*[+.]ce.*' --sort=-v:refname | awk '!/rc/' | head -1") - expect(described_class).not_to receive(:`).with("git -c versionsort.prereleaseSuffix=rc tag -l '*[+.]ce.*' --sort=-v:refname | awk '!/rc/' | head -1") - expect(described_class.latest_stable_tag).to eq('15.11.0+ce.0') + it 'returns the latest available tag' do + expect(described_class.latest_stable_tag).to eq('16.1.1+ee.0') + end + end + end + + context 'when a level is specified' do + context 'when level is less than total number of tags' do + before do + stub_is_ee(true) + stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + end + + it 'returns recent tag at specified position' do + expect(described_class.latest_stable_tag(level: 2)).to eq('15.11.1+ee.0') + end + end + + context 'when level is more than total number of tags' do + before do + stub_is_ee(true) + stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + end + + it 'returns last tag' do + expect(described_class.latest_stable_tag(level: 6)).to eq('15.10.0+ee.0') end end end