lib/release_tools/release_environment/environment.rb (100 lines of code) (raw):
# frozen_string_literal: true
require 'yaml'
module ReleaseTools
module ReleaseEnvironment
class Environment
include ::SemanticLogger::Loggable
def initialize(version, suffix = nil)
@version = ReleaseTools::Version.new(version)
@suffix = suffix
valid?
end
# Create a new release environment.
#
# A new environment directory is added to environments/ with the content
# of an existing enviornment. The logic to deploy the right version to
# the new environment is done by release-environment repo itself.
#
# @return [void]
def create
if exist?
logger.info("The environment #{name} already exists. Skipping.")
return
end
file_name = "environments/#{name}/environment.yaml"
new_config = build_config(last_commit_on_stable_branch)
logger.debug(new_config)
return if SharedStatus.dry_run?
Retriable.with_context(:api) do
GitlabClient.create_file(
project,
file_name,
project.default_branch,
new_config,
"[skip ci] Add new environment #{name}"
)
end
end
private
attr_reader :version, :suffix
def name
@name ||= suffix.present? ? "#{@version.stable_branch}-#{suffix}" : @version.stable_branch
end
def exist?
tree.any? { |hash| hash['name'] == name }
end
def tree
@tree ||=
Retriable.with_context(:api) do
GitlabClient
.tree(project, { path: 'environments' })
.lazy_paginate
end
end
def last_commit_on_stable_branch
branch(version.stable_branch(ee: true))
.last_commit['short_id']
end
# Package name is in the format <stable-branch>-<commit-id>
# Replace package name from "shell: 16-9-stable-abc456" to "shell: 16-10-stable-efg123"
def build_config(commit)
config = latest_config.gsub(
Regexp.new("#{latest_environment}-\\w+"),
image_tag(commit)
)
yaml_data = YAML.load(config)
if suffix == 'security'
yaml_data['versions']['registry'] = security_registry
end
yaml_data.to_yaml
end
# Image tag is in the format <stable-branch-without-ee>-<commit-id>
# E.g. 17-0-stable-8e06aedc
def image_tag(commit)
"#{version.stable_branch}-#{commit}"
end
def latest_config
Retriable.with_context(:api) do
GitlabClient.file_contents(
project,
"environments/#{latest_environment}/environment.yaml",
project.default_branch
)
end
end
def latest_environment
@latest_environment ||= begin
versions_hash = {}
tree.each do |hash|
branch_name = hash.to_h.fetch('name')
version = branch(branch_name).version
versions_hash[version] = branch_name
end
logger.info('Sorting versions', versions: versions_hash.keys, branches: versions_hash.values)
latest_version = ReleaseTools::Versions.sort(versions_hash.keys).last
versions_hash[latest_version]
end
end
def branch(name)
ReleaseTools::Branch.new(name: name, project: ReleaseTools::Project::GitlabEe)
end
def project
ReleaseTools::Project::Infrastructure::ReleaseEnvironment
end
def valid?
raise ArgumentError, "Invalid version: #{version}" unless ReleaseTools::Version.new(version).valid?
end
def security_registry
'registry.gitlab.com/gitlab-org/security/charts/components/images'
end
end
end
end