Class: SemVerComponents::Outputs::SemanticReleaseGenerateNotes
- Inherits:
-
SemVerComponents::Output
- Object
- SemVerComponents::Output
- SemVerComponents::Outputs::SemanticReleaseGenerateNotes
- Defined in:
- lib/sem_ver_components/outputs/semantic_release_generate_notes.rb
Overview
Output plugin generating release notes in the semantic-release changelog format
Instance Method Summary collapse
-
#process(commits_info) ⇒ Object
Process commits info.
Methods inherited from SemVerComponents::Output
Constructor Details
This class inherits a constructor from SemVerComponents::Output
Instance Method Details
#process(commits_info) ⇒ Object
Process commits info
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/sem_ver_components/outputs/semantic_release_generate_notes.rb', line 12 def process(commits_info) # Compute new version new_version = Semver.next_version_from( Semver.version_from_git_ref(@local_git.git_from), commits_info.map { |commit_info| commit_info[:components_bump_levels].values }.flatten(1).max ) git_url = @local_git.git.remote_list.find { |remote| remote.name == 'origin' }.url.first git_url = git_url[0..-5] if git_url.end_with?('.git') # Reference merge commits: merged commits will not be part of the changelog, # but their bump level will be taken into account when reporting the merge commit. # List of merged commits' shas, per merge commit sha. # Hash< String, Array< String > > merge_commits = {} commits_info.each do |commit_info| git_commit = commit_info[:commit] git_commit_parents = git_commit.parents # In the case of a merge commit, reference all commits that are part of this merge commit, directly from the graph next unless git_commit_parents.size > 1 git_commit_sha = git_commit.sha merge_commits[git_commit_sha] = @local_git.git.log(nil).between(@local_git.git.merge_base(*git_commit_parents.map(&:sha)).first, git_commit_sha).execute[1..].map(&:sha) end commits_to_ignore = merge_commits.values.flatten(1).sort.uniq # Group commits per bump level, per component # Hash< String or nil, Hash< Integer, Array<Git::Object::Commit> > commits_per_component = {} commits_info.each do |commit_info| git_commit = commit_info[:commit] git_commit_sha = git_commit.sha # Don't put merged commits as we consider the changelog should contain the merge commit comment. next if commits_to_ignore.include?(git_commit_sha) components_bump_levels = commit_info[:components_bump_levels] # If we are dealing with a merge commit, consider the components' bump levels of the merged commits if merge_commits.key?(git_commit_sha) merge_commits[git_commit_sha].each do |merged_commit_sha| merged_commit_info = commits_info.find { |search_commit_info| search_commit_info[:commit].sha == merged_commit_sha } # If the merged commit is not part of the list of commits, it means that the merge commit was not rebased on the previous release tag. # In this case we can have some merged commits that are already part of the previous release. # So we can ignore them. next if merged_commit_info.nil? components_bump_levels = components_bump_levels.merge(merged_commit_info[:components_bump_levels]) do |_component, bump_level1, bump_level2| [bump_level1, bump_level2].max end end end components_bump_levels.each do |component, bump_level| commits_per_component[component] = {} unless commits_per_component.key?(component) commits_per_component[component][bump_level] = [] unless commits_per_component[component].key?(bump_level) commits_per_component[component][bump_level] << git_commit end end puts "# [v#{new_version}](#{@git_hosting.compare_url(git_url, @local_git.git_from, "v#{new_version}")}) (#{Time.now.utc.strftime('%F %T')})" puts commits_per_component.sort_by { |component, _component_info| component || '' }.each do |(component, component_info)| puts "## #{component.nil? ? 'Global changes' : "Changes for #{component}"}\n" if commits_per_component.size > 1 || !component.nil? component_info.each do |bump_level, commits| puts "### #{ case bump_level when 0 'Patches' when 1 'Features' when 2 'Breaking changes' else raise "Invalid bump level: #{bump_level}" end }" puts # Gather an ordered set of commit lines (with the corresponding commit sha) in order to not duplicate the info when there are merge commits # Hash< String, String > commit_lines = {} commits.each do |commit| = commit..split("\n") commit_line = .first if commit_line =~ /^Merge pull request .+$/ # Consider the next line as commit line next_line = [1..].join("\n").strip.split("\n").first commit_line = next_line unless next_line.nil? end commit_lines[commit_line] = commit.sha end commit_lines.each do |commit_line, commit_sha| puts "* [#{commit_line}](#{@git_hosting.commit_url(git_url, commit_sha)})" end puts end end end |