lib/release_tools/services/auto_deploy_branch_service.rb (66 lines of code) (raw):
# frozen_string_literal: true
module ReleaseTools
module Services
class AutoDeployBranchService
include ::SemanticLogger::Loggable
include BranchCreation
CI_VAR_AUTO_DEPLOY = 'AUTO_DEPLOY_BRANCH'
COMMIT_AGE_THRESHOLD = 5.days
PROJECTS = [Project::GitlabEe, Project::OmnibusGitlab, Project::CNGImage].freeze
Result = Struct.new(:project, :branch, :response, :notify_branch_too_far_behind)
attr_reader :branch_name
def initialize(branch_name)
@branch_name = branch_name
end
def create_branches!
if all_refs_equal_to_limit_shas?
logger.warn('Not creating auto deploy branches because there are no new commits with passing builds')
return []
end
results = PROJECTS.map do |project|
# Find passing commits before creating branch
ref = latest_successful_ref(project)
branch = create_branch_from_ref(project.auto_deploy_path, branch_name, ref)
Result.new(project.auto_deploy_path, branch_name, branch, branch_too_far_behind?(project))
end
update_auto_deploy_ci
results
end
private
def latest_successful_ref(project)
passing_build(project).for_auto_deploy_branch.id
end
def previous_package_sha(project)
passing_build(project).previous_package_sha
end
def passing_build(project)
@passing_build ||= Hash.new do |hash, proj|
hash[proj] = PassingBuild.new(proj.default_branch, proj)
end
@passing_build[project]
end
def all_refs_equal_to_limit_shas?
refs = PROJECTS.map { |project| latest_successful_ref(project) }
limit_shas = PROJECTS.map { |project| previous_package_sha(project) }
PROJECTS.each_with_index.all? do |project, index|
equal = refs[index] == limit_shas[index]
logger.warn('New auto deploy branch will have same SHA as previous package', project: project, sha: refs[index]) if equal
equal
end
end
# Returns true if commits excluded from the auto deploy branch are 5 days old or more.
# We're checking the "age" of the excluded commit (with the committed_date as the birthday).
# If the age is 5 days or more, return true. Since we usually deploy multiple times a day,
# a commit should not reach the age of 5 days without being included in an auto deploy branch.
def branch_too_far_behind?(project)
excluded_commit = passing_build(project).next_commit
return false unless excluded_commit
commit_age = Time.current - Time.iso8601(excluded_commit.committed_date)
commit_age >= COMMIT_AGE_THRESHOLD
end
def update_auto_deploy_ci
return if SharedStatus.dry_run?
gitlab_ops_client = ReleaseTools::GitlabOpsClient
begin
gitlab_ops_client.update_variable('gitlab-org/release/tools', CI_VAR_AUTO_DEPLOY, branch_name)
rescue Gitlab::Error::NotFound
gitlab_ops_client.create_variable('gitlab-org/release/tools', CI_VAR_AUTO_DEPLOY, branch_name)
end
end
end
end
end