From 177bab38c74be0a41e3f1f3c74df974fd193701c Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 21 Mar 2024 21:36:07 -0700 Subject: [PATCH] Port Homebrew::DevCmd::Release --- Library/Homebrew/dev-cmd/release.rb | 171 +++++++++--------- Library/Homebrew/test/dev-cmd/release_spec.rb | 3 +- 2 files changed, 87 insertions(+), 87 deletions(-) diff --git a/Library/Homebrew/dev-cmd/release.rb b/Library/Homebrew/dev-cmd/release.rb index ec6e46a414..75fbab3511 100644 --- a/Library/Homebrew/dev-cmd/release.rb +++ b/Library/Homebrew/dev-cmd/release.rb @@ -1,100 +1,99 @@ -# typed: true +# typed: strict # frozen_string_literal: true +require "abstract_command" require "cli/parser" module Homebrew - module_function + module DevCmd + class Release < AbstractCommand + cmd_args do + description <<~EOS + Create a new draft Homebrew/brew release with the appropriate version number and release notes. - sig { returns(CLI::Parser) } - def release_args - Homebrew::CLI::Parser.new do - description <<~EOS - Create a new draft Homebrew/brew release with the appropriate version number and release notes. + By default, `brew release` will bump the patch version number. Pass + `--major` or `--minor` to bump the major or minor version numbers, respectively. + The command will fail if the previous major or minor release was made less than + one month ago. - By default, `brew release` will bump the patch version number. Pass - `--major` or `--minor` to bump the major or minor version numbers, respectively. - The command will fail if the previous major or minor release was made less than - one month ago. + *Note:* Requires write access to the Homebrew/brew repository. + EOS + switch "--major", + description: "Create a major release." + switch "--minor", + description: "Create a minor release." + conflicts "--major", "--minor" - *Note:* Requires write access to the Homebrew/brew repository. - EOS - switch "--major", - description: "Create a major release." - switch "--minor", - description: "Create a minor release." - conflicts "--major", "--minor" - - named_args :none - end - end - - def release - args = release_args.parse - - safe_system "git", "-C", HOMEBREW_REPOSITORY, "fetch", "origin" if Homebrew::EnvConfig.no_auto_update? - - begin - latest_release = GitHub.get_latest_release "Homebrew", "brew" - rescue GitHub::API::HTTPNotFoundError - odie "No existing releases found!" - end - latest_version = Version.new latest_release["tag_name"] - - if args.major? || args.minor? - one_month_ago = Date.today << 1 - latest_major_minor_release = begin - GitHub.get_release "Homebrew", "brew", "#{latest_version.major_minor}.0" - rescue GitHub::API::HTTPNotFoundError - nil + named_args :none end - if latest_major_minor_release.blank? - opoo "Unable to determine the release date of the latest major/minor release." - elsif Date.parse(latest_major_minor_release["published_at"]) > one_month_ago - odie "The latest major/minor release was less than one month ago." + sig { override.void } + def run + safe_system "git", "-C", HOMEBREW_REPOSITORY, "fetch", "origin" if Homebrew::EnvConfig.no_auto_update? + + begin + latest_release = GitHub.get_latest_release "Homebrew", "brew" + rescue GitHub::API::HTTPNotFoundError + odie "No existing releases found!" + end + latest_version = Version.new latest_release["tag_name"] + + if args.major? || args.minor? + one_month_ago = Date.today << 1 + latest_major_minor_release = begin + GitHub.get_release "Homebrew", "brew", "#{latest_version.major_minor}.0" + rescue GitHub::API::HTTPNotFoundError + nil + end + + if latest_major_minor_release.blank? + opoo "Unable to determine the release date of the latest major/minor release." + elsif Date.parse(latest_major_minor_release["published_at"]) > one_month_ago + odie "The latest major/minor release was less than one month ago." + end + end + + new_version = if args.major? + Version.new "#{latest_version.major.to_i + 1}.0.0" + elsif args.minor? + Version.new "#{latest_version.major}.#{latest_version.minor.to_i + 1}.0" + else + Version.new "#{latest_version.major}.#{latest_version.minor}.#{latest_version.patch.to_i + 1}" + end.to_s + + if args.major? || args.minor? + latest_major_minor_version = "#{latest_version.major}.#{latest_version.minor.to_i}.0" + ohai "Release notes since #{latest_major_minor_version} for #{new_version} blog post:" + # release notes without usernames, new contributors, or extra lines + blog_post_notes = GitHub.generate_release_notes("Homebrew", "brew", new_version, + previous_tag: latest_major_minor_version)["body"] + blog_post_notes = blog_post_notes.lines.filter_map do |line| + next unless (match = line.match(/^\* (.*) by @[\w-]+ in (.*)$/)) + + "- [#{match[1]}](#{match[2]})" + end.sort + puts blog_post_notes + end + + ohai "Creating draft release for version #{new_version}" + + release_notes = if args.major? || args.minor? + "Release notes for this release can be found on the [Homebrew blog](https://brew.sh/blog/#{new_version}).\n" + else + "" + end + release_notes += GitHub.generate_release_notes("Homebrew", "brew", new_version, + previous_tag: latest_version)["body"] + + begin + release = GitHub.create_or_update_release "Homebrew", "brew", new_version, body: release_notes, draft: true + rescue *GitHub::API::ERRORS => e + odie "Unable to create release: #{e.message}!" + end + + puts release["html_url"] + exec_browser release["html_url"] end end - - new_version = if args.major? - Version.new "#{latest_version.major.to_i + 1}.0.0" - elsif args.minor? - Version.new "#{latest_version.major}.#{latest_version.minor.to_i + 1}.0" - else - Version.new "#{latest_version.major}.#{latest_version.minor}.#{latest_version.patch.to_i + 1}" - end.to_s - - if args.major? || args.minor? - latest_major_minor_version = "#{latest_version.major}.#{latest_version.minor.to_i}.0" - ohai "Release notes since #{latest_major_minor_version} for #{new_version} blog post:" - # release notes without usernames, new contributors, or extra lines - blog_post_notes = GitHub.generate_release_notes("Homebrew", "brew", new_version, - previous_tag: latest_major_minor_version)["body"] - blog_post_notes = blog_post_notes.lines.filter_map do |line| - next unless (match = line.match(/^\* (.*) by @[\w-]+ in (.*)$/)) - - "- [#{match[1]}](#{match[2]})" - end.sort - puts blog_post_notes - end - - ohai "Creating draft release for version #{new_version}" - - release_notes = if args.major? || args.minor? - "Release notes for this release can be found on the [Homebrew blog](https://brew.sh/blog/#{new_version}).\n" - else - "" - end - release_notes += GitHub.generate_release_notes("Homebrew", "brew", new_version, - previous_tag: latest_version)["body"] - - begin - release = GitHub.create_or_update_release "Homebrew", "brew", new_version, body: release_notes, draft: true - rescue *GitHub::API::ERRORS => e - odie "Unable to create release: #{e.message}!" - end - - puts release["html_url"] - exec_browser release["html_url"] end end diff --git a/Library/Homebrew/test/dev-cmd/release_spec.rb b/Library/Homebrew/test/dev-cmd/release_spec.rb index a46d08ebd0..d8f93b7ee0 100644 --- a/Library/Homebrew/test/dev-cmd/release_spec.rb +++ b/Library/Homebrew/test/dev-cmd/release_spec.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true require "cmd/shared_examples/args_parse" +require "dev-cmd/release" -RSpec.describe "brew release" do +RSpec.describe Homebrew::DevCmd::Release do it_behaves_like "parseable arguments" end