Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-12-07 03:08:34 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-12-07 03:08:34 +0300
commit7e89568aa1b1c531aa34860fbd9e77d9e988b9b2 (patch)
tree9d644d947b75594d969f040ef046541c769e0dc3 /tooling
parentf2143c9986ad7b6206b8a41cc9aeb419e543d3f5 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'tooling')
-rw-r--r--tooling/danger/stable_branch.rb138
1 files changed, 138 insertions, 0 deletions
diff --git a/tooling/danger/stable_branch.rb b/tooling/danger/stable_branch.rb
new file mode 100644
index 00000000000..6c0b94b4f06
--- /dev/null
+++ b/tooling/danger/stable_branch.rb
@@ -0,0 +1,138 @@
+# frozen_string_literal: true
+
+module Tooling
+ module Danger
+ module StableBranch
+ VersionApiError = Class.new(StandardError)
+
+ STABLE_BRANCH_REGEX = %r{\A(?<version>\d+-\d+)-stable-ee\z}.freeze
+
+ # rubocop:disable Lint/MixedRegexpCaptureTypes
+ VERSION_REGEX = %r{
+ \A(?<major>\d+)
+ \.(?<minor>\d+)
+ (\.(?<patch>\d+))?
+ (-(?<rc>rc(?<rc_number>\d*)))?
+ (-\h+\.\h+)?
+ (-ee|\.ee\.\d+)?\z
+ }x.freeze
+ # rubocop:enable Lint/MixedRegexpCaptureTypes
+
+ MAINTENANCE_POLICY_URL = 'https://docs.gitlab.com/ee/policy/maintenance.html'
+
+ MAINTENANCE_POLICY_MESSAGE = <<~MSG
+ See the [release and maintenance policy](#{MAINTENANCE_POLICY_URL}) for more information.
+ MSG
+
+ FEATURE_ERROR_MESSAGE = <<~MSG
+ This MR includes the `type::feature` label. Features do not qualify for patch releases. #{MAINTENANCE_POLICY_MESSAGE}
+ MSG
+
+ BUG_ERROR_MESSAGE = <<~MSG
+ This branch is meant for backporting bug fixes. If this MR qualifies please add the `type::bug` label. #{MAINTENANCE_POLICY_MESSAGE}
+ MSG
+
+ VERSION_ERROR_MESSAGE = <<~MSG
+ Patches are only being accepted on the most recent 3 minor versions of GitLab. #{MAINTENANCE_POLICY_MESSAGE}
+ MSG
+
+ FAILED_VERSION_REQUEST_MESSAGE = <<~MSG
+ There was a problem checking if this is a qualified version for backporting. Re-running this job may fix the problem.
+ MSG
+
+ # rubocop:disable Style/SignalException
+ def check!
+ return unless stable_target_branch && !helper.security_mr?
+
+ fail FEATURE_ERROR_MESSAGE if has_feature_label?
+ fail BUG_ERROR_MESSAGE unless has_bug_label?
+ fail VERSION_ERROR_MESSAGE unless targeting_patchable_version?
+ end
+ # rubocop:enable Style/SignalException
+
+ private
+
+ def stable_target_branch
+ helper.mr_target_branch.match(STABLE_BRANCH_REGEX)
+ end
+
+ def has_feature_label?
+ helper.mr_has_labels?('type::feature')
+ end
+
+ def has_bug_label?
+ helper.mr_has_labels?('type::bug')
+ end
+
+ def targeting_patchable_version?
+ raise VersionApiError if last_three_minor_versions.empty?
+
+ last_three_minor_versions.include?(targeted_version)
+ rescue VersionApiError
+ # don't fail the job since we do not know the recent versions
+ warn FAILED_VERSION_REQUEST_MESSAGE
+ true
+ end
+
+ def last_three_minor_versions
+ return [] unless versions
+
+ current_version = versions.first.match(VERSION_REGEX)
+ version_1 = previous_minor_version(current_version)
+ version_2 = previous_minor_version(version_1)
+
+ [
+ version_to_minor_string(current_version),
+ version_to_minor_string(version_1),
+ version_to_minor_string(version_2)
+ ]
+ end
+
+ def targeted_version
+ stable_target_branch[1].tr('-', '.')
+ end
+
+ def versions(page = 1)
+ version_api_endpoint = "https://version.gitlab.com/api/v1/versions?per_page=50&page=#{page}"
+ response = HTTParty.get(version_api_endpoint) # rubocop:disable Gitlab/HTTParty
+
+ raise VersionApiError unless response.success?
+
+ version_list = response.parsed_response.map { |v| v['version'] } # rubocop:disable Rails/Pluck
+
+ version_list.sort_by { |v| Gem::Version.new(v) }.reverse
+ end
+
+ def previous_minor_version(version)
+ previous_minor = version[:minor].to_i - 1
+
+ return "#{version[:major]}.#{previous_minor}".match(VERSION_REGEX) if previous_minor >= 0
+
+ fetch_last_minor_version_for_major(version[:major].to_i - 1)
+ end
+
+ def fetch_last_minor_version_for_major(major)
+ page = 1
+ last_minor_version = nil
+
+ while last_minor_version.nil?
+ last_minor_version = versions(page).find do |version|
+ version.split('.').first.to_i == major
+ end
+
+ break if page > 10
+
+ page += 1
+ end
+
+ raise VersionApiError if last_minor_version.nil?
+
+ last_minor_version.match(VERSION_REGEX)
+ end
+
+ def version_to_minor_string(version)
+ "#{version[:major]}.#{version[:minor]}"
+ end
+ end
+ end
+end