Skip to content

Commit

Permalink
Merge pull request #4092 from rubygems/unify_releases
Browse files Browse the repository at this point in the history
Unify release scripts for bundler & rubygems
  • Loading branch information
deivid-rodriguez committed Dec 3, 2020
2 parents 70d836d + c2967af commit f7f8f7c
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 198 deletions.
11 changes: 9 additions & 2 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,13 @@ task :check_deprecations do
end
end

desc "Prepare stable branch"
task :prepare_stable_branch, [:version] do |_t, opts|
require_relative "util/release"

Release.for_rubygems(opts[:version] || v.to_s).prepare!
end

desc "Install rubygems to local system"
task :install => [:clear_package, :package] do
sh "ruby -Ilib bin/gem install --no-document pkg/rubygems-update-#{v}.gem && update_rubygems --no-document"
Expand All @@ -111,9 +118,9 @@ end

desc "Generates the changelog for a specific target version"
task :generate_changelog, [:version] do |_t, opts|
require_relative "util/changelog"
require_relative "util/release"

Changelog.for_rubygems(opts[:version]).cut!
Release.for_rubygems(opts[:version]).cut_changelog!
end

desc "Release rubygems-#{v}"
Expand Down
49 changes: 3 additions & 46 deletions bundler/task/release.rake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require_relative "../lib/bundler/gem_tasks"
require_relative "../spec/support/build_metadata"
require_relative "../../util/changelog"
require_relative "../../util/release"

Bundler::GemHelper.tag_prefix = "bundler-"

Expand Down Expand Up @@ -32,56 +33,12 @@ namespace :release do
desc "Push the release to Github releases"
task :github do
gemspec_version = Bundler::GemHelper.gemspec.version
version = Gem::Version.new(gemspec_version)
release_notes = Changelog.for_bundler(gemspec_version).release_notes
tag = "bundler-v#{version}"

GithubInfo.client.create_release "rubygems/rubygems", tag, :name => tag,
:body => release_notes.join("\n").strip,
:prerelease => version.prerelease?
Release.for_bundler(gemspec_version).create_for_github!
end

desc "Prepare a new release"
task :prepare, [:version] do |_t, opts|
version = opts[:version]
changelog = Changelog.for_bundler(version)

branch = Gem::Version.new(version).segments.map.with_index {|s, i| i == 0 ? s + 1 : s }[0, 2].join(".")

previous_branch = `git rev-parse --abbrev-ref HEAD`.strip
release_branch = "release_bundler/#{version}"

sh("git", "checkout", "-b", release_branch, branch)

begin
prs = changelog.relevant_pull_requests_since_last_release

if prs.any? && !system("git", "cherry-pick", "-x", "-m", "1", *prs.map(&:merge_commit_sha))
warn <<~MSG
Opening a new shell to fix the cherry-pick errors manually. Run `git add . && git cherry-pick --continue` once done, and if it succeeds, run `exit 0` to resume the task.
Otherwise type `Ctrl-D` to cancel
MSG

unless system(ENV["SHELL"] || "zsh")
raise "Failed to resolve conflitcs, resetting original state"
end
end

version_file = "lib/bundler/version.rb"
version_contents = File.read(version_file)
unless version_contents.sub!(/^(\s*VERSION = )"#{Gem::Version::VERSION_PATTERN}"/, "\\1#{version.to_s.dump}")
raise "Failed to update #{version_file}, is it in the expected format?"
end
File.open(version_file, "w") {|f| f.write(version_contents) }

changelog.cut!

sh("git", "commit", "-am", "Version #{version} with changelog")
rescue StandardError
sh("git", "checkout", previous_branch)
sh("git", "branch", "-D", release_branch)
raise
end
Release.for_bundler(opts[:version]).prepare!
end
end
66 changes: 13 additions & 53 deletions util/changelog.rb
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
# frozen_string_literal: true

require_relative "github_info"
require "yaml"

class Changelog
def self.for_rubygems(version)
@rubygems ||= new(
"History.txt",
version,
:latest_release => GithubInfo.latest_release_for("rubygems"),
)
end

