lib/release_tools/public_release/gitlab_operator_release.rb (141 lines of code) (raw):
# frozen_string_literal: true
module ReleaseTools
module PublicRelease
# A release of GitLab Operator using the API
class GitlabOperatorRelease
include Release
include Services::SyncRefsHelper
attr_reader :version, :client, :chart_version, :gitlab_version, :helm_finder
# File containing versions of GitLab Helm chart supported by GitLab
# Operator
CHART_VERSIONS_FILE = 'CHART_VERSIONS'
DEFAULT_BRANCH = Project::GitlabOperator.default_branch
CHART_YML_FILE = 'deploy/chart/Chart.yaml'
WAIT_SYNC_INTERVALS = Array.new(10, 60)
TagNotFoundInBuildMirror = Class.new(StandardError) do
def message
'The tag was not found in Build mirror'
end
end
def initialize(
version,
chart_version,
gitlab_version,
client: GitlabClient,
commit: nil
)
@version = version
@chart_version = chart_version
@gitlab_version = gitlab_version.to_ee
@client = client
@commit = commit
@helm_finder = ::ReleaseTools::Helm::HelmVersionFinder.new
end
def execute
if gitlab_version.rc?
logger.info(
'Not releasing GitLab Operator for an RC',
version: version,
chart_version: chart_version,
gitlab_version: gitlab_version
)
return
end
if backport_chart_release?
logger.info(
'Not releasing GitLab Operator for backport Chart release',
version: version,
chart_version: chart_version,
gitlab_version: gitlab_version
)
return
end
logger.info(
'Starting release of GitLab Operator',
version: version,
chart_version: chart_version,
gitlab_version: gitlab_version
)
return if SharedStatus.dry_run?
create_target_branch
compile_changelog
supported_versions = helm_finder.latest_minor_versions
update_chart_yml_file
update_chart_files(supported_versions)
create_tag(supported_versions)
# We're syncing Operator refs as part of release because Operator is
# tagged while other components are being published, and the general
# sync has already happened. Because the sync involves fetching refs
# from dev and pushing them to other mirrors, we first wait for the
# tag to reach dev.
wait_for_tag_in_dev
sync_branch_and_tag
notify_slack(project, version)
end
def wait_for_tag_in_dev
return if Feature.enabled?(:skip_operator_wait_for_tag_in_dev)
logger.info('Waiting for Operator tag to be present in Build mirror')
remotes = project::REMOTES
repository = RemoteRepository.get(remotes, global_depth: 50, branch: target_branch)
Retriable.retriable(intervals: WAIT_SYNC_INTERVALS, on: TagNotFoundInBuildMirror) do
status = repository.fetch("refs/tags/#{version}", remote: :dev)
raise TagNotFoundInBuildMirror unless status
logger.info('Operator tag found in Build mirror')
end
end
def sync_branch_and_tag
sync_branches(Project::GitlabOperator, target_branch)
sync_tags(Project::GitlabOperator, version.to_s)
end
def update_chart_files(supported_versions)
# Commit to target branch
commit_version_files(
target_branch,
{ CHART_VERSIONS_FILE => supported_versions.join("\n") },
message: "Update CHART_VERSIONS for GitLab Chart release #{chart_version}"
)
# Commit to default branch (master/main)
commit_version_files(
DEFAULT_BRANCH,
{ CHART_VERSIONS_FILE => supported_versions.join("\n") },
message: "Update CHART_VERSIONS for GitLab Chart release #{chart_version}"
)
end
def update_chart_yml_file
content = read_file(CHART_YML_FILE)
chart_details = YAML.safe_load(content)
chart_details['version'] = version.to_s
chart_details['appVersion'] = version.to_s
commit_version_files(
target_branch,
{ CHART_YML_FILE => YAML.dump(chart_details) },
message: "Update Chart version to #{version}\n\n [ci skip]"
)
# Commit to default branch (master/main)
commit_version_files(
DEFAULT_BRANCH,
{ CHART_YML_FILE => YAML.dump(chart_details) },
message: "Update Chart version to #{version}\n\n [ci skip]"
)
end
def compile_changelog
logger.info('Compiling changelog', project: project_path)
ChangelogCompiler
.new(project_path, client: client)
.compile(version, branch: target_branch)
end
def create_tag(supported_versions)
logger.info('Creating tag', tag: tag_name, project: project_path)
client.find_or_create_tag(
project_path,
version.to_s,
target_branch,
message: "Version #{version} - supports GitLab Charts #{supported_versions.join(', ')}"
)
end
def read_file(file, project: project_path, branch: target_branch)
Retriable.with_context(:api) do
client.file_contents(project, file, branch).strip
end
end
def backport_chart_release?
latest_chart_version = helm_finder.latest_version
chart_version != latest_chart_version && helm_finder.sorted_versions([chart_version, latest_chart_version]).last == latest_chart_version
end
def project
Project::GitlabOperator
end
def source_for_target_branch
@commit || DEFAULT_BRANCH
end
end
end
end