summaryrefslogtreecommitdiff
path: root/app/finders/repositories
diff options
context:
space:
mode:
Diffstat (limited to 'app/finders/repositories')
-rw-r--r--app/finders/repositories/changelog_commits_finder.rb (renamed from app/finders/repositories/commits_with_trailer_finder.rb)25
-rw-r--r--app/finders/repositories/previous_tag_finder.rb12
2 files changed, 31 insertions, 6 deletions
diff --git a/app/finders/repositories/commits_with_trailer_finder.rb b/app/finders/repositories/changelog_commits_finder.rb
index 4bd643c345b..b80b8e94e59 100644
--- a/app/finders/repositories/commits_with_trailer_finder.rb
+++ b/app/finders/repositories/changelog_commits_finder.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module Repositories
- # Finder for obtaining commits between two refs, with a Git trailer set.
- class CommitsWithTrailerFinder
+ # Finder for getting the commits to include in a changelog.
+ class ChangelogCommitsFinder
# The maximum number of commits to retrieve per page.
#
# This value is arbitrarily chosen. Lowering it means more Gitaly calls, but
@@ -20,6 +20,9 @@ module Repositories
# 5-10 Gitaly calls, while keeping memory usage at a reasonable amount.
COMMITS_PER_PAGE = 1024
+ # The regex to use for extracting the SHA of a reverted commit.
+ REVERT_REGEX = /^This reverts commit (?<sha>[0-9a-f]{40})/i.freeze
+
# The `project` argument specifies the project for which to obtain the
# commits.
#
@@ -44,7 +47,7 @@ module Repositories
#
# Example:
#
- # CommitsWithTrailerFinder.new(...).each_page('Signed-off-by') do |commits|
+ # ChangelogCommitsFinder.new(...).each_page('Changelog') do |commits|
# commits.each do |commit|
# ...
# end
@@ -53,12 +56,22 @@ module Repositories
return to_enum(__method__, trailer) unless block_given?
offset = 0
+ reverted = Set.new
response = fetch_commits
while response.any?
commits = []
response.each do |commit|
+ # If the commit is reverted in the same range (by a newer commit), we
+ # won't include it. This works here because commits are processed in
+ # reverse order (= newer first).
+ next if reverted.include?(commit.id)
+
+ if (sha = revert_commit_sha(commit))
+ reverted << sha
+ end
+
commits.push(commit) if commit.trailers.key?(trailer)
end
@@ -78,5 +91,11 @@ module Repositories
.repository
.commits(range, limit: @per_page, offset: offset, trailers: true)
end
+
+ def revert_commit_sha(commit)
+ matches = commit.description&.match(REVERT_REGEX)
+
+ matches[:sha] if matches
+ end
end
end
diff --git a/app/finders/repositories/previous_tag_finder.rb b/app/finders/repositories/previous_tag_finder.rb
index 150a6332c29..b5e786c30e9 100644
--- a/app/finders/repositories/previous_tag_finder.rb
+++ b/app/finders/repositories/previous_tag_finder.rb
@@ -16,12 +16,13 @@ module Repositories
# This finder expects that all tags to consider meet the following
# requirements:
#
- # * They start with the letter "v"
- # * They use semantic versioning for the tag format
+ # * They start with the letter "v" followed by a version, or immediately start
+ # with a version
+ # * They use semantic versioning for the version format
#
# Tags not meeting these requirements are ignored.
class PreviousTagFinder
- TAG_REGEX = /\Av(?<version>#{Gitlab::Regex.unbounded_semver_regex})\z/.freeze
+ TAG_REGEX = /\Av?(?<version>#{Gitlab::Regex.unbounded_semver_regex})\z/.freeze
def initialize(project)
@project = project
@@ -36,6 +37,11 @@ module Repositories
next unless matches
+ # When using this class for generating changelog data for a range of
+ # commits, we want to compare against the tag of the last _stable_
+ # release; not some random RC that came after that.
+ next if matches[:prerelease]
+
version = matches[:version]
tags[version] = tag
versions << version