lib/tasks/task_helpers.rb (84 lines of code) (raw):
# frozen_string_literal: true
require 'yaml'
require 'json'
require 'date'
require 'nanoc'
require 'active_support'
require 'active_support/time'
require_relative '../helpers/generic'
class TaskHelpers
include Nanoc::Helpers::Generic
PRODUCTS = %w[ee omnibus runner charts operator].freeze
VERSION_FORMAT = %r{^(?<major>\d{1,2})\.(?<minor>\d{1,2})$}
COLOR_CODE_RESET = "\e[0m"
COLOR_CODE_RED = "\e[31m"
COLOR_CODE_GREEN = "\e[32m"
Time.zone = 'UTC'
def self.info(slug, message)
puts "#{TaskHelpers::COLOR_CODE_GREEN}INFO: (#{slug}): #{message} #{TaskHelpers::COLOR_CODE_RESET}"
end
def config
# Parse the config file and create a hash.
@config ||= YAML.load_file('./nanoc.yaml')
end
def project_root
@project_root ||= File.expand_path('../../', __dir__)
end
def products
# Pull products data from the config.
@products ||= PRODUCTS.each_with_object({}) do |key, result|
result[key] = config['products'][key]
end
end
def retrieve_branch(slug)
#
# If we're NOT on a gitlab-docs stable branch, fetch the BRANCH_* environment
# variable, and if not assigned, set to the default branch.
#
if stable_branch_name.nil?
merge_request_iid = ENV.fetch("MERGE_REQUEST_IID_#{slug.upcase}", nil)
branch_name = ENV.fetch("BRANCH_#{slug.upcase}", default_branch(products[slug].fetch('repo')))
return branch_name, "heads/#{branch_name}" if merge_request_iid.nil?
return branch_name, "merge-requests/#{merge_request_iid}/head"
end
#
# Check the project slug to determine the branch name
#
stable_branch = stable_branch_for(slug)
[stable_branch, "heads/#{stable_branch}"]
end
def stable_branch_for(slug)
case slug
when 'ee'
"#{stable_branch_name}-ee"
when 'omnibus', 'runner'
stable_branch_name
# Charts don't use the same version scheme as GitLab, we need to
# deduct their version from the GitLab equivalent one.
when 'charts'
charts_stable_branch
# If the upstream product doesn't follow a stable branch scheme, set the
# branch to the default
else
default_branch(products[slug].fetch('repo'))
end
end
def git_workdir_dirty?
!`git status --porcelain`.empty?
end
def local_branch_exist?(branch)
!`git branch --list #{branch}`.empty?
end
#
# If we're on a gitlab-docs stable branch (or targeting one) according to the
# regex, catch the version and return the branch name.
# For example, 15-8-stable.
#
# 1. Skip if CI_COMMIT_REF_NAME is not defined (run outside the CI environment).
# 2. If CI_COMMIT_REF_NAME matches the version format it means we're on a
# stable branch. Return the version format of that branch.
# 3. If CI_MERGE_REQUEST_TARGET_BRANCH_NAME is defined and its value matches
# the version format, return that value.
#
def stable_branch_name
@stable_branch_name ||= begin
ref_name = ENV["CI_COMMIT_REF_NAME"]&.match(VERSION_FORMAT)
if ref_name
"#{ref_name[:major]}-#{ref_name[:minor]}-stable"
else
mr_name = ENV["CI_MERGE_REQUEST_TARGET_BRANCH_NAME"]&.match(VERSION_FORMAT)
"#{mr_name[:major]}-#{mr_name[:minor]}-stable" if mr_name
end
end
end
#
# The charts versions do not follow the same GitLab major number, BUT
# they do follow a pattern https://docs.gitlab.com/charts/installation/version_mappings.html:
#
# 1. The minor version is the same for both
# 2. The major version augments for both at the same time
#
# This means we can deduct the charts version from the GitLab version, since
# the major charts version is always 9 versions behind its GitLab counterpart.
#
def charts_stable_branch
major, minor = stable_branch_name.split('-')
# Assume major charts version is nine less than major GitLab version.
# If this breaks and the version isn't found, it might be because they
# are no longer exactly 9 releases behind. Ask the distribution team
# about it.
major = major.to_i - 9
"#{major}-#{minor}-stable"
end
def default_branch(repo)
# Get the URL-encoded path of the project
# https://docs.gitlab.com/ee/api/README.html#namespaced-path-encoding
url_encoded_path = repo.sub('https://gitlab.com/', '').sub('.git', '').gsub('/', '%2F')
`curl --silent https://gitlab.com/api/v4/projects/#{url_encoded_path} | jq --raw-output .default_branch`.tr("\n", '')
end
def current_milestone(release_date = Time.zone.today.strftime("%Y-%m"))
@current_milestone ||= begin
# Search in the release dates hash for this month's release date
# and fetch the milestone version number.
releases = JSON.parse(get_release_dates)
releases.find { |item| item["date"].start_with?(release_date) }&.fetch("version", nil)
end
end
end