diff options
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.rb | 12 |
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 |