# frozen_string_literal: true require "active_support/core_ext/module/delegation" module Gitlab module QA class Release CANONICAL_REGEX = / \A (?ce|ee) (-qa)? (:(?.+))? \z /xi.freeze CUSTOM_GITLAB_IMAGE_REGEX = %r{ \A (? (?[^/:]+(:(?\d+))?) (?.+) gitlab- (?ce|ee) ) (-qa)? (:(?.+))? \z }xi.freeze delegate :ci_project_path, to: Gitlab::QA::Runtime::Env # Official dev tag example: # 12.5.4(-rc42)-ee # |-------------|--| # | | # | | # | | # | edition # version DEV_OFFICIAL_TAG_REGEX = / \A (?\d+\.\d+.\d+(?:-rc\d+)?)-(?ce|ee) \z /xi.freeze # Dev tag example: # 12.1.201906121026-325a6632895.b340d0bd35d # |----|------------|-----------|-----------| # | | | | # | | | omnibus-ref # | | gitlab-ee ref # | timestamp # version DEV_TAG_REGEX = / \A (?\d+\.\d+(.\d+)?)\.(?\d+)-(?[A-Za-z0-9]+)\.(?[A-Za-z0-9]+) \z /xi.freeze DEFAULT_TAG = 'latest' DEFAULT_CANONICAL_TAG = 'nightly' DEV_REGISTRY = 'dev.gitlab.org:5005' COM_REGISTRY = 'registry.gitlab.com' InvalidImageNameError = Class.new(RuntimeError) attr_reader :release attr_writer :tag def initialize(release) @release = release.to_s.downcase return if valid? raise InvalidImageNameError, "The release image name '#{@release}' does not have the expected format." end def to_s "#{image}:#{tag}" end def previous_stable # The previous stable is always gitlab/gitlab-ce:latest or # gitlab/gitlab-ee:latest self.class.new("#{canonical_image}:latest") end def edition @edition ||= if canonical? release.match(CANONICAL_REGEX)[:edition].to_sym else release.match(CUSTOM_GITLAB_IMAGE_REGEX)[:edition].to_sym end end def ee? edition == :ee end def to_ee return self if ee? self.class.new(to_s.sub('ce:', 'ee:')) end def image @image ||= if canonical? "gitlab/gitlab-#{edition}" else release.match(CUSTOM_GITLAB_IMAGE_REGEX)[:image_without_tag] end end def qa_image @qa_image ||= if omnibus_mirror? omnibus_project = image.match(CUSTOM_GITLAB_IMAGE_REGEX)[:project] gitlab_project = ci_project_path ? "/#{ci_project_path}/" : "/gitlab-org/gitlab/" "#{image.gsub(omnibus_project, gitlab_project)}-qa" else "#{image}-qa" end end def project_name @project_name ||= if canonical? "gitlab-#{edition}" else "gitlab-#{release.match(CUSTOM_GITLAB_IMAGE_REGEX)[:edition]}" end end # Tag scheme for gitlab-{ce,ee} images is like 11.1.0-rc12.ee.0 def tag @tag ||= if canonical? release.match(CANONICAL_REGEX)[:tag] || DEFAULT_CANONICAL_TAG else release.match(CUSTOM_GITLAB_IMAGE_REGEX)&.[](:tag) || DEFAULT_TAG end end # Tag scheme for gitlab-{ce,ee}-qa images is like 11.1.0-rc12-ee def qa_tag if dev_gitlab_org? && (match_data = tag.match(DEV_TAG_REGEX)) match_data[:gitlab_ref] else tag.sub(/[-.]([ce]e)(\.(\d+))?\z/, '-\1') end end def login_params return if Runtime::Env.skip_pull? if dev_gitlab_org? Runtime::Env.require_qa_dev_access_token! { username: Runtime::Env.gitlab_dev_username, password: Runtime::Env.dev_access_token_variable, registry: DEV_REGISTRY } elsif omnibus_mirror? username, password = if Runtime::Env.ci_job_token && Runtime::Env.ci_pipeline_source.include?('pipeline') ['gitlab-ci-token', Runtime::Env.ci_job_token] elsif Runtime::Env.qa_container_registry_access_token [Runtime::Env.gitlab_username, Runtime::Env.qa_container_registry_access_token] else Runtime::Env.require_qa_access_token! [Runtime::Env.gitlab_username, Runtime::Env.qa_access_token] end { username: username, password: password, registry: COM_REGISTRY } end end def dev_gitlab_org? image.start_with?(DEV_REGISTRY) end def omnibus_mirror? image.start_with?("#{COM_REGISTRY}/gitlab-org/build/omnibus-gitlab-mirror/") end def valid? canonical? || release.match?(CUSTOM_GITLAB_IMAGE_REGEX) end def api_project_name project_name.gsub('ce', 'foss').gsub('-ee', '') end private def canonical? release =~ CANONICAL_REGEX end def canonical_image @canonical_image ||= "gitlab/gitlab-#{edition}" end end end end