diff --git a/lib/gitlab/build/check.rb b/lib/gitlab/build/check.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_bGliL2dpdGxhYi9idWlsZC9jaGVjay5yYg==..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_bGliL2dpdGxhYi9idWlsZC9jaGVjay5yYg== 100644 --- a/lib/gitlab/build/check.rb +++ b/lib/gitlab/build/check.rb @@ -1,4 +1,5 @@ require_relative "info.rb" +require_relative "info/git" require_relative "../util.rb" module Build @@ -46,7 +47,7 @@ end def is_auto_deploy_tag? - AUTO_DEPLOY_TAG_REGEX.match?(Build::Info.current_git_tag) + AUTO_DEPLOY_TAG_REGEX.match?(Build::Info::Git.tag_name) end def is_auto_deploy_branch? @@ -59,7 +60,7 @@ end def is_rc_tag? - Build::Info.current_git_tag.include?("+rc") + Build::Info::Git.tag_name&.include?("+rc") end def ci_commit_tag? @@ -67,7 +68,7 @@ end def is_latest_stable_tag? - match_tag?(Info.latest_stable_tag) + match_tag?(Info::Git.latest_stable_tag) end def is_latest_tag? @@ -71,7 +72,7 @@ end def is_latest_tag? - match_tag?(Info.latest_tag) + match_tag?(Info::Git.latest_tag) end def is_nightly? @@ -91,7 +92,7 @@ end def on_stable_branch? - Build::Info.branch_name&.match?(/^\d+-\d+-stable$/) + Build::Info::Git.branch_name&.match?(/^\d+-\d+-stable$/) end def on_regular_branch? @@ -95,7 +96,7 @@ end def on_regular_branch? - Build::Info.branch_name && !on_stable_branch? + Build::Info::Git.branch_name && !on_stable_branch? end end end diff --git a/lib/gitlab/build/facts.rb b/lib/gitlab/build/facts.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_bGliL2dpdGxhYi9idWlsZC9mYWN0cy5yYg==..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_bGliL2dpdGxhYi9idWlsZC9mYWN0cy5yYg== 100644 --- a/lib/gitlab/build/facts.rb +++ b/lib/gitlab/build/facts.rb @@ -1,3 +1,5 @@ +require_relative 'info/git' + module Build class Facts class << self @@ -12,7 +14,7 @@ :latest_stable_tag, :latest_tag ].each do |fact| - content = Build::Info.send(fact) # rubocop:disable GitlabSecurity/PublicSend + content = Build::Info::Git.send(fact) # rubocop:disable GitlabSecurity/PublicSend File.write("build_facts/#{fact}", content) unless content.nil? end end @@ -74,7 +76,7 @@ QA_IMAGE=#{Build::Info.qa_image} QA_TESTS=#{Gitlab::Util.get_env('QA_TESTS')} ALLURE_JOB_NAME=#{allure_job_name}-#{Build::Info.edition} - GITLAB_SEMVER_VERSION=#{Build::Info.latest_stable_tag.tr('+', '-')} + GITLAB_SEMVER_VERSION=#{Build::Info::Git.latest_stable_tag.tr('+', '-')} RAT_REFERENCE_ARCHITECTURE=#{Gitlab::Util.get_env('RAT_REFERENCE_ARCHITECTURE') || 'omnibus-gitlab-mrs'} RAT_FIPS_REFERENCE_ARCHITECTURE=#{Gitlab::Util.get_env('RAT_FIPS_REFERENCE_ARCHITECTURE') || 'omnibus-gitlab-mrs-fips-ubuntu'} RAT_PACKAGE_URL=#{Gitlab::Util.get_env('PACKAGE_URL') || Build::Info::CI.triggered_package_download_url(fips: false)} diff --git a/lib/gitlab/build/info.rb b/lib/gitlab/build/info.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_bGliL2dpdGxhYi9idWlsZC9pbmZvLnJi..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_bGliL2dpdGxhYi9idWlsZC9pbmZvLnJi 100644 --- a/lib/gitlab/build/info.rb +++ b/lib/gitlab/build/info.rb @@ -1,5 +1,6 @@ require 'omnibus' +require_relative 'info/git' require_relative '../build_iteration' require_relative "../util.rb" require_relative './info/ci' @@ -16,13 +17,6 @@ PACKAGE_GLOB = "pkg/**/*.{deb,rpm}".freeze class << self - def fetch_fact_from_file(fact) - return unless File.exist?("build_facts/#{fact}") - - content = File.read("build_facts/#{fact}").strip - return content unless content.empty? - end - def package return "gitlab-fips" if Check.use_system_ssl? return "gitlab-ee" if Check.is_ee? @@ -46,5 +40,5 @@ Omnibus.load_configuration('omnibus.rb') Omnibus::BuildVersion.semver else - latest_git_tag = Info.latest_tag.strip + latest_git_tag = Info::Git.latest_tag.strip latest_version = latest_git_tag && !latest_git_tag.empty? ? latest_git_tag[0, latest_git_tag.match("[+]").begin(0)] : '0.0.1' @@ -50,8 +44,8 @@ latest_version = latest_git_tag && !latest_git_tag.empty? ? latest_git_tag[0, latest_git_tag.match("[+]").begin(0)] : '0.0.1' - commit_sha = Build::Info.commit_sha + commit_sha = Build::Info::Git.commit_sha ver_tag = "#{latest_version}+" + (Build::Check.is_nightly? ? "rnightly" : "rfbranch") ver_tag += ".fips" if Build::Check.use_system_ssl? [ver_tag, Gitlab::Util.get_env('CI_PIPELINE_ID'), commit_sha].compact.join('.') end end @@ -52,20 +46,11 @@ ver_tag = "#{latest_version}+" + (Build::Check.is_nightly? ? "rnightly" : "rfbranch") ver_tag += ".fips" if Build::Check.use_system_ssl? [ver_tag, Gitlab::Util.get_env('CI_PIPELINE_ID'), commit_sha].compact.join('.') end end - def branch_name - Gitlab::Util.get_env('CI_COMMIT_BRANCH') - end - - def commit_sha - commit_sha_raw = Gitlab::Util.get_env('CI_COMMIT_SHA') || `git rev-parse HEAD`.strip - commit_sha_raw[0, 8] - end - def release_version semver = Info.semver_version "#{semver}-#{Gitlab::BuildIteration.new.build_iteration}" end @@ -67,65 +52,8 @@ def release_version semver = Info.semver_version "#{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 - unless (fact_from_file = fetch_fact_from_file(__method__)).nil? - return fact_from_file - end - - tags = sorted_tags_for_edition - - return if tags.empty? - - 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) - unless (fact_from_file = fetch_fact_from_file(__method__)).nil? - 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? - - 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. - # 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 Gitlab::Util.get_env('IMAGE_TAG') || Info.release_version.tr('+', '-') end @@ -162,12 +90,6 @@ Gitlab::Version.new('gitlab-rails').print(prepend_version) end - def previous_version - # Get the second latest git tag - previous_tag = Info.latest_stable_tag(level: 2) - previous_tag.tr("+", "-") - end - def gitlab_rails_project_path if Gitlab::Util.get_env('CI_SERVER_HOST') == 'dev.gitlab.org' package == "gitlab-ee" ? 'gitlab/gitlab-ee' : 'gitlab/gitlabhq' @@ -243,12 +165,6 @@ "https://#{Info.release_bucket}.#{Info.release_bucket_s3_endpoint}/#{folder}/#{Info.package}_#{package_filename_url_safe}_#{arch}.deb" end - def tag_match_pattern - return '*[+.]ee.*' if Check.is_ee? - - '*[+.]ce.*' - end - def release_file_contents repo = Gitlab::Util.get_env('PACKAGECLOUD_REPO') # Target repository @@ -269,10 +185,6 @@ contents.join end - def current_git_tag - `git describe --exact-match 2>/dev/null`.chomp - end - def image_reference "#{Build::GitlabImage.gitlab_registry_image_address}:#{Info.docker_tag}" end diff --git a/lib/gitlab/build/info/git.rb b/lib/gitlab/build/info/git.rb new file mode 100644 index 0000000000000000000000000000000000000000..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_bGliL2dpdGxhYi9idWlsZC9pbmZvL2dpdC5yYg== --- /dev/null +++ b/lib/gitlab/build/info/git.rb @@ -0,0 +1,104 @@ +require_relative '../../util' +require_relative '../check' +require_relative 'ci' + +module Build + class Info + class Git + class << self + def branch_name + # If on CI, branch name from `CI_COMMIT_BRANCH` wins + result = Build::Info::CI.branch_name + + return result if result + + # If not on CI, attempt to detect branch name + head_reference = Gitlab::Util.shellout_stdout('git rev-parse --abbrev-ref HEAD') + + # On tags, the shell command will return `HEAD`. If that is not the + # case, we are on a branch and can return the output we received. + return head_reference unless head_reference == "HEAD" + end + + def tag_name + Build::Info::CI.tag_name || Gitlab::Util.shellout_stdout('git describe --tags --exact-match') + rescue Gitlab::Util::ShellOutExecutionError => e + return nil if /fatal: no tag exactly matches/.match?(e.stderr) + + raise "#{e.message}\nSTDOUT: #{e.stdout}\nSTDERR: #{e.stderr}" + end + + def commit_sha + commit_sha_raw = Gitlab::Util.get_env('CI_COMMIT_SHA') || Gitlab::Util.shellout_stdout('git rev-parse HEAD') + + commit_sha_raw[0, 8] + end + + # TODO, merge latest_tag with latest_stable_tag + # TODO, add tests, needs a repo clone + def latest_tag + unless (fact_from_file = Gitlab::Util.fetch_fact_from_file(__method__)).nil? + return fact_from_file + end + + tags = sorted_tags_for_edition + + return if tags.empty? + + 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) + unless (fact_from_file = Gitlab::Util.fetch_fact_from_file(__method__)).nil? + 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? + + 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. + # 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 + + private + + def sorted_tags_for_edition + Gitlab::Util.shellout_stdout("git -c versionsort.prereleaseSuffix=rc tag -l '#{tag_match_pattern}' --sort=-v:refname")&.split("\n") + end + + def tag_match_pattern + return '*[+.]ee.*' if Build::Check.is_ee? + + '*[+.]ce.*' + end + end + end + end +end diff --git a/lib/gitlab/tasks/build.rake b/lib/gitlab/tasks/build.rake index f26af321538def1d4a72605a5b54310aeac8f5ff_bGliL2dpdGxhYi90YXNrcy9idWlsZC5yYWtl..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_bGliL2dpdGxhYi90YXNrcy9idWlsZC5yYWtl 100644 --- a/lib/gitlab/tasks/build.rake +++ b/lib/gitlab/tasks/build.rake @@ -2,6 +2,7 @@ require_relative "../build.rb" require_relative "../build/check.rb" require_relative "../build/info.rb" +require_relative "../build/info/git" require_relative '../build/facts' require_relative "../gcloud_helper.rb" require_relative "../ohai_helper.rb" @@ -27,8 +28,8 @@ namespace :docker do desc 'Show latest available tag. Includes unstable releases.' task :latest_tag do - puts Build::Info.latest_tag + puts Build::Info::Git.latest_tag end desc 'Show latest stable tag.' task :latest_stable_tag do @@ -31,8 +32,8 @@ end desc 'Show latest stable tag.' task :latest_stable_tag do - puts Build::Info.latest_stable_tag + puts Build::Info::Git.latest_stable_tag end end diff --git a/lib/gitlab/tasks/qa.rake b/lib/gitlab/tasks/qa.rake index f26af321538def1d4a72605a5b54310aeac8f5ff_bGliL2dpdGxhYi90YXNrcy9xYS5yYWtl..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_bGliL2dpdGxhYi90YXNrcy9xYS5yYWtl 100644 --- a/lib/gitlab/tasks/qa.rake +++ b/lib/gitlab/tasks/qa.rake @@ -3,6 +3,7 @@ require_relative '../build/qa' require_relative '../build/check' require_relative '../build/info' +require_relative "../build/info/git" require_relative '../build/gitlab_image' require_relative '../build/qa_image' require_relative '../build/rat' @@ -64,7 +65,7 @@ task :staging do Gitlab::Util.section('qa:push:staging') do Build::QAImage.tag_and_push_to_gitlab_registry(Build::Info.gitlab_version) - Build::QAImage.tag_and_push_to_gitlab_registry(Build::Info.commit_sha) + Build::QAImage.tag_and_push_to_gitlab_registry(Build::Info::Git.commit_sha) end end diff --git a/lib/gitlab/util.rb b/lib/gitlab/util.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_bGliL2dpdGxhYi91dGlsLnJi..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_bGliL2dpdGxhYi91dGlsLnJi 100644 --- a/lib/gitlab/util.rb +++ b/lib/gitlab/util.rb @@ -1,5 +1,17 @@ module Gitlab class Util + class ShellOutExecutionError < StandardError + attr_accessor :stdout, :stderr + + def initialize(command, exitcode, stdout, stderr) + @stdout = stdout + @stderr = stderr + msg = "Execution of command `#{command}` failed with exit code #{exitcode}." + + super(msg) + end + end + class << self def get_env(key) value = ENV[key]&.strip @@ -27,6 +39,24 @@ $stdout.puts "section_end:#{Time.now.to_i}:#{name}\r\e[0K" end + + def shellout_stdout(cmd) + output = Mixlib::ShellOut.new(cmd) + output.run_command + + raise ShellOutExecutionError.new(cmd, output.status.exitstatus, output.stdout, output.stderr) unless output.status.exitstatus.zero? + + stdout = output.stdout&.chomp&.strip + + stdout unless stdout&.empty? + end + + def fetch_fact_from_file(fact) + return unless File.exist?("build_facts/#{fact}") + + content = File.read("build_facts/#{fact}").strip + return content unless content.empty? + end end end end diff --git a/spec/lib/gitlab/build/check_spec.rb b/spec/lib/gitlab/build/check_spec.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2NoZWNrX3NwZWMucmI=..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2NoZWNrX3NwZWMucmI= 100644 --- a/spec/lib/gitlab/build/check_spec.rb +++ b/spec/lib/gitlab/build/check_spec.rb @@ -92,9 +92,9 @@ it 'returns true if it is an rc release' do # This will be the case if latest_tag is eg. 9.3.0+rc6.ce.0 # or 9.3.0+ce.0 - allow(Build::Info).to receive(:latest_tag).and_return('9.3.0+rc6.ce.0') # This line only is only an example, stubbing is not needed. + allow(Build::Info::Git).to receive(:latest_tag).and_return('9.3.0+rc6.ce.0') # This line only is only an example, stubbing is not needed. allow(described_class).to receive(:match_tag?).and_return(true) expect(described_class.is_latest_tag?).to be_truthy end it 'returns true if it is not an rc release' do @@ -96,9 +96,9 @@ allow(described_class).to receive(:match_tag?).and_return(true) expect(described_class.is_latest_tag?).to be_truthy end it 'returns true if it is not an rc release' do - allow(Build::Info).to receive(:latest_tag).and_return('9.3.0+ce.0') # This line only is only an example, stubbing is not needed. + allow(Build::Info::Git).to receive(:latest_tag).and_return('9.3.0+ce.0') # This line only is only an example, stubbing is not needed. allow(described_class).to receive(:match_tag?).and_return(false) expect(described_class.is_latest_tag?).to be_falsey end @@ -108,9 +108,9 @@ it 'returns true if it is a stable release' do # This will be the case if latest_tag is eg. 9.3.0+ce.0 # It will not be the case if the tag is 9.3.0+rc6.ce.0 - allow(Build::Info).to receive(:latest_stable_tag).and_return('9.3.0+ce.0') # This line only is only an example, stubbing is not needed. + allow(Build::Info::Git).to receive(:latest_stable_tag).and_return('9.3.0+ce.0') # This line only is only an example, stubbing is not needed. allow(described_class).to receive(:match_tag?).and_return(true) expect(described_class.is_latest_stable_tag?).to be_truthy end it 'returns true if it is not a stable release' do @@ -112,9 +112,9 @@ allow(described_class).to receive(:match_tag?).and_return(true) expect(described_class.is_latest_stable_tag?).to be_truthy end it 'returns true if it is not a stable release' do - allow(Build::Info).to receive(:latest_stable_tag).and_return('9.3.0+rc6.ce.0') # This line only is only an example, stubbing is not needed. + allow(Build::Info::Git).to receive(:latest_stable_tag).and_return('9.3.0+rc6.ce.0') # This line only is only an example, stubbing is not needed. allow(described_class).to receive(:match_tag?).and_return(false) expect(described_class.is_latest_stable_tag?).to be_falsey end @@ -136,8 +136,8 @@ describe 'is_rc_tag?' do it 'returns true if it looks like an rc tag' do # It will be the case if the tag is 9.3.0+rc6.ce.0 - allow(Build::Info).to receive(:current_git_tag).and_return('9.3.0+rc6.ce.0') + allow(Build::Info::Git).to receive(:tag_name).and_return('9.3.0+rc6.ce.0') expect(described_class.is_rc_tag?).to be_truthy end it 'returns false if it does not look like an rc tag' do # This not be the case if tag is eg. 9.3.0+ce.0 @@ -140,8 +140,8 @@ expect(described_class.is_rc_tag?).to be_truthy end it 'returns false if it does not look like an rc tag' do # This not be the case if tag is eg. 9.3.0+ce.0 - allow(Build::Info).to receive(:current_git_tag).and_return('9.3.0+ce.0') + allow(Build::Info::Git).to receive(:tag_name).and_return('9.3.0+ce.0') expect(described_class.is_rc_tag?).to be_falsey end end @@ -149,7 +149,7 @@ describe 'is_auto_deploy?' do it 'returns true if it looks like an auto-deploy tag' do # This is the case if the tag is 11.10.12345+5159f2949cb.59c9fa631 - allow(Build::Info).to receive(:current_git_tag).and_return('11.10.12345+5159f2949cb.59c9fa631') + allow(Build::Info::Git).to receive(:tag_name).and_return('11.10.12345+5159f2949cb.59c9fa631') expect(described_class.is_auto_deploy?).to be_truthy end @@ -157,7 +157,7 @@ # This not be the case if ag is eg. 9.3.0+ce.0 allow(Gitlab::Util).to receive(:get_env).with('CI_COMMIT_REF_NAME').and_return('a-random-branch') - allow(Build::Info).to receive(:current_git_tag).and_return('9.3.0+ce.0') + allow(Build::Info::Git).to receive(:tag_name).and_return('9.3.0+ce.0') expect(described_class.is_auto_deploy?).to be_falsey end end @@ -172,7 +172,7 @@ describe 'on_stable_branch?' do context 'when on a stable branch' do before do - stub_env_var('CI_COMMIT_BRANCH', '14-10-stable') + stub_branch('14-10-stable') end it 'returns true' do @@ -182,7 +182,7 @@ context 'when on a regular branch' do before do - stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + stub_branch('my-feature-branch') end it 'returns false' do @@ -192,7 +192,7 @@ context 'when using a a tag' do before do - stub_env_var('CI_COMMIT_BRANCH', '') + stub_tag('1.2.3') end it 'returns false' do @@ -204,7 +204,7 @@ describe 'on_regular_tag?' do context 'when on a regular branch' do before do - stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + stub_branch('my-feature-branch') allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(false) end @@ -215,7 +215,7 @@ context 'when on a stable branch' do before do - stub_env_var('CI_COMMIT_BRANCH', '15-6-stable') + stub_branch('15-6-stable') allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(false) end @@ -226,8 +226,7 @@ context 'when on RC tag' do before do - stub_env_var('CI_COMMIT_BRANCH', '') - stub_env_var('CI_COMMIT_TAG', '15.8.0+rc42.ce.0') + stub_tag('15.8.0+rc42.ce.0') allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(true) end @@ -238,8 +237,7 @@ context 'when on stable tag' do before do - stub_env_var('CI_COMMIT_BRANCH', '') - stub_env_var('CI_COMMIT_TAG', '15.8.0+ce.0') + stub_tag('15.8.0+ce.0') allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(true) end @@ -250,9 +248,7 @@ context 'when on auto-deploy tag' do before do - stub_env_var('CI_COMMIT_BRANCH', '') - stub_env_var('CI_COMMIT_TAG', '15.8.202301050320+b251a9da107.0e5d6807f3a') - allow(Build::Info).to receive(:current_git_tag).and_return('15.8.202301050320+b251a9da107.0e5d6807f3a') + stub_tag('15.8.202301050320+b251a9da107.0e5d6807f3a') allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(true) end @@ -265,7 +261,6 @@ describe 'on_regular_branch?' do context 'when on a regular branch' do before do - stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') - allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(false) + stub_branch('my-feature-branch') end @@ -270,9 +265,9 @@ end - it 'returns false' do + it 'returns true' do expect(described_class.on_regular_branch?).to be_truthy end end context 'when on a stable branch' do before do @@ -273,11 +268,10 @@ expect(described_class.on_regular_branch?).to be_truthy end end context 'when on a stable branch' do before do - stub_env_var('CI_COMMIT_BRANCH', '15-6-stable') - allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(false) + stub_branch('15-6-stable') end it 'returns false' do @@ -287,9 +281,7 @@ context 'when on RC tag' do before do - stub_env_var('CI_COMMIT_BRANCH', '') - stub_env_var('CI_COMMIT_TAG', '15.8.0+rc42.ce.0') - allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(true) + stub_tag('15.8.0+rc42.ce.0') end it 'returns true' do @@ -299,9 +291,7 @@ context 'when on stable tag' do before do - stub_env_var('CI_COMMIT_BRANCH', '') - stub_env_var('CI_COMMIT_TAG', '15.8.0+ce.0') - allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(true) + stub_tag('15.8.0+ce.0') end it 'returns true' do @@ -311,10 +301,7 @@ context 'when on auto-deploy tag' do before do - stub_env_var('CI_COMMIT_BRANCH', '') - stub_env_var('CI_COMMIT_TAG', '15.8.202301050320+b251a9da107.0e5d6807f3a') - allow(Build::Info).to receive(:current_git_tag).and_return('15.8.202301050320+b251a9da107.0e5d6807f3a') - allow(described_class).to receive(:system).with(/git describe --exact-match/).and_return(true) + stub_tag('15.8.202301050320+b251a9da107.0e5d6807f3a') end it 'returns false' do diff --git a/spec/lib/gitlab/build/facts_spec.rb b/spec/lib/gitlab/build/facts_spec.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2ZhY3RzX3NwZWMucmI=..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2ZhY3RzX3NwZWMucmI= 100644 --- a/spec/lib/gitlab/build/facts_spec.rb +++ b/spec/lib/gitlab/build/facts_spec.rb @@ -93,8 +93,8 @@ describe '.generate_tag_files' do before do - allow(Build::Info).to receive(:latest_stable_tag).and_return('14.6.2+ce.0') - allow(Build::Info).to receive(:latest_tag).and_return('14.7.0+rc42.ce.0') + allow(Build::Info::Git).to receive(:latest_stable_tag).and_return('14.6.2+ce.0') + allow(Build::Info::Git).to receive(:latest_tag).and_return('14.7.0+rc42.ce.0') end it 'writes tag details to file' do @@ -223,7 +223,7 @@ before do allow(described_class).to receive(:generate_knapsack_report?).and_return('true') allow(Build::GitlabImage).to receive(:gitlab_registry_image_address).and_return('registry.gitlab.com/gitlab-org/build/omnibus-gitlab-mirror/gitlab-ee:14.6.2-rfbranch.450066356.c97110ad-0') - allow(Build::Info).to receive(:latest_stable_tag).and_return("14.6.2+rfbranch.450066356") + allow(Build::Info::Git).to receive(:latest_stable_tag).and_return("14.6.2+rfbranch.450066356") stub_env_var('QA_IMAGE', 'gitlab/gitlab-ee-qa:nightly') stub_env_var('QA_TESTS', '') diff --git a/spec/lib/gitlab/build/info/git_spec.rb b/spec/lib/gitlab/build/info/git_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2luZm8vZ2l0X3NwZWMucmI= --- /dev/null +++ b/spec/lib/gitlab/build/info/git_spec.rb @@ -0,0 +1,342 @@ +require 'spec_helper' +require 'gitlab/build/info/git' + +RSpec.describe Build::Info::Git do + before do + stub_default_package_version + + 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(Gitlab::Util).to receive(:shellout_stdout).with(/git -c versionsort.*ce/).and_return(ce_tags) + allow(Gitlab::Util).to receive(:shellout_stdout).with(/git -c versionsort.*ee/).and_return(ee_tags) + end + + describe '.branch_name' do + context 'in tags' do + context 'in CI' do + before do + stub_tag('16.1.1+ee.0') + end + + it 'returns nil' do + expect(described_class.branch_name).to be_nil + end + end + + context 'not in CI' do + before do + stub_env_var('CI_COMMIT_BRANCH', '') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git rev-parse --abbrev-ref HEAD').and_return('HEAD') + end + + it 'returns nil' do + expect(described_class.branch_name).to be_nil + end + end + end + + context 'in branches' do + context 'in CI' do + before do + stub_env_var('CI_COMMIT_BRANCH', 'my-feature-branch') + end + + it 'returns branch name from CI variable' do + expect(described_class.branch_name).to eq('my-feature-branch') + end + end + + context 'not in CI' do + before do + stub_env_var('CI_COMMIT_BRANCH', '') + stub_env_var('CI_COMMIT_TAG', '') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git rev-parse --abbrev-ref HEAD').and_return('my-feature-branch') + end + + it 'computes branch name from git' do + expect(described_class.branch_name).to eq('my-feature-branch') + end + end + end + end + + describe '.tag_name' do + context 'in tags' do + context 'in CI' do + before do + stub_env_var('CI_COMMIT_BRANCH', '') + stub_env_var('CI_COMMIT_TAG', '16.1.1+ee.0') + end + + it 'returns tag name from CI variables' do + expect(described_class.tag_name).to eq('16.1.1+ee.0') + end + + context 'not in CI' do + before do + stub_env_var('CI_COMMIT_BRANCH', '') + stub_env_var('CI_COMMIT_TAG', '') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git describe --tags --exact-match').and_return('16.1.1+ee.0') + end + + it 'computes tag name from git' do + expect(described_class.tag_name).to eq('16.1.1+ee.0') + end + end + end + end + + context 'in branches' do + before do + stub_branch('my-feature-branch') + end + + it 'returns nil' do + expect(described_class.tag_name).to be_nil + end + end + + context 'if some other error is raised' do + before do + stub_env_var('CI_COMMIT_BRANCH', '') + stub_env_var('CI_COMMIT_TAG', '') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git describe --tags --exact-match').and_raise(Gitlab::Util::ShellOutExecutionError.new("", 100, "", "Some Other Error")) + end + + it 'raises the error' do + expect { described_class.tag_name }.to raise_error(/Some Other Error/) + end + end + end + + describe '.commit_sha' do + context 'from CI' do + before do + stub_env_var('CI_COMMIT_SHA', '3cd8e712ccd3c3f356108ec1a5cbeecbf3d3be88') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git rev-parse HEAD').and_return('some-other-sha') + end + + it 'returns truncated commit sha from CI variable' do + expect(described_class.commit_sha).to eq('3cd8e712') + end + end + + context 'not from CI' do + before do + stub_env_var('CI_COMMIT_SHA', '') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git rev-parse HEAD').and_return('3cd8e712ccd3c3f356108ec1a5cbeecbf3d3be88') + end + + it 'returns truncated commit sha from CI variable' do + expect(described_class.commit_sha).to eq('3cd8e712') + end + end + end + + describe '.latest_tag' do + context 'on CE edition' do + before do + stub_is_ee(false) + 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_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 + + 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 + + context 'on EE edition' do + before do + stub_is_ee(true) + 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_tag).to eq('15.10.0+ee.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 + + it 'returns the latest available tag' do + expect(described_class.latest_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 'returns the RC tag' do + expect(described_class.latest_tag).to eq('16.0.0+rc42.ee.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+ee.0') + end + end + end + end + + describe '.latest_stable_tag' do + context 'on CE edition' do + before do + stub_is_ee(false) + 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 + + 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 + + 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 + + context 'on EE edition' do + before do + stub_is_ee(true) + 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+ee.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 + + 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 + + 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+ee.0') + end + end + end + + context 'when a level is specified' 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 + end +end diff --git a/spec/lib/gitlab/build/info_spec.rb b/spec/lib/gitlab/build/info_spec.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2luZm9fc3BlYy5yYg==..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_c3BlYy9saWIvZ2l0bGFiL2J1aWxkL2luZm9fc3BlYy5yYg== 100644 --- a/spec/lib/gitlab/build/info_spec.rb +++ b/spec/lib/gitlab/build/info_spec.rb @@ -49,8 +49,8 @@ it 'defaults to an initial build version when there are no matching tags' do allow(Build::Check).to receive(:on_tag?).and_return(false) allow(Build::Check).to receive(:is_nightly?).and_return(false) - allow(Build::Info).to receive(:latest_tag).and_return('') - allow(Build::Info).to receive(:commit_sha).and_return('ffffffff') + allow(Build::Info::Git).to receive(:latest_tag).and_return('') + allow(Build::Info::Git).to receive(:commit_sha).and_return('ffffffff') stub_env_var('CI_PIPELINE_ID', '5555') expect(described_class.release_version).to eq('0.0.1+rfbranch.5555.ffffffff-ce.1') @@ -91,226 +91,6 @@ end end - describe '.latest_tag' do - context 'on CE edition' do - before do - stub_is_ee(false) - 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_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 - - 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 - - context 'on EE edition' do - before do - stub_is_ee(true) - 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_tag).to eq('15.10.0+ee.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 - - it 'returns the latest available tag' do - expect(described_class.latest_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 'returns the RC tag' do - expect(described_class.latest_tag).to eq('16.0.0+rc42.ee.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+ee.0') - end - end - end - end - - describe '.latest_stable_tag' do - context 'on CE edition' do - before do - stub_is_ee(false) - 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 - - 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 - - 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 - - context 'on EE edition' do - before do - stub_is_ee(true) - 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+ee.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 - - 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 - - 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+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 - end - describe '.gitlab_version' do describe 'GITLAB_VERSION variable specified' do it 'returns passed value' do @@ -327,15 +107,6 @@ end end - describe '.previous_version' do - it 'detects previous version correctly' do - allow(described_class).to receive(:`).with("git describe --exact-match 2>/dev/null").and_return('10.4.0+ee.0') - allow(Build::Info).to receive(:`).with(/git -c versionsort/).and_return("10.4.0+ee.0\n10.3.5+ee.0") - - expect(described_class.previous_version).to eq("10.3.5-ee.0") - end - end - describe '.gitlab_rails repo' do describe 'with alternative sources channel selected' do before do diff --git a/spec/lib/gitlab/tasks/qa_spec.rb b/spec/lib/gitlab/tasks/qa_spec.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_c3BlYy9saWIvZ2l0bGFiL3Rhc2tzL3FhX3NwZWMucmI=..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_c3BlYy9saWIvZ2l0bGFiL3Rhc2tzL3FhX3NwZWMucmI= 100644 --- a/spec/lib/gitlab/tasks/qa_spec.rb +++ b/spec/lib/gitlab/tasks/qa_spec.rb @@ -40,7 +40,7 @@ describe 'qa:copy' do before do allow(Build::Info).to receive(:gitlab_version).and_return(gitlab_version) - allow(Build::Info).to receive(:commit_sha).and_return(commit_sha) + allow(Build::Info::Git).to receive(:commit_sha).and_return(commit_sha) end describe ':nightly' do @@ -139,7 +139,7 @@ Rake::Task['qa:push:staging'].reenable allow(Build::Info).to receive(:gitlab_version).and_return(gitlab_version) - allow(Build::Info).to receive(:commit_sha).and_return(commit_sha) + allow(Build::Info::Git).to receive(:commit_sha).and_return(commit_sha) end it 'pushes staging images correctly' do diff --git a/spec/support/macros.rb b/spec/support/macros.rb index f26af321538def1d4a72605a5b54310aeac8f5ff_c3BlYy9zdXBwb3J0L21hY3Jvcy5yYg==..9ff1734b0815b09760e2d71b3cd6b71c7ee51e44_c3BlYy9zdXBwb3J0L21hY3Jvcy5yYg== 100644 --- a/spec/support/macros.rb +++ b/spec/support/macros.rb @@ -51,6 +51,22 @@ allow(ENV).to receive(:[]).with(var).and_return(value) end + def stub_branch(branch) + stub_env_var('CI_COMMIT_BRANCH', branch) + allow(Gitlab::Util).to receive(:shellout_stdout).with('git rev-parse --abbrev-ref HEAD').and_return(branch) + + stub_env_var('CI_COMMIT_TAG', '') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git describe --tags --exact-match').and_raise(Gitlab::Util::ShellOutExecutionError.new("git describe --tags --exact-match", 128, "", "fatal: no tag exactly matches 'foobar'")) + end + + def stub_tag(tag) + stub_env_var('CI_COMMIT_TAG', tag) + allow(Gitlab::Util).to receive(:shellout_stdout).with('git describe --tags --exact-match').and_return(tag) + + stub_env_var('CI_COMMIT_BRANCH', '') + allow(Gitlab::Util).to receive(:shellout_stdout).with('git rev-parse --abbrev-ref HEAD').and_return('HEAD') + end + def stub_is_package_version(package, value = nil) allow(File).to receive(:read).with('VERSION').and_return(value ? "1.2.3-#{package}" : '1.2.3') end