lib/gitlab/version.rb (129 lines of code) (raw):

require 'uri' require 'yaml' require_relative 'util' module Gitlab class Version DEFAULT_SOURCE = 'remote'.freeze ALTERNATIVE_SOURCE = 'alternative'.freeze SECURITY_SOURCE = 'security'.freeze CUSTOM_SOURCES_FILENAME = '.custom_sources.yml'.freeze COMPONENTS_ENV_VARS = { 'gitlab-rails' => 'GITLAB_VERSION', 'gitlab-rails-ee' => 'GITLAB_VERSION', 'gitlab-shell' => 'GITLAB_SHELL_VERSION', 'gitlab-pages' => 'GITLAB_PAGES_VERSION', 'gitaly' => 'GITALY_SERVER_VERSION', 'gitlab-elasticsearch-indexer' => 'GITLAB_ELASTICSEARCH_INDEXER_VERSION', 'gitlab-kas' => 'GITLAB_KAS_VERSION', }.freeze COMPONENTS_FILES = { "gitlab-rails" => "VERSION", "gitlab-rails-ee" => "VERSION", "gitlab-shell" => "GITLAB_SHELL_VERSION", "gitlab-pages" => "GITLAB_PAGES_VERSION", "gitaly" => "GITALY_SERVER_VERSION", "gitlab-elasticsearch-indexer" => "GITLAB_ELASTICSEARCH_INDEXER_VERSION", "gitlab-kas" => "GITLAB_KAS_VERSION", "omnibus" => "OMNIBUS_GEM_VERSION" }.freeze # Return which remote sources channel we are using # # Channels can be selected based on ENVIRONMENTAL variables # It defaults to "remote", which means internal "dev" instance. # # Security always takes precedence. # # @return [String] def self.sources_channel return SECURITY_SOURCE if Gitlab::Util.get_env("SECURITY_SOURCES").to_s == "true" fallback_sources_channel end # Return the fallback remote sources channel, which can be used when # no security remote alternative exists # # @return [String] def self.fallback_sources_channel Gitlab::Util.get_env("ALTERNATIVE_SOURCES").to_s == "false" ? DEFAULT_SOURCE : ALTERNATIVE_SOURCE end # Whether security sources channel is selected # # @return [Boolean] whether we are using security channel def self.security_channel? sources_channel == SECURITY_SOURCE end def self.alternative_channel? sources_channel == ALTERNATIVE_SOURCE end def initialize(software_name, version = nil) @software = software_name @read_version = version || get_software_version @project_root = File.join(File.dirname(__dir__), '../') end def get_software_version read_version_from_env || read_version_from_file end def read_version_from_env Gitlab::Util.get_env(COMPONENTS_ENV_VARS[@software]) if COMPONENTS_ENV_VARS.include?(@software) end def read_version_from_file path_to_build_facts_file = "build_facts/#{@software}_version" path_to_version_file = COMPONENTS_FILES[@software] if File.exist?(path_to_build_facts_file) File.read(path_to_build_facts_file).chomp elsif path_to_version_file filepath = File.expand_path(path_to_version_file, @project_root) File.read(filepath).chomp else "" end rescue Errno::ENOENT # Didn't find the file @read_version = "" end def print(prepend_version = true) if @read_version.include?('.pre') || @read_version == "master" "master" elsif @read_version.empty? nil else # Check if it satisfies the following criteria # 1. One of our own components - has a VERSION file # 2. Not a valid version string following SemVer # If it satisfy both, it is probably a branch name or a SHA # commit of one of our own component so it doesn't need `v` prepended if COMPONENTS_FILES.key?(@software) return @read_version unless /^\d+\.\d+\.\d+(-rc\d+)?(-ee)?$/.match?(@read_version) end v = "v" if prepend_version [ v, @read_version ].join end end def read_remote_from_env remote = case @software when "gitlab-rails", "gitlab-rails-ee" Gitlab::Util.get_env("GITLAB_ALTERNATIVE_REPO") when "gitlab-shell" Gitlab::Util.get_env("GITLAB_SHELL_ALTERNATIVE_REPO") when "gitlab-pages" Gitlab::Util.get_env("GITLAB_PAGES_ALTERNATIVE_REPO") when "gitaly" Gitlab::Util.get_env("GITALY_SERVER_ALTERNATIVE_REPO") when "gitlab-elasticsearch-indexer" Gitlab::Util.get_env("GITLAB_ELASTICSEARCH_INDEXER_ALTERNATIVE_REPO") when "gitlab-kas" Gitlab::Util.get_env("GITLAB_KAS_ALTERNATIVE_REPO") end if remote && Gitlab::Util.get_env("ALTERNATIVE_PRIVATE_TOKEN") attach_remote_credential(remote, Gitlab::Util.get_env("ALTERNATIVE_PRIVATE_TOKEN")) else remote end end def read_remote_from_file(channel = nil) filepath = File.expand_path(CUSTOM_SOURCES_FILENAME, @project_root) sources = YAML.load_file(filepath)[@software] channel ||= ::Gitlab::Version.sources_channel return "" unless sources if channel == SECURITY_SOURCE attach_remote_credential(sources[channel], Gitlab::Util.get_env("CI_JOB_TOKEN")) || sources[::Gitlab::Version.fallback_sources_channel] else sources[channel] end end def remote(channel = nil) read_remote_from_env || read_remote_from_file(channel) || "" end private def attach_remote_credential(url, token) return unless url uri = URI.parse(url) uri.user = "gitlab-ci-token" uri.password = token uri.to_s rescue URI::InvalidURIError # Git may use scp address which is not valid URI. Ignore it url end end end