def self.for_bundler(version)
@bundler ||= new(
"CHANGELOG.md",
version,
:latest_release => GithubInfo.latest_release_for("bundler"),
)
end

def initialize(file, version, latest_release:)
def initialize(file, version)
@version = Gem::Version.new(version)
@file = File.expand_path(file)
@config = YAML.load_file("#{File.dirname(file)}/.changelog.yml")
Expand All @@ -31,7 +28,6 @@ def initialize(file, version, latest_release:)
else
:patch
end
@latest_release = latest_release
end

def release_notes
Expand Down Expand Up @@ -78,21 +74,21 @@ def change_types_for_blog
types << last_change_type
end

def cut!
def cut!(previous_version, included_pull_requests)
full_new_changelog = [
format_header,
"",
unreleased_notes,
released_notes,
unreleased_notes_for(included_pull_requests),
released_notes_until(previous_version),
].join("\n") + "\n"

File.write(@file, full_new_changelog)
end

def unreleased_notes
def unreleased_notes_for(included_pull_requests)
lines = []

group_by_labels(relevant_pull_requests_since_last_release).each do |label, pulls|
group_by_labels(included_pull_requests).each do |label, pulls|
category = changelog_label_mapping[label]

lines << category
Expand All @@ -108,12 +104,13 @@ def unreleased_notes
lines
end

def relevant_pull_requests_since_last_release
last_release_date = @latest_release.created_at
def relevant_label_for(pull)
relevant_labels = pull.labels.map(&:name) & changelog_labels
return unless relevant_labels.any?

pr_ids = merged_pr_ids_since(last_release_date)
raise "#{pull.html_url} has multiple labels that map to changelog sections" unless relevant_labels.size == 1

relevant_pull_requests_for(pr_ids)
relevant_labels.first
end

private
Expand Down Expand Up @@ -175,15 +172,6 @@ def group_by_labels(pulls)
end.to_h
end

def relevant_label_for(pull)
relevant_labels = pull.labels.map(&:name) & changelog_labels
return unless relevant_labels.any?

raise "#{pull.html_url} has multiple labels that map to changelog sections" unless relevant_labels.size == 1

relevant_labels.first
end

def relevant_changelog_label_mapping
if @level == :patch
changelog_label_mapping.slice(*patch_level_labels)
Expand All @@ -202,32 +190,8 @@ def change_types
relevant_changelog_label_mapping.values
end

def merged_pr_ids_since(date)
commits = `git log --oneline origin/master --since '#{date}'`.split("\n").map {|l| l.split(/\s/, 2) }
commits.map do |_sha, message|
match = /Merge pull request #(\d+)/.match(message)
next unless match

match[1].to_i
end.compact
end

def relevant_pull_requests_for(ids)
pulls = gh_client.pull_requests("rubygems/rubygems", :sort => :updated, :state => :closed, :direction => :desc)

loop do
pulls.select! {|pull| ids.include?(pull.number) }

break if (pulls.map(&:number) & ids).to_set == ids.to_set

pulls.concat gh_client.get(gh_client.last_response.rels[:next].href)
end

pulls.select {|pull| relevant_label_for(pull) }.sort_by(&:merged_at)
end

def released_notes
lines.drop_while {|line| !line.start_with?(release_section_token) || !line.include?(@latest_release.tag_name.gsub(/^.*-v/, "")) }
def released_notes_until(version)
lines.drop_while {|line| !line.start_with?(release_section_token) || !line.include?(version) }
end

def lines
Expand Down Expand Up @@ -269,8 +233,4 @@ def patch_level_labels
def minor_level_labels
@config["minor_level_labels"]
end

def gh_client
GithubInfo.client
end
end
21 changes: 0 additions & 21 deletions util/github_info.rb

This file was deleted.

76 changes: 0 additions & 76 deletions util/patch_with_prs.rb

This file was deleted.

0 comments on commit f7f8f7c

Please sign in to comment.