From 6ec1d63157053db43b7191d641df514a09283c91 Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Wed, 23 Mar 2022 15:34:49 +0200 Subject: [PATCH 1/5] Script first part of releasing --- Gemfile | 1 + Gemfile.lock | 44 ++++++++++++++--- Rakefile | 27 +++++++++++ lib/shopify_cli/changelog.rb | 75 ++++++++++++++++++++++++++++ lib/shopify_cli/release.rb | 94 ++++++++++++++++++++++++++++++++++++ lib/shopify_cli/sed.rb | 19 ++++++++ 6 files changed, 254 insertions(+), 6 deletions(-) create mode 100644 lib/shopify_cli/changelog.rb create mode 100644 lib/shopify_cli/release.rb create mode 100644 lib/shopify_cli/sed.rb diff --git a/Gemfile b/Gemfile index ca1bb83cf4..4fcb2b0fab 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ group :development, :test do gem "rubocop-rake", require: false gem "iniparse", "~> 1.5" gem "colorize", "~> 0.8.1" + gem "octokit", "~> 4.0" end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 0dda22cc65..b15fcd142f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,13 +13,13 @@ GEM public_suffix (>= 2.0.2, < 5.0) ansi (1.5.0) ast (2.4.2) - bugsnag (6.23.0) + bugsnag (6.24.2) concurrent-ruby (~> 1.0) builder (3.2.4) byebug (11.1.3) coderay (1.1.3) colorize (0.8.1) - concurrent-ruby (1.1.9) + concurrent-ruby (1.1.10) crack (0.4.5) rexml cucumber (7.0.0) @@ -55,11 +55,34 @@ GEM cucumber-messages (~> 17.0, >= 17.0.1) diff-lcs (1.4.4) fakefs (1.3.2) + faraday (1.10.0) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) + faraday-net_http (~> 1.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.3) + multipart-post (>= 1.2, < 3) + faraday-net_http (1.0.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) ffi (1.15.4) hashdiff (1.0.1) iniparse (1.5.0) - liquid (5.1.0) - listen (3.7.0) + liquid (5.3.0) + listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) method_source (1.0.0) @@ -77,9 +100,13 @@ GEM ruby-progressbar mocha (1.13.0) multi_test (0.1.2) + multipart-post (2.1.1) nokogiri (1.13.3) mini_portile2 (~> 2.8.0) racc (~> 1.4) + octokit (4.22.0) + faraday (>= 0.9) + sawyer (~> 0.8.0, >= 0.5.3) parallel (1.21.0) parser (3.1.1.0) ast (~> 2.4.1) @@ -94,7 +121,7 @@ GEM rack (2.2.3) rainbow (3.1.1) rake (13.0.6) - rb-fsevent (0.11.0) + rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) regexp_parser (2.2.0) @@ -117,9 +144,13 @@ GEM rubocop-shopify (2.0.1) rubocop (~> 1.11) ruby-progressbar (1.11.0) + ruby2_keywords (0.0.5) + sawyer (0.8.2) + addressable (>= 2.3.5) + faraday (> 0.8, < 2.0) sys-uname (1.2.2) ffi (~> 1.1) - theme-check (1.10.1) + theme-check (1.10.2) liquid (>= 5.1.0) nokogiri (>= 1.12) parser (~> 3) @@ -144,6 +175,7 @@ DEPENDENCIES minitest-fail-fast minitest-reporters mocha + octokit (~> 4.0) pry-byebug rack rake diff --git a/Rakefile b/Rakefile index 793062f83a..066182ee00 100644 --- a/Rakefile +++ b/Rakefile @@ -129,6 +129,33 @@ end desc("Builds all distribution packages of the CLI") task(package: "package:all") +namespace :release do + require "shopify_cli/release" + + task :prepare, [:new_version] do |_t, args| + new_version = args[:new_version] + unless new_version + raise <<~NO_NEW_VERSION + New version must be provided, e.g.: + + $ GITHUB_ACCESS_TOKEN=abcdef rake "release:prepare[1.2.3]" + + NO_NEW_VERSION + end + github_access_token = ENV['GITHUB_ACCESS_TOKEN'] + unless github_access_token + raise <<~NO_GITHUB_ACCESS_TOKEN + GitHub access token must be provided, e.g.: + + $ GITHUB_ACCESS_TOKEN=abcdef rake "release:prepare[1.2.3]" + NO_GITHUB_ACCESS_TOKEN + end + + ShopifyCLI::Release.new(new_version, github_access_token).create! + puts "Completed!" + end +end + namespace :extensions do task :update do version = ENV.fetch("VERSION").strip diff --git a/lib/shopify_cli/changelog.rb b/lib/shopify_cli/changelog.rb new file mode 100644 index 0000000000..3d675150c2 --- /dev/null +++ b/lib/shopify_cli/changelog.rb @@ -0,0 +1,75 @@ +require 'shopify_cli/sed' + +module ShopifyCLI + class Changelog + CHANGELOG_FILE = File.join(ShopifyCLI::ROOT, "CHANGELOG.md") + + def initialize + load(File.read(CHANGELOG_FILE)) + end + + def update_version!(new_version) + Sed.new.replace_inline( + CHANGELOG_FILE, + "## \\[Unreleased\\]", + "## [Unreleased]\\n\\n## Version #{new_version}" + ) + end + + def release_notes(version) + changes[version].map { |change_category, changes| + <<~CHANGES + ### #{change_category} + #{changes.map { |change| entry(**change) }.join("\n")} + CHANGES + }.join("\n") + end + + def entry(pr_id:, desc:) + "* [##{pr_id}](https://github.com/Shopify/shopify-cli/pull/#{pr_id}): #{desc}" + end + + private + + def changes + @changes ||= Hash.new do |h, k| + h[k] = Hash.new do |h, k| + h[k] = [] + end + end + end + + def load(log) + state = :initial + change_category = nil + current_version = nil + @remainder = "" + log.each_line do |line| + case state + when :initial + next unless line.chomp == "\#\# [Unreleased]" + state = :unreleased + current_version = "Unreleased" + when :unreleased, :last_version + if /\A\#\#\# (?\w+)/ =~ line + change_category = category + elsif %r{\A\* \[\#(?\d+)\]\(https://github.com/Shopify/shopify-cli/pull/\d+\): (?.+)\n} =~ line + changes[current_version][change_category] << { pr_id: pr_id, desc: desc } + elsif /\A\#\# Version (?\d+\.\d+\.\d+)/ =~ line + current_version = version + case state + when :unreleased + state = :last_version + else + state = :finished + end + elsif !line.match?(/\s*\n/) + raise "Unrecognized line: #{line.inspect}" + end + when :finished + @remainder << line + end + end + end + end +end diff --git a/lib/shopify_cli/release.rb b/lib/shopify_cli/release.rb new file mode 100644 index 0000000000..2f647d312e --- /dev/null +++ b/lib/shopify_cli/release.rb @@ -0,0 +1,94 @@ +require 'shopify_cli/sed' +require 'shopify_cli/changelog' +require 'octokit' + +module ShopifyCLI + class Release + def initialize(new_version, github_access_token) + @new_version = new_version + @changelog = ShopifyCLI::Changelog.new + @github = Octokit::Client.new(access_token: github_access_token) + end + + def create! + ensure_updated_main + create_release_branch + update_changelog + update_versions_in_files + commit + pr = create_pr + system("open #{pr["html_url"]}") + end + + private + + attr_reader :new_version, :changelog, :github + + def ensure_updated_main + current_branch = `git branch --show-current` + unless current_branch == "main" + raise "Must be on the main branch to package a release!" + end + unless system("git pull") + raise "git pull failed, cannot be sure there aren't new commits!" + end + end + + def create_release_branch + puts "Checking out release branch" + unless system("git checkout -b #{release_branch_name}") + puts "Cannot check out release branch!" + end + end + + def update_changelog + if release_notes.empty? + puts "No unreleased CHANGELOG updates found!" + else + puts "Updating CHANGELOG" + changelog.update_version!(new_version) + end + end + + def update_versions_in_files + version_file = File.join(ShopifyCLI::ROOT, "lib/shopify_cli/version.rb") + puts "Updating version.rb" + ShopifyCLI::Sed.new.replace_inline(version_file, ShopifyCLI::VERSION, new_version) + gemfile_lock = File.join(ShopifyCLI::ROOT, "Gemfile.lock") + puts "Updating Gemfile.lock" + ShopifyCLI::Sed.new.replace_inline( + gemfile_lock, + "shopify-cli (#{ShopifyCLI::VERSION})", + "shopify-cli (#{new_version})", + ) + end + + def commit + puts "Committing" + unless system("git commit -am 'Packaging for release v#{new_version}'") + puts "Commit failed!" + end + unless system("git push -u origin #{release_branch_name}") + puts "Failed to push branch!" + end + end + + def create_pr + github.create_pull_request( + "Shopify/shopify-cli", + "main", + release_branch_name, + "Packaging for release v#{new_version}", + release_notes + ) + end + + def release_branch_name + @release_branch_name ||= "release_#{new_version.split('.').join('_')}" + end + + def release_notes + @release_notes ||= changelog.release_notes("Unreleased") + end + end +end diff --git a/lib/shopify_cli/sed.rb b/lib/shopify_cli/sed.rb new file mode 100644 index 0000000000..5479f5a814 --- /dev/null +++ b/lib/shopify_cli/sed.rb @@ -0,0 +1,19 @@ +module ShopifyCLI + class Sed + class SedError < StandardError; end + + def replace_inline(filename, pattern, output) + command = + case CLI::Kit::System.os + when :mac + "sed -i ''" + when :linux + "sed -i" + else + raise "Unrecognized system!" + end + success = system("#{command} 's/#{pattern}/#{output}/' #{filename}") + raise SedError unless success + end + end +end From f8264b8b14424b30566eb2e82416e94d72fce8d4 Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Wed, 23 Mar 2022 15:36:39 +0200 Subject: [PATCH 2/5] Packaging for release v2.15.1 --- CHANGELOG.md | 2 ++ Gemfile.lock | 2 +- lib/shopify_cli/release.rb | 2 +- lib/shopify_cli/version.rb | 2 +- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 72b65453fb..92ddf754a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ From version 2.6.0, the sections in this file adhere to the [keep a changelog](h ## [Unreleased] +## Version 2.15.1 + ### Added * [#1934](https://github.com/Shopify/shopify-cli/pull/1934): Block directories in theme assets * [#1880](https://github.com/Shopify/shopify-cli/pull/1880): Recognize attempts to pass a store name and suggest correction diff --git a/Gemfile.lock b/Gemfile.lock index b15fcd142f..d5766a8a4a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - shopify-cli (2.15.0) + shopify-cli (2.15.1) bugsnag (~> 6.22) listen (~> 3.7.0) theme-check (~> 1.10.1) diff --git a/lib/shopify_cli/release.rb b/lib/shopify_cli/release.rb index 2f647d312e..63c42ca988 100644 --- a/lib/shopify_cli/release.rb +++ b/lib/shopify_cli/release.rb @@ -11,7 +11,7 @@ def initialize(new_version, github_access_token) end def create! - ensure_updated_main + #ensure_updated_main create_release_branch update_changelog update_versions_in_files diff --git a/lib/shopify_cli/version.rb b/lib/shopify_cli/version.rb index 4ad8985ca8..d64cb2b49c 100644 --- a/lib/shopify_cli/version.rb +++ b/lib/shopify_cli/version.rb @@ -1,3 +1,3 @@ module ShopifyCLI - VERSION = "2.15.0" + VERSION = "2.15.1" end From 35d8d119fc27f84ad1badb3bf038014de411166c Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Wed, 23 Mar 2022 16:02:15 +0200 Subject: [PATCH 3/5] Output when PR created --- lib/shopify_cli/release.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/shopify_cli/release.rb b/lib/shopify_cli/release.rb index 63c42ca988..22647c1e48 100644 --- a/lib/shopify_cli/release.rb +++ b/lib/shopify_cli/release.rb @@ -80,7 +80,7 @@ def create_pr release_branch_name, "Packaging for release v#{new_version}", release_notes - ) + ).tap { |results| puts "Created PR ##{results["number"]}" } end def release_branch_name From 7cc745eef7bc87484557b9b187b54d2c445b70ab Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Thu, 24 Mar 2022 12:49:58 +0200 Subject: [PATCH 4/5] Rubofixes --- Rakefile | 2 +- lib/shopify_cli/changelog.rb | 23 ++++++++++++----------- lib/shopify_cli/release.rb | 12 ++++++------ 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/Rakefile b/Rakefile index 066182ee00..8282333cf1 100644 --- a/Rakefile +++ b/Rakefile @@ -142,7 +142,7 @@ namespace :release do NO_NEW_VERSION end - github_access_token = ENV['GITHUB_ACCESS_TOKEN'] + github_access_token = ENV["GITHUB_ACCESS_TOKEN"] unless github_access_token raise <<~NO_GITHUB_ACCESS_TOKEN GitHub access token must be provided, e.g.: diff --git a/lib/shopify_cli/changelog.rb b/lib/shopify_cli/changelog.rb index 3d675150c2..bf2e7c40e9 100644 --- a/lib/shopify_cli/changelog.rb +++ b/lib/shopify_cli/changelog.rb @@ -1,4 +1,4 @@ -require 'shopify_cli/sed' +require "shopify_cli/sed" module ShopifyCLI class Changelog @@ -17,12 +17,12 @@ def update_version!(new_version) end def release_notes(version) - changes[version].map { |change_category, changes| + changes[version].map do |change_category, changes| <<~CHANGES ### #{change_category} #{changes.map { |change| entry(**change) }.join("\n")} CHANGES - }.join("\n") + end.join("\n") end def entry(pr_id:, desc:) @@ -33,8 +33,8 @@ def entry(pr_id:, desc:) def changes @changes ||= Hash.new do |h, k| - h[k] = Hash.new do |h, k| - h[k] = [] + h[k] = Hash.new do |h2, k2| + h2[k2] = [] end end end @@ -57,12 +57,13 @@ def load(log) changes[current_version][change_category] << { pr_id: pr_id, desc: desc } elsif /\A\#\# Version (?\d+\.\d+\.\d+)/ =~ line current_version = version - case state - when :unreleased - state = :last_version - else - state = :finished - end + state = + case state + when :unreleased + :last_version + else + :finished + end elsif !line.match?(/\s*\n/) raise "Unrecognized line: #{line.inspect}" end diff --git a/lib/shopify_cli/release.rb b/lib/shopify_cli/release.rb index 22647c1e48..4ec5c46467 100644 --- a/lib/shopify_cli/release.rb +++ b/lib/shopify_cli/release.rb @@ -1,6 +1,6 @@ -require 'shopify_cli/sed' -require 'shopify_cli/changelog' -require 'octokit' +require "shopify_cli/sed" +require "shopify_cli/changelog" +require "octokit" module ShopifyCLI class Release @@ -11,7 +11,7 @@ def initialize(new_version, github_access_token) end def create! - #ensure_updated_main + ensure_updated_main create_release_branch update_changelog update_versions_in_files @@ -25,7 +25,7 @@ def create! attr_reader :new_version, :changelog, :github def ensure_updated_main - current_branch = `git branch --show-current` + current_branch = %x(git branch --show-current) unless current_branch == "main" raise "Must be on the main branch to package a release!" end @@ -84,7 +84,7 @@ def create_pr end def release_branch_name - @release_branch_name ||= "release_#{new_version.split('.').join('_')}" + @release_branch_name ||= "release_#{new_version.split(".").join("_")}" end def release_notes From 971a4c483b0cd9d7b455faae0b7ada9eeff46bcf Mon Sep 17 00:00:00 2001 From: Ariel Caplan Date: Thu, 24 Mar 2022 12:51:38 +0200 Subject: [PATCH 5/5] Rename method more accurately --- Rakefile | 2 +- lib/shopify_cli/release.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Rakefile b/Rakefile index 8282333cf1..691fb2061c 100644 --- a/Rakefile +++ b/Rakefile @@ -151,7 +151,7 @@ namespace :release do NO_GITHUB_ACCESS_TOKEN end - ShopifyCLI::Release.new(new_version, github_access_token).create! + ShopifyCLI::Release.new(new_version, github_access_token).prepare! puts "Completed!" end end diff --git a/lib/shopify_cli/release.rb b/lib/shopify_cli/release.rb index 4ec5c46467..b30711befe 100644 --- a/lib/shopify_cli/release.rb +++ b/lib/shopify_cli/release.rb @@ -10,7 +10,7 @@ def initialize(new_version, github_access_token) @github = Octokit::Client.new(access_token: github_access_token) end - def create! + def prepare! ensure_updated_main create_release_branch update_changelog