From 7a73236bc448da73750b231b4c43817004bbe133 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Mon, 15 Jul 2024 11:57:49 +0200 Subject: [PATCH 01/24] Run webpack rake task for v0.27 --- lib/decidim/maintainers_toolbox/releaser.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/decidim/maintainers_toolbox/releaser.rb b/lib/decidim/maintainers_toolbox/releaser.rb index 9d15648..bf3a8f8 100644 --- a/lib/decidim/maintainers_toolbox/releaser.rb +++ b/lib/decidim/maintainers_toolbox/releaser.rb @@ -37,11 +37,15 @@ def call run("git checkout #{release_branch}") run("git pull origin #{release_branch}") + bump_decidim_version run("bin/rake update_versions") + run("bin/rake patch_generators") + run("bin/rake bundle") run("npm install") + run("bin/rake webpack") if Dir.exists?("decidim_app-design") check_tests From c829d5ffd4391ddc17292dec0232f9aa1ec66013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Mon, 15 Jul 2024 11:58:40 +0200 Subject: [PATCH 02/24] Add i18n environment variables to local rspec run --- lib/decidim/maintainers_toolbox/releaser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decidim/maintainers_toolbox/releaser.rb b/lib/decidim/maintainers_toolbox/releaser.rb index bf3a8f8..a909de2 100644 --- a/lib/decidim/maintainers_toolbox/releaser.rb +++ b/lib/decidim/maintainers_toolbox/releaser.rb @@ -180,7 +180,7 @@ def old_version_number # @return [void] def check_tests puts "Running specs" - output, status = capture("bin/rspec") + output, status = capture("bin/rspec", { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }) unless status.success? run("git restore .") From bdd28ce94c442e2c99860ed667745aa5892c9259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Mon, 15 Jul 2024 12:09:41 +0200 Subject: [PATCH 03/24] Replace ByTitle with ByQuery --- .../github_manager/querier.rb | 2 +- .../querier/{by_title.rb => by_query.rb} | 16 ++++++---------- lib/decidim/maintainers_toolbox/releaser.rb | 4 ++-- .../{by_title_spec.rb => by_query_spec.rb} | 8 ++++---- 4 files changed, 13 insertions(+), 17 deletions(-) rename lib/decidim/maintainers_toolbox/github_manager/querier/{by_title.rb => by_query.rb} (73%) rename spec/lib/decidim/maintainers_toolbox/github_manager/querier/{by_title_spec.rb => by_query_spec.rb} (85%) diff --git a/lib/decidim/maintainers_toolbox/github_manager/querier.rb b/lib/decidim/maintainers_toolbox/github_manager/querier.rb index 54055c1..0ab5e50 100644 --- a/lib/decidim/maintainers_toolbox/github_manager/querier.rb +++ b/lib/decidim/maintainers_toolbox/github_manager/querier.rb @@ -15,7 +15,7 @@ module GithubManager module Querier autoload :ByIssueId, "decidim/maintainers_toolbox/github_manager/querier/by_issue_id" autoload :ByLabel, "decidim/maintainers_toolbox/github_manager/querier/by_label" - autoload :ByTitle, "decidim/maintainers_toolbox/github_manager/querier/by_title" + autoload :ByQuery, "decidim/maintainers_toolbox/github_manager/querier/by_query" autoload :RelatedIssues, "decidim/maintainers_toolbox/github_manager/querier/related_issues" end end diff --git a/lib/decidim/maintainers_toolbox/github_manager/querier/by_title.rb b/lib/decidim/maintainers_toolbox/github_manager/querier/by_query.rb similarity index 73% rename from lib/decidim/maintainers_toolbox/github_manager/querier/by_title.rb rename to lib/decidim/maintainers_toolbox/github_manager/querier/by_query.rb index d3c3a58..01b7b82 100644 --- a/lib/decidim/maintainers_toolbox/github_manager/querier/by_title.rb +++ b/lib/decidim/maintainers_toolbox/github_manager/querier/by_query.rb @@ -9,15 +9,13 @@ module Querier # Makes a GET request for the list of Issues or Pull Requests in GitHub. # # @param token [String] token for GitHub authentication - # @param title [String] the title that we want to search by - # @param state [String] the state of the issue. By default is "open" + # @pparam query [Hash] the query to search # # @see https://docs.github.com/en/rest/issues/issues#list-repository-issues GitHub API documentation - class ByTitle < Decidim::MaintainersToolbox::GithubManager::Querier::Base - def initialize(title:, token:, state: "open") - @title = title + class ByQuery < Decidim::MaintainersToolbox::GithubManager::Querier::Base + def initialize(token:, query: {}) @token = token - @state = state + @query = query end # Makes the GET request and parses the response of an Issue or Pull Request in GitHub @@ -31,14 +29,12 @@ def call private - attr_reader :title, :state + attr_reader :query def headers { - title: title, - state: state, per_page: 100 - } + }.merge(query) end # Parses the response of an Issue or Pull Request in GitHub diff --git a/lib/decidim/maintainers_toolbox/releaser.rb b/lib/decidim/maintainers_toolbox/releaser.rb index a909de2..5b10930 100644 --- a/lib/decidim/maintainers_toolbox/releaser.rb +++ b/lib/decidim/maintainers_toolbox/releaser.rb @@ -2,7 +2,7 @@ require "open3" require_relative "github_manager/poster" -require_relative "github_manager/querier/by_title" +require_relative "github_manager/querier/by_query" require_relative "changelog_generator" module Decidim @@ -248,7 +248,7 @@ def run(cmd, out: $stdout) # # @return [Boolean] - true if there is any open PR def pending_crowdin_pull_requests? - pull_requests = Decidim::MaintainersToolbox::GithubManager::Querier::ByTitle.new(token: @token, title: "New Crowdin updates").call + pull_requests = Decidim::MaintainersToolbox::GithubManager::Querier::ByQuery.new(token: @token, query: { title: "New Crowdin updates", creator: "decidim-bot" }).call pull_requests.any? end diff --git a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_title_spec.rb b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_query_spec.rb similarity index 85% rename from spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_title_spec.rb rename to spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_query_spec.rb index 64731c6..54c6da7 100644 --- a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_title_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_query_spec.rb @@ -3,12 +3,12 @@ require "decidim/maintainers_toolbox/github_manager/querier" require "webmock/rspec" -describe Decidim::MaintainersToolbox::GithubManager::Querier::ByTitle do - let(:querier) { described_class.new(token: "abc", title: title, state: state) } +describe Decidim::MaintainersToolbox::GithubManager::Querier::ByQuery do + let(:querier) { described_class.new(token: @token, query: { title: "Fix whatever" }) } + let(:title) { "Fix whatever" } - let(:state) { "open" } - let(:stubbed_url) { "https://api.github.com/repos/decidim/decidim/issues?per_page=100&state=open&title=Fix%20whatever" } + let(:stubbed_url) { "https://api.github.com/repos/decidim/decidim/issues?per_page=100&title=Fix%20whatever" } let(:stubbed_headers) { {} } before do From 3b011ef640827bdc9730ba888a1c16f3e3b82c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Mon, 15 Jul 2024 16:34:29 +0200 Subject: [PATCH 04/24] Extract ReleasePatchVersion to its own class and ReleaserUtils module --- .../release_patch_version.rb | 124 +++++++++ lib/decidim/maintainers_toolbox/releaser.rb | 240 ++---------------- .../maintainers_toolbox/releaser_utils.rb | 111 ++++++++ 3 files changed, 253 insertions(+), 222 deletions(-) create mode 100644 lib/decidim/maintainers_toolbox/release_patch_version.rb create mode 100644 lib/decidim/maintainers_toolbox/releaser_utils.rb diff --git a/lib/decidim/maintainers_toolbox/release_patch_version.rb b/lib/decidim/maintainers_toolbox/release_patch_version.rb new file mode 100644 index 0000000..debf9d3 --- /dev/null +++ b/lib/decidim/maintainers_toolbox/release_patch_version.rb @@ -0,0 +1,124 @@ +# frozen_string_literal: true + +require "open3" +require_relative "github_manager/poster" +require_relative "github_manager/querier/by_query" +require_relative "changelog_generator" +require_relative "releaser_utils" + +module Decidim + module MaintainersToolbox + class ReleasePatchVersion + include Decidim::MaintainersToolbox::ReleaserUtils + + # @param token [String] token for GitHub authentication + # @param working_dir [String] current working directory. Useful for testing purposes + def initialize(token:, working_dir: Dir.pwd) + @token = token + @working_dir = working_dir + end + + def call + run("git checkout #{release_branch}") + run("git pull origin #{release_branch}") + + bump_decidim_version + run("bin/rake update_versions") + + run("bin/rake patch_generators") + + run("bin/rake bundle") + run("npm install") + run("bin/rake webpack") if Dir.exist?("decidim_app-design") + + check_tests + + generate_changelog + + run("git checkout -b chore/prepare/#{version_number}") + run("git commit -a -m 'Prepare #{version_number} release'") + run("git push origin chore/prepare/#{version_number}") + + create_pull_request + end + + # The version number for the release that we are preparing + # + # @return [String] the version number + def version_number + next_version_number_for_patch_release(old_version_number) + end + + private + + # The git branch + # + # @return [String] + def branch + @branch ||= capture("git rev-parse --abbrev-ref HEAD")[0].strip + end + + # Raise an error if the branch does not start with the preffix "release/" + # or returns the branch name + # + # @raise [InvalidBranchError] + # + # @return [String] + def release_branch + raise InvalidBranchError, "This is not a release branch, aborting" unless branch.start_with?("release/") + + branch + end + + # Changes the decidim version in the file + # + # @return [void] + def bump_decidim_version + File.write(DECIDIM_VERSION_FILE, version_number) + end + + # Run the tests and if fails restore the changes using git and exit with an error + # + # @return [void] + def check_tests + puts "Running specs" + output, status = capture("bin/rspec", { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }) + + unless status.success? + run("git restore .") + puts output + exit_with_errors("Tests execution failed. Fix the errors and run again.") + end + end + + # Given a version number, returns the next patch release + # + # If the current version number is `dev`, then we raise an Exception, as you need to first do a release candidate. + # If the current version number is `rc`, then we return the `0` patch version + # Else, it means is a `patch` version, so we return the next patch version + # + # @raise [InvalidVersionTypeError] + # + # @param current_version_number [String] - The version number of the current version + # + # @return [String] - the new version number + def next_version_number_for_patch_release(current_version_number) + major, minor, patch = parsed_version_number(current_version_number) + + if current_version_number.include? "dev" + error_message = <<-EOMESSAGE + Trying to do a patch version from dev release. Bailing out. + You need to do first a release candidate. + EOMESSAGE + raise InvalidVersionTypeError, error_message + elsif current_version_number.include? "rc" + new_version_number = "#{major}.#{minor}.0" + else + new_version_number = "#{major}.#{minor}.#{patch.to_i + 1}" + end + + new_version_number + end + end + end +end diff --git a/lib/decidim/maintainers_toolbox/releaser.rb b/lib/decidim/maintainers_toolbox/releaser.rb index 5b10930..c8c1cf9 100644 --- a/lib/decidim/maintainers_toolbox/releaser.rb +++ b/lib/decidim/maintainers_toolbox/releaser.rb @@ -1,20 +1,17 @@ # frozen_string_literal: true -require "open3" -require_relative "github_manager/poster" require_relative "github_manager/querier/by_query" -require_relative "changelog_generator" + +require_relative "releaser_utils" +require_relative "release_candidate_version" +require_relative "release_patch_version" module Decidim module MaintainersToolbox class Releaser class InvalidMetadataError < StandardError; end - class InvalidBranchError < StandardError; end - - class InvalidVersionTypeError < StandardError; end - - DECIDIM_VERSION_FILE = ".decidim-version" + include Decidim::MaintainersToolbox::ReleaserUtils # @param token [String] token for GitHub authentication # @param version_type [String] The kind of release that you want to prepare. Supported values: rc, minor, patch @@ -32,223 +29,30 @@ def call exit_if_unstaged_changes if @exit_with_unstaged_changes exit_if_pending_crowdin_pull_request - puts "Starting the release process for #{version_number} in 10 seconds" - sleep 10 - - run("git checkout #{release_branch}") - run("git pull origin #{release_branch}") - - bump_decidim_version - run("bin/rake update_versions") + case @version_type + when "patch" + release = ReleasePatchVersion.new(token: @token, working_dir: @working_dir) + else + raise InvalidVersionTypeError, "This is not a valid version type" + end - run("bin/rake patch_generators") - - run("bin/rake bundle") - run("npm install") - run("bin/rake webpack") if Dir.exists?("decidim_app-design") - - check_tests - - generate_changelog - - run("git checkout -b chore/prepare/#{version_number}") - run("git commit -a -m 'Prepare #{version_number} release'") - run("git push origin chore/prepare/#{version_number}") + puts "Starting the release process for #{release.version_number} in 10 seconds" + sleep 10 - create_pull_request + release.call end end private - # The git branch - # - # @return [String] - def branch - @branch ||= capture("git rev-parse --abbrev-ref HEAD")[0].strip - end - - # Raise an error if the branch does not start with the preffix "release/" - # or returns the branch name - # - # @raise [InvalidBranchError] - # - # @return [String] - def release_branch - raise InvalidBranchError, "This is not a release branch, aborting" unless branch.start_with?("release/") - - branch - end - - # Changes the decidim version in the file - # - # @return [void] - def bump_decidim_version - File.write(DECIDIM_VERSION_FILE, version_number) - end - - # The version number for the release that we are preparing - # - # @todo support the "minor" type version - # - # @return [String] the version number - def version_number - @version_number ||= case @version_type - when "rc" - next_version_number_for_release_candidate(old_version_number) - when "patch" - next_version_number_for_patch_release(old_version_number) - else - raise InvalidVersionTypeError, "This is not a supported version type" - end - end - - def parsed_version_number(version_number) - /(?\d+)\.(?\d+)\.(?\d+)/ =~ version_number - - [major.to_i, minor.to_i, patch.to_i] - end - - # Given a version number, returns the next release candidate - # - # If the current version number is `dev`, then we return the `rc1` version - # If the current version number is `rc`, then we return the next `rc` version - # Else, it means is a `minor` or `patch` version. On those cases we raise an Exception, as releases candidates should - # be only done from a `dev` or a `rc` version. - # - # @raise [InvalidVersionTypeError] - # - # @param current_version_number [String] - The version number of the current version - # - # @return [String] - the new version number - def next_version_number_for_release_candidate(current_version_number) - if current_version_number.include? "dev" - major, minor, patch = parsed_version_number(current_version_number) - new_version_number = "#{major}.#{minor}.#{patch}.rc1" - elsif current_version_number.include? "rc" - new_rc_number = current_version_number.match(/rc(\d)/)[1].to_i + 1 - new_version_number = current_version_number.gsub(/rc\d/, "rc#{new_rc_number}") - else - error_message = <<-EOMESSAGE - Trying to do a release candidate version from patch release. Bailing out. - You need to do a release candidate from a `dev` or from another `rc` version - EOMESSAGE - raise InvalidVersionTypeError, error_message - end - - new_version_number - end - - # Given a version number, returns the next patch release - # - # If the current version number is `dev`, then we raise an Exception, as you need to first do a release candidate. - # If the current version number is `rc`, then we return the `0` patch version - # Else, it means is a `patch` version, so we return the next patch version - # - # @raise [InvalidVersionTypeError] - # - # @param current_version_number [String] - The version number of the current version - # - # @return [String] - the new version number - def next_version_number_for_patch_release(current_version_number) - major, minor, patch = parsed_version_number(current_version_number) - - if current_version_number.include? "dev" - error_message = <<-EOMESSAGE - Trying to do a patch version from dev release. Bailing out. - You need to do first a release candidate. - EOMESSAGE - raise InvalidVersionTypeError, error_message - elsif current_version_number.include? "rc" - new_version_number = "#{major}.#{minor}.0" - else - new_version_number = "#{major}.#{minor}.#{patch.to_i + 1}" - end - - new_version_number - end - - # The version number from the file - # - # @return [String] the version number - def old_version_number - File.read(DECIDIM_VERSION_FILE).strip - end - - # Run the tests and if fails restore the changes using git and exit with an error - # - # @return [void] - def check_tests - puts "Running specs" - output, status = capture("bin/rspec", { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }) - - unless status.success? - run("git restore .") - puts output - exit_with_errors("Tests execution failed. Fix the errors and run again.") - end - end - - # Generates the changelog taking into account the last time the version changed - # - # @return [void] - def generate_changelog - sha_version = capture("git log -n 1 --pretty=format:%h -- .decidim-version")[0] - ChangeLogGenerator.new(token: @token, since_sha: sha_version).call - temporary_changelog = File.read("./temporary_changelog.md") - legacy_changelog = File.read("./CHANGELOG.md") - version_changelog = "## [#{version_number}](https://github.com/decidim/decidim/tree/#{version_number})\n\n#{temporary_changelog}\n" - changelog = legacy_changelog.gsub("# Changelog\n\n", "# Changelog\n\n#{version_changelog}") - File.write("./CHANGELOG.md", changelog) - end - - # Creates the pull request for bumping the version - # - # @return [void] - def create_pull_request - base_branch = release_branch - head_branch = "chore/prepare/#{version_number}" - - params = { - title: "Bump to v#{version_number} version", - body: "#### :tophat: What? Why? - -This PR changes the version of the #{release_branch} branch, so we can publish the release once this is approved and merged. - -#### Testing - -All the tests should pass, except for some generators tests, that will fail because the gems and NPM packages have not -been actually published yet (as in sent to rubygems/npm). -You will see errors such as `No matching version found for @decidim/browserslist-config@~0.xx.y` in the CI logs. - -:hearts: Thank you! - ", - labels: ["type: internal"], - head: head_branch, - base: base_branch - } - Decidim::MaintainersToolbox::GithubManager::Poster.new(token: @token, params: params).call - end - - # Captures to output of a command - # - # @return [Array] The stdout and stderr of the command and its status (aka error code) - def capture(cmd, env: {}) - Open3.capture2e(env, cmd) - end - - # Runs a command - # - # @return [void] - def run(cmd, out: $stdout) - system(cmd, out: out) - end - # Check if there is any open pull request from Crowdin in GitHub # # @return [Boolean] - true if there is any open PR def pending_crowdin_pull_requests? - pull_requests = Decidim::MaintainersToolbox::GithubManager::Querier::ByQuery.new(token: @token, query: { title: "New Crowdin updates", creator: "decidim-bot" }).call + pull_requests = Decidim::MaintainersToolbox::GithubManager::Querier::ByQuery.new( + token: @token, + query: { title: "New Crowdin updates", creator: "decidim-bot" } + ).call pull_requests.any? end @@ -278,14 +82,6 @@ def exit_if_unstaged_changes EOERROR exit_with_errors(error_message) end - - # Exit the script execution with a message - # - # @return [void] - def exit_with_errors(message) - puts message - exit 1 - end end end end diff --git a/lib/decidim/maintainers_toolbox/releaser_utils.rb b/lib/decidim/maintainers_toolbox/releaser_utils.rb new file mode 100644 index 0000000..abefb64 --- /dev/null +++ b/lib/decidim/maintainers_toolbox/releaser_utils.rb @@ -0,0 +1,111 @@ +# frozen_string_literal: true + +require "open3" + +module Decidim + module MaintainersToolbox + module ReleaserUtils + class InvalidVersionTypeError < StandardError; end + + DECIDIM_VERSION_FILE = ".decidim-version".freeze + + # Exit the script execution with a message + # + # @return [void] + def exit_with_errors(message) + puts message + exit 1 + end + + # Captures to output of a command + # + # @return [Array] The stdout and stderr of the command and its status (aka error code) + def capture(cmd, env: {}) + Open3.capture2e(env, cmd) + end + + # Runs a command + # + # @return [void] + def run(cmd, out: $stdout) + system(cmd, out: out) + end + + # The git branch + # + # @return [String] + def branch + @branch ||= capture("git rev-parse --abbrev-ref HEAD")[0].strip + end + + # The version number from the file + # + # @return [String] the version number + def old_version_number + File.read(DECIDIM_VERSION_FILE).strip + end + + def parsed_version_number(version_number) + /(?\d+)\.(?\d+)\.(?\d+)/ =~ version_number + + [major.to_i, minor.to_i, patch.to_i] + end + + # Run the tests and if fails restore the changes using git and exit with an error + # + # @return [void] + def check_tests + puts "Running specs" + output, status = capture("bin/rspec", { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }) + + unless status.success? + run("git restore .") + puts output + exit_with_errors("Tests execution failed. Fix the errors and run again.") + end + end + + # Generates the changelog taking into account the last time the version changed + # + # @return [void] + def generate_changelog + sha_version = capture("git log -n 1 --pretty=format:%h -- .decidim-version")[0] + ChangeLogGenerator.new(token: @token, since_sha: sha_version).call + temporary_changelog = File.read("./temporary_changelog.md") + legacy_changelog = File.read("./CHANGELOG.md") + version_changelog = "## [#{version_number}](https://github.com/decidim/decidim/tree/#{version_number})\n\n#{temporary_changelog}\n" + changelog = legacy_changelog.gsub("# Changelog\n\n", "# Changelog\n\n#{version_changelog}") + File.write("./CHANGELOG.md", changelog) + end + + # Creates the pull request for bumping the version + # + # @return [void] + def create_pull_request + base_branch = release_branch + head_branch = "chore/prepare/#{version_number}" + + params = { + title: "Bump to v#{version_number} version", + body: "#### :tophat: What? Why? + + This PR prepares version of the #{release_branch} branch, so we can publish the release once this is approved and merged. + + #### Testing + + All the tests should pass, except for some generators tests, that will fail because the gems and NPM packages have not + been actually published yet (as in sent to rubygems/npm). + You will see errors such as `No matching version found for @decidim/browserslist-config@~0.xx.y` in the CI logs. + + :hearts: Thank you! + ", + labels: ["type: internal"], + head: head_branch, + base: base_branch + } + Decidim::MaintainersToolbox::GithubManager::Poster.new(token: @token, params: params).call + end + end + end +end + From 79562a1eb1a0728a95d25369ea611e5b679b0902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Mon, 15 Jul 2024 16:34:49 +0200 Subject: [PATCH 05/24] Add ReleaseCandidateVersion class --- .../release_candidate_version.rb | 306 ++++++++++++++++++ lib/decidim/maintainers_toolbox/releaser.rb | 2 + 2 files changed, 308 insertions(+) create mode 100644 lib/decidim/maintainers_toolbox/release_candidate_version.rb diff --git a/lib/decidim/maintainers_toolbox/release_candidate_version.rb b/lib/decidim/maintainers_toolbox/release_candidate_version.rb new file mode 100644 index 0000000..3107e31 --- /dev/null +++ b/lib/decidim/maintainers_toolbox/release_candidate_version.rb @@ -0,0 +1,306 @@ +# frozen_string_literal: true + +require_relative "changelog_generator" +require_relative "releaser_utils" + +module Decidim + module MaintainersToolbox + class ReleaseCandidateVersion + include Decidim::MaintainersToolbox::ReleaserUtils + + # @param token [String] token for GitHub authentication + # @param working_dir [String] current working directory. Useful for testing purposes + def initialize(token:, working_dir: Dir.pwd) + @token = token + @working_dir = working_dir + @old_version_number = old_version_number + end + + def call + exit_unless_develop + + prepare_next_development_version + prepare_next_release_candidate_version + end + + # The version number for the release that we are preparing + # + # @return [String] the version number + def version_number + @version_number ||= next_version_number_for_release_candidate(@old_version_number) + end + + private + + # Returns the next branch that needs to be created for the RC. + # + # @return [String] + def release_branch + @release_branch ||= begin + major, minor, _patch = parsed_version_number(version_number) + + "release/#{major}.#{minor}-stable" + end + end + + def exit_unless_develop + return if branch == "develop" + + error_message = <<-EOERROR + This is not the develop branch, change to the develop branch to run this script. + EOERROR + exit_with_errors(error_message) + end + + def prepare_next_development_version + run("git pull origin develop") + + run("git checkout -b #{release_branch}") + run("git push origin #{release_branch}") + + puts "*" * 80 + puts "Create the stable branch in Crowdin and exit this shell to continue the release process" + puts "https://docs.decidim.org/en/develop/develop/maintainers/releases.html#_create_the_stable_branch_in_crowdin" + puts "*" * 80 + system ENV.fetch("SHELL") + + run("git checkout develop") + + next_dev_version = next_version_number_for_dev(@old_version_number) + prepare_branch = "chore/prepare/#{next_dev_version}" + run("git checkout -b #{prepare_branch}") + + bump_decidim_version_dev + + run("bin/rake update_versions") + run("bin/rake patch_generators") + run("bin/rake bundle") + run("npm install") + run("bin/rake webpack") if Dir.exist?("decidim_app-design") + + generate_empty_changelog + generate_empty_release_notes + + run("git add .") + run("git commit -m 'Bump develop to next release version'") + run("git push origin #{prepare_branch}") + + create_develop_pull_request(prepare_branch, next_dev_version) + end + + def prepare_next_release_candidate_version + run("git checkout #{release_branch}") + run("git checkout -b chore/prepare/#{version_number}") + + bump_decidim_version + + run("bin/rake update_versions") + run("bin/rake patch_generators") + run("bin/rake bundle") + + run("npm install") + run("bin/rake webpack") if Dir.exist?("decidim_app-design") + + check_tests + + generate_changelog + + run("git add .") + run("git commit -m 'Bump to #{version_number} version'") + run("git push origin chore/prepare/#{version_number}") + + create_pull_request + + finish_message = <<~EOMESSAGE + Finished the release process + Next steps: + + 1. Wait for the tests to finish and check that everything is passing before releasing the version. + NOTE: When you bump the version, the generator tests will fail because the gems and NPM packages + have not been actually published yet (as in sent to rubygems/npm). You may see errors such as + No matching version found for @decidim/browserslist-config@~0.xx.y in the CI logs. This should + be fine as long as you have ensured that the generators tests passed in the previous commit. + 2. Review and merge this PR + 3. Once that PR is merged, run the following commands to create the tags and push the gems to RubyGems and the packages to NPM: + > git pull + > bin/rake release_all + 4. Usually, at this point, the release branch is deployed to Metadecidim during, at least, one week to validate the stability of the version. + EOMESSAGE + + puts finish_message + end + + # Given a version number, returns the next release candidate + # + # If the current version number is `dev`, then we return the `rc1` version + # If the current version number is `rc`, then we return the next `rc` version + # Else, it means is a `minor` or `patch` version. On those cases we raise an Exception, as releases candidates should + # be only done from a `dev` or a `rc` version. + # + # @raise [InvalidVersionTypeError] + # + # @param current_version_number [String] - The version number of the current version + # + # @return [String] - the new version number + def next_version_number_for_release_candidate(current_version_number) + if current_version_number.include? "dev" + major, minor, patch = parsed_version_number(current_version_number) + new_version_number = "#{major}.#{minor}.#{patch}.rc1" + elsif current_version_number.include? "rc" + new_rc_number = current_version_number.match(/rc(\d)/)[1].to_i + 1 + new_version_number = current_version_number.gsub(/rc\d/, "rc#{new_rc_number}") + else + error_message = <<-EOMESSAGE + Trying to do a release candidate version from patch release. Bailing out. + You need to do a release candidate from a `dev` or from another `rc` version + EOMESSAGE + raise InvalidVersionTypeError, error_message + end + + new_version_number + end + + def next_version_number_for_dev(current_version_number) + major, minor, patch = parsed_version_number(current_version_number) + + "#{major}.#{minor.to_i + 1}.#{patch}.dev" + end + + # Changes the decidim version in the file + # + # @return [void] + def bump_decidim_version_dev + File.write(DECIDIM_VERSION_FILE, next_version_number_for_dev(@old_version_number)) + end + + def generate_empty_changelog + major, minor, patch = parsed_version_number(@old_version_number) + + changelog_contents = <<-EOCHANGELOG +# Changelog + +## [Unreleased](https://github.com/decidim/decidim/tree/HEAD) + +Nothing. + +... + +## Previous versions + +Please check [#{major}.#{minor}-stable](https://github.com/decidim/decidim/blob/release/#{major}.#{minor}-stable/CHANGELOG.md) for previous changes. +EOCHANGELOG + + File.write("CHANGELOG.md", changelog_contents) + end + + def generate_empty_release_notes + release_notes_contents = <<-EORELEASE +# Release Notes + +## 1. Upgrade notes + +As usual, we recommend that you have a full backup, of the database, application code and static files. + +To update, follow these steps: + +### 1.1. Update your Gemfile + +```ruby +gem "decidim", github: "decidim/decidim" +gem "decidim-dev", github: "decidim/decidim" +``` + +### 1.2. Run these commands + +```console +bundle update decidim +bin/rails decidim:upgrade +bin/rails db:migrate +``` + +### 1.3. Follow the steps and commands detailed in these notes + +## 2. General notes + +## 3. One time actions + +These are one time actions that need to be done after the code is updated in the production database. + +### 3.1. [[TITLE OF THE ACTION]] + +You can read more about this change on PR [#XXXX](https://github.com/decidim/decidim/pull/XXXX). +## 4. Scheduled tasks + + +Implementers need to configure these changes it in your scheduler task system in the production server. We give the examples +with `crontab`, although alternatively you could use `whenever` gem or the scheduled jobs of your hosting provider. + +### 4.1. [[TITLE OF THE TASK]] + +```bash +4 0 * * * cd /home/user/decidim_application && RAILS_ENV=production bundle exec rails decidim:TASK +``` + +You can read more about this change on PR [#XXXX](https://github.com/decidim/decidim/pull/XXXX). + +## 5. Changes in APIs + +### 5.1. [[TITLE OF THE CHANGE]] + +In order to [[REASONING (e.g. improve the maintenance of the code base)]] we have changed... + +If you have used code as such: + +```ruby +# Explain the usage of the API as it was in the previous version +result = 1 + 1 if before +``` + +You need to change it to: + +```ruby +# Explain the usage of the API as it is in the new version +result = 1 + 1 if after + ``` +EORELEASE + + File.write("RELEASE_NOTES.md", release_notes_contents) + end + + # Changes the decidim version in the file + # + # @return [void] + def bump_decidim_version + File.write(DECIDIM_VERSION_FILE, version_number) + end + + # Creates the pull request for bumping the develop version + # + # @param head_branch [String] the branch that we want to merge to develop + # @param next_dev_version [String] the name of the next dev version (for instance 0.99.0.dev) + # + # @return [void] + def create_develop_pull_request(head_branch, next_dev_version) + base_branch = "develop" + + params = { + title: "Bump develop to next release version (#{next_dev_version})", + body: "#### :tophat: What? Why? + +This PR prepares the next develop version. + +#### Testing + +All the tests should pass + +:hearts: Thank you! + ", + labels: ["type: internal"], + head: head_branch, + base: base_branch + } + Decidim::MaintainersToolbox::GithubManager::Poster.new(token: @token, params: params).call + end + end + end +end diff --git a/lib/decidim/maintainers_toolbox/releaser.rb b/lib/decidim/maintainers_toolbox/releaser.rb index c8c1cf9..b94ba3c 100644 --- a/lib/decidim/maintainers_toolbox/releaser.rb +++ b/lib/decidim/maintainers_toolbox/releaser.rb @@ -30,6 +30,8 @@ def call exit_if_pending_crowdin_pull_request case @version_type + when "rc" + release = ReleaseCandidateVersion.new(token: @token, working_dir: @working_dir) when "patch" release = ReleasePatchVersion.new(token: @token, working_dir: @working_dir) else From 19c59a19b95a02ba28473460396f7648718faf66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Mon, 15 Jul 2024 18:10:24 +0200 Subject: [PATCH 06/24] Refactor ReleasePatchVersion so it's consistent with ReleaseCandidateVersion --- .../release_patch_version.rb | 76 +++++++++---------- .../maintainers_toolbox/releaser_utils.rb | 14 ++-- 2 files changed, 41 insertions(+), 49 deletions(-) diff --git a/lib/decidim/maintainers_toolbox/release_patch_version.rb b/lib/decidim/maintainers_toolbox/release_patch_version.rb index debf9d3..10ba9b0 100644 --- a/lib/decidim/maintainers_toolbox/release_patch_version.rb +++ b/lib/decidim/maintainers_toolbox/release_patch_version.rb @@ -19,6 +19,40 @@ def initialize(token:, working_dir: Dir.pwd) end def call + exit_unless_release_branch + + prepare_next_patch_version + end + + # The version number for the release that we are preparing + # + # @return [String] the version number + def version_number + @version_number ||= next_version_number_for_patch_release(old_version_number) + end + + private + + # Raise an error if the branch does not start with the preffix "release/" + # or returns the branch name + # + # @raise [InvalidBranchError] + # + # @return [String] + def release_branch + @release_branch ||= branch + end + + def exit_unless_release_branch + return if branch.start_with?("release/") + + error_message = <<-EOERROR + This is not a release branch, change to the release branch branch to run this script. + EOERROR + exit_with_errors(error_message) + end + + def prepare_next_patch_version run("git checkout #{release_branch}") run("git pull origin #{release_branch}") @@ -42,34 +76,6 @@ def call create_pull_request end - # The version number for the release that we are preparing - # - # @return [String] the version number - def version_number - next_version_number_for_patch_release(old_version_number) - end - - private - - # The git branch - # - # @return [String] - def branch - @branch ||= capture("git rev-parse --abbrev-ref HEAD")[0].strip - end - - # Raise an error if the branch does not start with the preffix "release/" - # or returns the branch name - # - # @raise [InvalidBranchError] - # - # @return [String] - def release_branch - raise InvalidBranchError, "This is not a release branch, aborting" unless branch.start_with?("release/") - - branch - end - # Changes the decidim version in the file # # @return [void] @@ -77,20 +83,6 @@ def bump_decidim_version File.write(DECIDIM_VERSION_FILE, version_number) end - # Run the tests and if fails restore the changes using git and exit with an error - # - # @return [void] - def check_tests - puts "Running specs" - output, status = capture("bin/rspec", { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }) - - unless status.success? - run("git restore .") - puts output - exit_with_errors("Tests execution failed. Fix the errors and run again.") - end - end - # Given a version number, returns the next patch release # # If the current version number is `dev`, then we raise an Exception, as you need to first do a release candidate. diff --git a/lib/decidim/maintainers_toolbox/releaser_utils.rb b/lib/decidim/maintainers_toolbox/releaser_utils.rb index abefb64..ee0a4cf 100644 --- a/lib/decidim/maintainers_toolbox/releaser_utils.rb +++ b/lib/decidim/maintainers_toolbox/releaser_utils.rb @@ -56,7 +56,7 @@ def parsed_version_number(version_number) # @return [void] def check_tests puts "Running specs" - output, status = capture("bin/rspec", { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }) + output, status = capture("bin/rspec", env: { "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }) unless status.success? run("git restore .") @@ -89,15 +89,15 @@ def create_pull_request title: "Bump to v#{version_number} version", body: "#### :tophat: What? Why? - This PR prepares version of the #{release_branch} branch, so we can publish the release once this is approved and merged. +This PR prepares version of the #{release_branch} branch, so we can publish the release once this is approved and merged. - #### Testing +#### Testing - All the tests should pass, except for some generators tests, that will fail because the gems and NPM packages have not - been actually published yet (as in sent to rubygems/npm). - You will see errors such as `No matching version found for @decidim/browserslist-config@~0.xx.y` in the CI logs. +All the tests should pass, except for some generators tests, that will fail because the gems and NPM packages have not +been actually published yet (as in sent to rubygems/npm). +You will see errors such as `No matching version found for @decidim/browserslist-config@~0.xx.y` in the CI logs. - :hearts: Thank you! +:hearts: Thank you! ", labels: ["type: internal"], head: head_branch, From 9b6989fcc26f60eb7b7c7682da3c07ca3addbf8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 08:08:44 +0200 Subject: [PATCH 07/24] Add throttling for GitHub REST API --- lib/decidim/maintainers_toolbox/changelog_generator.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/decidim/maintainers_toolbox/changelog_generator.rb b/lib/decidim/maintainers_toolbox/changelog_generator.rb index b8a42b8..2caf023 100644 --- a/lib/decidim/maintainers_toolbox/changelog_generator.rb +++ b/lib/decidim/maintainers_toolbox/changelog_generator.rb @@ -61,6 +61,9 @@ def call if type_prs.any? type_prs.each do |_pr_title, data| + # Prevent throttling by GitHub REST API + sleep 1 + process_single_pr(data, type_data) end else From 135e7e3106260a89752258a5fd0ac299b725fc36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 08:09:59 +0200 Subject: [PATCH 08/24] Fix requires --- lib/decidim/maintainers_toolbox/release_candidate_version.rb | 1 + lib/decidim/maintainers_toolbox/release_patch_version.rb | 4 ---- lib/decidim/maintainers_toolbox/releaser_utils.rb | 2 ++ 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/decidim/maintainers_toolbox/release_candidate_version.rb b/lib/decidim/maintainers_toolbox/release_candidate_version.rb index 3107e31..ab6bdd2 100644 --- a/lib/decidim/maintainers_toolbox/release_candidate_version.rb +++ b/lib/decidim/maintainers_toolbox/release_candidate_version.rb @@ -2,6 +2,7 @@ require_relative "changelog_generator" require_relative "releaser_utils" +require_relative "github_manager/poster" module Decidim module MaintainersToolbox diff --git a/lib/decidim/maintainers_toolbox/release_patch_version.rb b/lib/decidim/maintainers_toolbox/release_patch_version.rb index 10ba9b0..b0ff3dd 100644 --- a/lib/decidim/maintainers_toolbox/release_patch_version.rb +++ b/lib/decidim/maintainers_toolbox/release_patch_version.rb @@ -1,9 +1,5 @@ # frozen_string_literal: true -require "open3" -require_relative "github_manager/poster" -require_relative "github_manager/querier/by_query" -require_relative "changelog_generator" require_relative "releaser_utils" module Decidim diff --git a/lib/decidim/maintainers_toolbox/releaser_utils.rb b/lib/decidim/maintainers_toolbox/releaser_utils.rb index ee0a4cf..6450c79 100644 --- a/lib/decidim/maintainers_toolbox/releaser_utils.rb +++ b/lib/decidim/maintainers_toolbox/releaser_utils.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true require "open3" +require_relative "changelog_generator" +require_relative "github_manager/poster" module Decidim module MaintainersToolbox From 76010d9486ca9d31334ff77ffad96c95142e0ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 08:10:10 +0200 Subject: [PATCH 09/24] Fix markdownlint offense --- lib/decidim/maintainers_toolbox/release_candidate_version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decidim/maintainers_toolbox/release_candidate_version.rb b/lib/decidim/maintainers_toolbox/release_candidate_version.rb index ab6bdd2..95f7fcd 100644 --- a/lib/decidim/maintainers_toolbox/release_candidate_version.rb +++ b/lib/decidim/maintainers_toolbox/release_candidate_version.rb @@ -230,8 +230,8 @@ def generate_empty_release_notes ### 3.1. [[TITLE OF THE ACTION]] You can read more about this change on PR [#XXXX](https://github.com/decidim/decidim/pull/XXXX). -## 4. Scheduled tasks +## 4. Scheduled tasks Implementers need to configure these changes it in your scheduler task system in the production server. We give the examples with `crontab`, although alternatively you could use `whenever` gem or the scheduled jobs of your hosting provider. From 40c5e29156e3d4bc06ce5ecd8afbedf93a80318c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 08:10:24 +0200 Subject: [PATCH 10/24] Raise exception if system command failed --- lib/decidim/maintainers_toolbox/releaser_utils.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/decidim/maintainers_toolbox/releaser_utils.rb b/lib/decidim/maintainers_toolbox/releaser_utils.rb index 6450c79..0e8c21a 100644 --- a/lib/decidim/maintainers_toolbox/releaser_utils.rb +++ b/lib/decidim/maintainers_toolbox/releaser_utils.rb @@ -30,7 +30,7 @@ def capture(cmd, env: {}) # # @return [void] def run(cmd, out: $stdout) - system(cmd, out: out) + system(cmd, out: out, exception: true) end # The git branch From ef9807f1e7a239480d980150c1ec7ac6aa1c7ac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 09:54:33 +0200 Subject: [PATCH 11/24] Init the spec_helper for rspec's configuration --- .rspec | 1 + spec/spec_helper.rb | 98 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 .rspec create mode 100644 spec/spec_helper.rb diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..c99d2e7 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..c80d44b --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,98 @@ +# This file was generated by the `rspec --init` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ + config.disable_monkey_patching! + + # This setting enables warnings. It's recommended, but in some cases may + # be too noisy due to issues in dependencies. + config.warnings = true + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end From 21a749774687fcbf311477137111855a61df9fc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 09:55:17 +0200 Subject: [PATCH 12/24] Enable default recommeneded settings for rspec --- spec/spec_helper.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c80d44b..67493fa 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -44,9 +44,8 @@ # triggering implicit auto-inclusion in groups with matching metadata. config.shared_context_metadata_behavior = :apply_to_host_groups -# The settings below are suggested to provide a good initial experience -# with RSpec, but feel free to customize to your heart's content. -=begin + # The settings below are suggested to provide a good initial experience + # with RSpec, but feel free to customize to your heart's content. # This allows you to limit a spec run to individual examples or groups # you care about by tagging them with `:focus` metadata. When nothing # is tagged with `:focus`, all examples get run. RSpec also provides @@ -94,5 +93,4 @@ # test failures related to randomization by passing the same `--seed` value # as the one that triggered the failure. Kernel.srand config.seed -=end end From b6e8c6eede08efb0d943ce2e6f71253a4fa557bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 09:57:48 +0200 Subject: [PATCH 13/24] Use explicit RSpec call in specs --- spec/lib/decidim/maintainers_toolbox/backporter_spec.rb | 2 +- .../maintainers_toolbox/backports_reporter/cli_report_spec.rb | 2 +- .../maintainers_toolbox/backports_reporter/csv_report_spec.rb | 2 +- .../decidim/maintainers_toolbox/git_backport_manager_spec.rb | 2 +- .../decidim/maintainers_toolbox/github_manager/poster_spec.rb | 2 +- .../github_manager/querier/by_issue_id_spec.rb | 2 +- .../maintainers_toolbox/github_manager/querier/by_label_spec.rb | 2 +- .../maintainers_toolbox/github_manager/querier/by_query_spec.rb | 2 +- .../github_manager/querier/related_issues_spec.rb | 2 +- spec/lib/decidim/maintainers_toolbox/releaser_spec.rb | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/spec/lib/decidim/maintainers_toolbox/backporter_spec.rb b/spec/lib/decidim/maintainers_toolbox/backporter_spec.rb index f747640..de4ea7d 100644 --- a/spec/lib/decidim/maintainers_toolbox/backporter_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/backporter_spec.rb @@ -2,7 +2,7 @@ require "decidim/maintainers_toolbox/backporter" -describe Decidim::MaintainersToolbox::Backporter do +RSpec.describe Decidim::MaintainersToolbox::Backporter do subject { described_class.new(token: token, pull_request_id: pull_request_id, version_number: version_number, exit_with_unstaged_changes: exit_with_unstaged_changes) } let(:token) { "1234" } diff --git a/spec/lib/decidim/maintainers_toolbox/backports_reporter/cli_report_spec.rb b/spec/lib/decidim/maintainers_toolbox/backports_reporter/cli_report_spec.rb index 2b737f0..d55d4d9 100644 --- a/spec/lib/decidim/maintainers_toolbox/backports_reporter/cli_report_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/backports_reporter/cli_report_spec.rb @@ -2,7 +2,7 @@ require "decidim/maintainers_toolbox/backports_reporter/cli_report" -describe Decidim::MaintainersToolbox::BackportsReporter::CLIReport do +RSpec.describe Decidim::MaintainersToolbox::BackportsReporter::CLIReport do subject { described_class.new(report: report, last_version_number: last_version_number).call } let(:report) do diff --git a/spec/lib/decidim/maintainers_toolbox/backports_reporter/csv_report_spec.rb b/spec/lib/decidim/maintainers_toolbox/backports_reporter/csv_report_spec.rb index 8e139e8..4b581ae 100644 --- a/spec/lib/decidim/maintainers_toolbox/backports_reporter/csv_report_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/backports_reporter/csv_report_spec.rb @@ -2,7 +2,7 @@ require "decidim/maintainers_toolbox/backports_reporter/csv_report" -describe Decidim::MaintainersToolbox::BackportsReporter::CSVReport do +RSpec.describe Decidim::MaintainersToolbox::BackportsReporter::CSVReport do subject { described_class.new(report: report, last_version_number: last_version_number).call } let(:report) do diff --git a/spec/lib/decidim/maintainers_toolbox/git_backport_manager_spec.rb b/spec/lib/decidim/maintainers_toolbox/git_backport_manager_spec.rb index b4c17e3..9094459 100644 --- a/spec/lib/decidim/maintainers_toolbox/git_backport_manager_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/git_backport_manager_spec.rb @@ -4,7 +4,7 @@ require "decidim/maintainers_toolbox/git_backport_manager" -describe Decidim::MaintainersToolbox::GitBackportManager do +RSpec.describe Decidim::MaintainersToolbox::GitBackportManager do subject { described_class.new(pull_request_id: pull_request_id, release_branch: release_branch, backport_branch: backport_branch, working_dir: tmp_repository_dir) } let(:release_branch) { "release/0.99-stable" } diff --git a/spec/lib/decidim/maintainers_toolbox/github_manager/poster_spec.rb b/spec/lib/decidim/maintainers_toolbox/github_manager/poster_spec.rb index 7ccddfb..2bee948 100644 --- a/spec/lib/decidim/maintainers_toolbox/github_manager/poster_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/github_manager/poster_spec.rb @@ -3,7 +3,7 @@ require "decidim/maintainers_toolbox/github_manager/poster" require "webmock/rspec" -describe Decidim::MaintainersToolbox::GithubManager::Poster do +RSpec.describe Decidim::MaintainersToolbox::GithubManager::Poster do let(:poster) { described_class.new(token: "abc", params: { title: "Hello world", body: "This is a test" }) } before do diff --git a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id_spec.rb b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id_spec.rb index cc39dfd..f191dea 100644 --- a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_issue_id_spec.rb @@ -3,7 +3,7 @@ require "decidim/maintainers_toolbox/github_manager/querier" require "webmock/rspec" -describe Decidim::MaintainersToolbox::GithubManager::Querier::ByIssueId do +RSpec.describe Decidim::MaintainersToolbox::GithubManager::Querier::ByIssueId do let(:querier) { described_class.new(token: "abc", issue_id: 12_345) } before do diff --git a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_label_spec.rb b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_label_spec.rb index 333cdc6..1fa779a 100644 --- a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_label_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_label_spec.rb @@ -4,7 +4,7 @@ require "webmock/rspec" require "active_support/testing/time_helpers" -describe Decidim::MaintainersToolbox::GithubManager::Querier::ByLabel do +RSpec.describe Decidim::MaintainersToolbox::GithubManager::Querier::ByLabel do include ActiveSupport::Testing::TimeHelpers let(:querier) { described_class.new(token: "abc", days_to_check_from: days_to_check_from) } diff --git a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_query_spec.rb b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_query_spec.rb index 54c6da7..d858b6f 100644 --- a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_query_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/by_query_spec.rb @@ -3,7 +3,7 @@ require "decidim/maintainers_toolbox/github_manager/querier" require "webmock/rspec" -describe Decidim::MaintainersToolbox::GithubManager::Querier::ByQuery do +RSpec.describe Decidim::MaintainersToolbox::GithubManager::Querier::ByQuery do let(:querier) { described_class.new(token: @token, query: { title: "Fix whatever" }) } let(:title) { "Fix whatever" } diff --git a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/related_issues_spec.rb b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/related_issues_spec.rb index d5e94ba..81de9cd 100644 --- a/spec/lib/decidim/maintainers_toolbox/github_manager/querier/related_issues_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/github_manager/querier/related_issues_spec.rb @@ -3,7 +3,7 @@ require "decidim/maintainers_toolbox/github_manager/querier" require "webmock/rspec" -describe Decidim::MaintainersToolbox::GithubManager::Querier::RelatedIssues do +RSpec.describe Decidim::MaintainersToolbox::GithubManager::Querier::RelatedIssues do let(:querier) { described_class.new(token: "abc", issue_id: 12_345) } let(:response) do [ diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index 7420f0c..a72dfb8 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -2,7 +2,7 @@ require "decidim/maintainers_toolbox/releaser" -describe Decidim::MaintainersToolbox::Releaser do +RSpec.describe Decidim::MaintainersToolbox::Releaser do subject { described_class.new(token: token, version_type: version_type, exit_with_unstaged_changes: exit_with_unstaged_changes, working_dir: tmp_repository_dir) } let(:token) { "1234" } From 10c512bd2296f07138bcee4b121885469cfde7ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 13:29:05 +0200 Subject: [PATCH 14/24] Add .rspec-failures as example status persistence file for rspec --- .gitignore | 1 + spec/spec_helper.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9106b2a..5d76322 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /pkg/ /spec/reports/ /tmp/ +.rspec-failures diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 67493fa..012a059 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -56,7 +56,7 @@ # Allows RSpec to persist some state between runs in order to support # the `--only-failures` and `--next-failure` CLI options. We recommend # you configure your source control system to ignore this file. - config.example_status_persistence_file_path = "spec/examples.txt" + config.example_status_persistence_file_path = ".rspec-failures" # Limits the available syntax to the non-monkey patched syntax that is # recommended. For more details, see: From 079dfec96c1f96b8f705aba3d885c301a5a20c96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 13:44:10 +0200 Subject: [PATCH 15/24] Refactor bump_decidim_version method and extract it to ReleaserUtils --- .../release_candidate_version.rb | 18 +------ .../release_patch_version.rb | 9 +--- .../maintainers_toolbox/releaser_utils.rb | 7 +++ .../maintainers_toolbox/releaser_spec.rb | 29 ---------- .../releaser_utils_spec.rb | 54 +++++++++++++++++++ 5 files changed, 64 insertions(+), 53 deletions(-) create mode 100644 spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb diff --git a/lib/decidim/maintainers_toolbox/release_candidate_version.rb b/lib/decidim/maintainers_toolbox/release_candidate_version.rb index 95f7fcd..9d7cf59 100644 --- a/lib/decidim/maintainers_toolbox/release_candidate_version.rb +++ b/lib/decidim/maintainers_toolbox/release_candidate_version.rb @@ -71,7 +71,7 @@ def prepare_next_development_version prepare_branch = "chore/prepare/#{next_dev_version}" run("git checkout -b #{prepare_branch}") - bump_decidim_version_dev + bump_decidim_version(next_version_number_for_dev(@old_version_number)) run("bin/rake update_versions") run("bin/rake patch_generators") @@ -93,7 +93,7 @@ def prepare_next_release_candidate_version run("git checkout #{release_branch}") run("git checkout -b chore/prepare/#{version_number}") - bump_decidim_version + bump_decidim_version(version_number) run("bin/rake update_versions") run("bin/rake patch_generators") @@ -167,13 +167,6 @@ def next_version_number_for_dev(current_version_number) "#{major}.#{minor.to_i + 1}.#{patch}.dev" end - # Changes the decidim version in the file - # - # @return [void] - def bump_decidim_version_dev - File.write(DECIDIM_VERSION_FILE, next_version_number_for_dev(@old_version_number)) - end - def generate_empty_changelog major, minor, patch = parsed_version_number(@old_version_number) @@ -268,13 +261,6 @@ def generate_empty_release_notes File.write("RELEASE_NOTES.md", release_notes_contents) end - # Changes the decidim version in the file - # - # @return [void] - def bump_decidim_version - File.write(DECIDIM_VERSION_FILE, version_number) - end - # Creates the pull request for bumping the develop version # # @param head_branch [String] the branch that we want to merge to develop diff --git a/lib/decidim/maintainers_toolbox/release_patch_version.rb b/lib/decidim/maintainers_toolbox/release_patch_version.rb index b0ff3dd..755d8a3 100644 --- a/lib/decidim/maintainers_toolbox/release_patch_version.rb +++ b/lib/decidim/maintainers_toolbox/release_patch_version.rb @@ -52,7 +52,7 @@ def prepare_next_patch_version run("git checkout #{release_branch}") run("git pull origin #{release_branch}") - bump_decidim_version + bump_decidim_version(version_number) run("bin/rake update_versions") run("bin/rake patch_generators") @@ -72,13 +72,6 @@ def prepare_next_patch_version create_pull_request end - # Changes the decidim version in the file - # - # @return [void] - def bump_decidim_version - File.write(DECIDIM_VERSION_FILE, version_number) - end - # Given a version number, returns the next patch release # # If the current version number is `dev`, then we raise an Exception, as you need to first do a release candidate. diff --git a/lib/decidim/maintainers_toolbox/releaser_utils.rb b/lib/decidim/maintainers_toolbox/releaser_utils.rb index 0e8c21a..d74d69e 100644 --- a/lib/decidim/maintainers_toolbox/releaser_utils.rb +++ b/lib/decidim/maintainers_toolbox/releaser_utils.rb @@ -107,6 +107,13 @@ def create_pull_request } Decidim::MaintainersToolbox::GithubManager::Poster.new(token: @token, params: params).call end + + # Changes the decidim version in the file + # + # @return [void] + def bump_decidim_version(new_version_number) + File.write(DECIDIM_VERSION_FILE, new_version_number) + end end end end diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index a72dfb8..5587136 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -54,35 +54,6 @@ end end - describe "#bump_decidim_version" do - context "when it is a release candidate" do - let(:decidim_version) { "0.99.0.rc1" } - let(:version_type) { "rc" } - - it "changes the version number in the decidim version file" do - version_number = File.read(".decidim-version").strip - expect(version_number).to eq("0.99.0.rc1") - - subject.send(:bump_decidim_version) - new_version_number = File.read(".decidim-version").strip - - expect(new_version_number).to eq("0.99.0.rc2") - end - end - - context "when it is a patch release" do - let(:decidim_version) { "0.99.0" } - let(:version_type) { "patch" } - - it "changes the version number in the decidim version file" do - subject.send(:bump_decidim_version) - new_version_number = File.read(".decidim-version").strip - - expect(new_version_number).to eq("0.99.1") - end - end - end - describe "#parsed_version_number" do context "when it is a dev version" do let(:version_number) { "1.2.3.dev" } diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb new file mode 100644 index 0000000..edd1e15 --- /dev/null +++ b/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require "decidim/maintainers_toolbox/releaser" + +RSpec.describe Decidim::MaintainersToolbox::ReleaserUtils do + + subject do + class DummyClass + include Decidim::MaintainersToolbox::ReleaserUtils + end + + klass = DummyClass.new + klass + end + + let(:working_dir) { File.expand_path("../../..", __dir__) } + let(:tmp_repository_dir) { "/tmp/decidim-releaser-utils-test-#{rand(1_000)}" } + let(:decidim_version) { "0.99.0.rc1" } + let(:release_branch) { "release/0.99-stable" } + + before do + FileUtils.mkdir_p("#{tmp_repository_dir}/code") + Dir.chdir("#{tmp_repository_dir}/code") + ` + git init --initial-branch=develop . + git config user.email "decidim_releaser@example.com" + git config user.name "Decidim::ReleaserUtils test" + + touch a_file.txt && git add a_file.txt + echo #{decidim_version} > .decidim-version && git add .decidim-version + git commit -m "Initial commit (#1234)" + + git branch #{release_branch} + git switch --quiet #{release_branch} + ` + end + + after do + Dir.chdir(working_dir) + FileUtils.rm_r(Dir.glob(tmp_repository_dir)) + end + + describe "#bump_decidim_version" do + it "writes the file" do + version_number = File.read(".decidim-version").strip + expect(version_number).to eq("0.99.0.rc1") + + subject.bump_decidim_version("0.99.0.rc2") + + new_version_number = File.read(".decidim-version").strip + expect(new_version_number).to eq("0.99.0.rc2") + end + end +end From edaa46f983712178963cbbfde76c6e2708c9b280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 13:54:46 +0200 Subject: [PATCH 16/24] Extract 'releaser repository' shared context --- .../maintainers_toolbox/releaser_spec.rb | 29 +++--------------- .../releaser_utils_spec.rb | 26 ++-------------- .../releaser_repository_shared_context.rb | 30 +++++++++++++++++++ 3 files changed, 36 insertions(+), 49 deletions(-) create mode 100644 spec/shared/releaser_repository_shared_context.rb diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index 5587136..bf63936 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -1,39 +1,18 @@ # frozen_string_literal: true require "decidim/maintainers_toolbox/releaser" +require_relative "../../../shared/releaser_repository_shared_context" RSpec.describe Decidim::MaintainersToolbox::Releaser do subject { described_class.new(token: token, version_type: version_type, exit_with_unstaged_changes: exit_with_unstaged_changes, working_dir: tmp_repository_dir) } let(:token) { "1234" } let(:version_type) { "patch" } - let(:release_branch) { "release/0.99-stable" } - let(:tmp_repository_dir) { "/tmp/decidim-releaser-test-#{rand(1_000)}" } - let(:working_dir) { File.expand_path("../../..", __dir__) } let(:exit_with_unstaged_changes) { true } - let(:decidim_version) { "0.99.0.rc1" } - - before do - FileUtils.mkdir_p("#{tmp_repository_dir}/code") - Dir.chdir("#{tmp_repository_dir}/code") - ` - git init --initial-branch=develop . - git config user.email "decidim_releaser@example.com" - git config user.name "Decidim::Releaser test" - - touch a_file.txt && git add a_file.txt - echo #{decidim_version} > .decidim-version && git add .decidim-version - git commit -m "Initial commit (#1234)" - - git branch #{release_branch} - git switch --quiet #{release_branch} - ` - end - after do - Dir.chdir(working_dir) - FileUtils.rm_r(Dir.glob(tmp_repository_dir)) - end + let(:tmp_repository_dir) { "/tmp/decidim-releaser-test-#{rand(1_000)}" } + + include_context "releaser repository" describe "#branch" do it "returns the correct branch" do diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb index edd1e15..fc6ea52 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "decidim/maintainers_toolbox/releaser" +require_relative "../../../shared/releaser_repository_shared_context" RSpec.describe Decidim::MaintainersToolbox::ReleaserUtils do @@ -13,32 +14,9 @@ class DummyClass klass end - let(:working_dir) { File.expand_path("../../..", __dir__) } let(:tmp_repository_dir) { "/tmp/decidim-releaser-utils-test-#{rand(1_000)}" } - let(:decidim_version) { "0.99.0.rc1" } - let(:release_branch) { "release/0.99-stable" } - - before do - FileUtils.mkdir_p("#{tmp_repository_dir}/code") - Dir.chdir("#{tmp_repository_dir}/code") - ` - git init --initial-branch=develop . - git config user.email "decidim_releaser@example.com" - git config user.name "Decidim::ReleaserUtils test" - - touch a_file.txt && git add a_file.txt - echo #{decidim_version} > .decidim-version && git add .decidim-version - git commit -m "Initial commit (#1234)" - - git branch #{release_branch} - git switch --quiet #{release_branch} - ` - end - after do - Dir.chdir(working_dir) - FileUtils.rm_r(Dir.glob(tmp_repository_dir)) - end + include_context "releaser repository" describe "#bump_decidim_version" do it "writes the file" do diff --git a/spec/shared/releaser_repository_shared_context.rb b/spec/shared/releaser_repository_shared_context.rb new file mode 100644 index 0000000..f86376d --- /dev/null +++ b/spec/shared/releaser_repository_shared_context.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +RSpec.shared_context "releaser repository" do + let(:working_dir) { File.expand_path("../../..", __dir__) } + let(:decidim_version) { "0.99.0.rc1" } + let(:release_branch) { "release/0.99-stable" } + + before do + FileUtils.mkdir_p("#{tmp_repository_dir}/code") + Dir.chdir("#{tmp_repository_dir}/code") + ` + git init --initial-branch=develop . + git config user.email "decidim_releaser@example.com" + git config user.name "Decidim::ReleaserUtils test" + + touch a_file.txt && git add a_file.txt + echo #{decidim_version} > .decidim-version && git add .decidim-version + git commit -m "Initial commit (#1234)" + + git branch #{release_branch} + git switch --quiet #{release_branch} + ` + end + + after do + Dir.chdir(working_dir) + FileUtils.rm_r(Dir.glob(tmp_repository_dir)) + end + +end From a3ec237e86b3cad86f251037693c49ff5a8cbafa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 17:58:22 +0200 Subject: [PATCH 17/24] Improve checks for branches and versions when releasing a RC --- .../release_candidate_version.rb | 34 ++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/decidim/maintainers_toolbox/release_candidate_version.rb b/lib/decidim/maintainers_toolbox/release_candidate_version.rb index 9d7cf59..8f808d6 100644 --- a/lib/decidim/maintainers_toolbox/release_candidate_version.rb +++ b/lib/decidim/maintainers_toolbox/release_candidate_version.rb @@ -6,6 +6,11 @@ module Decidim module MaintainersToolbox + # Creates a release candidate version for this branch + # + # If we are in develop (i.e. v0.30.0.dev) it will create the rc1 (i.e. v0.30.0.rc1) + # If we are in the stable release with an rc (i.e. v0.30.0.rc1) it will create the next rc (i.e. v0.30.0.rc2) + # If we are in the stable release with a patch (i.e. v0.30.0) it will bail out class ReleaseCandidateVersion include Decidim::MaintainersToolbox::ReleaserUtils @@ -18,7 +23,7 @@ def initialize(token:, working_dir: Dir.pwd) end def call - exit_unless_develop + check_branch_and_version_sanity prepare_next_development_version prepare_next_release_candidate_version @@ -44,16 +49,37 @@ def release_branch end end - def exit_unless_develop - return if branch == "develop" + def check_branch_and_version_sanity + return if develop_branch? && dev_version_number? + return if release_branch? && rc_version_number? error_message = <<-EOERROR - This is not the develop branch, change to the develop branch to run this script. + Check if the branch is valid for a release candidate. It should be: + - develop with a dev version (i.e. develop branch with 0.30.0.dev decidim version) + - stable branch with a release candidate version (i.e. release/0.30-stable branch with 0.30.rc1 decidim version) EOERROR exit_with_errors(error_message) end + def develop_branch? + branch == "develop" + end + + def dev_version_number? + version_number.match? /dev$/ + end + + def release_branch? + branch.start_with?("release/") + end + + def rc_version_number? + version_number.match? /rc.$/ + end + def prepare_next_development_version + return unless develop_branch? || dev_version_number? + run("git pull origin develop") run("git checkout -b #{release_branch}") From 15a8b536b180745a03a399e1a2b78f397707257d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 17:58:37 +0200 Subject: [PATCH 18/24] fixup! Extract 'releaser repository' shared context --- spec/shared/releaser_repository_shared_context.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/shared/releaser_repository_shared_context.rb b/spec/shared/releaser_repository_shared_context.rb index f86376d..f4bab7c 100644 --- a/spec/shared/releaser_repository_shared_context.rb +++ b/spec/shared/releaser_repository_shared_context.rb @@ -26,5 +26,4 @@ Dir.chdir(working_dir) FileUtils.rm_r(Dir.glob(tmp_repository_dir)) end - end From b5dc3e1f9bc8975898e23c7526ab5b2f4df478e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 17:59:26 +0200 Subject: [PATCH 19/24] Extract #release_branch spec to RC/Patch specs --- .../release_candidate_version_spec.rb | 21 +++++++++++++++++++ .../release_patch_version_spec.rb | 20 ++++++++++++++++++ .../maintainers_toolbox/releaser_spec.rb | 13 ------------ 3 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb create mode 100644 spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb diff --git a/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb b/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb new file mode 100644 index 0000000..24a72b7 --- /dev/null +++ b/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require "decidim/maintainers_toolbox/release_candidate_version" +require_relative "../../../shared/releaser_repository_shared_context" + +RSpec.describe Decidim::MaintainersToolbox::ReleaseCandidateVersion do + subject { described_class.new(token: token, working_dir: tmp_repository_dir) } + + let(:token) { "1234" } + let(:tmp_repository_dir) { "/tmp/decidim-release-candidate-version-test-#{rand(1_000)}" } + + include_context "releaser repository" + + describe "#release_branch" do + it "returns the correct branch" do + expect(subject.send(:release_branch)).to eq release_branch + end + end +end + + diff --git a/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb b/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb new file mode 100644 index 0000000..f8a3a8b --- /dev/null +++ b/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require "decidim/maintainers_toolbox/release_patch_version" +require_relative "../../../shared/releaser_repository_shared_context" + +RSpec.describe Decidim::MaintainersToolbox::ReleasePatchVersion do + subject { described_class.new(token: token, working_dir: tmp_repository_dir) } + + let(:token) { "1234" } + let(:tmp_repository_dir) { "/tmp/decidim-release-patch-version-test-#{rand(1_000)}" } + + include_context "releaser repository" + + describe "#release_branch" do + it "returns the correct branch" do + expect(subject.send(:release_branch)).to eq release_branch + end + end +end + diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index bf63936..c6cacde 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -20,19 +20,6 @@ end end - describe "#release_branch" do - it "returns the correct branch" do - expect(subject.send(:release_branch)).to eq release_branch - end - - context "when we are not in a release branch" do - it "raises an error" do - `git switch --quiet develop` - expect { subject.send(:release_branch) }.to raise_error(Decidim::MaintainersToolbox::Releaser::InvalidBranchError) - end - end - end - describe "#parsed_version_number" do context "when it is a dev version" do let(:version_number) { "1.2.3.dev" } From 93726a4b32d1393067cfa4f7031f50f204a0aef4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 18:02:40 +0200 Subject: [PATCH 20/24] Move #next_version_number_for_release_candidate method spec to ReleaseCandidateVersion spec --- .../release_candidate_version_spec.rb | 26 ++++++++++++++++++- .../maintainers_toolbox/releaser_spec.rb | 26 ------------------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb b/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb index 24a72b7..c60fc1e 100644 --- a/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb @@ -16,6 +16,30 @@ expect(subject.send(:release_branch)).to eq release_branch end end -end + describe "#next_version_number_for_release_candidate" do + context "when it is a dev version" do + let(:version_number) { "0.1.0.dev" } + + it "returns the first release candidate" do + expect(subject.send(:next_version_number_for_release_candidate, version_number)).to eq "0.1.0.rc1" + end + end + + context "when it is a release candidate version" do + let(:version_number) { "0.1.0.rc1" } + + it "returns the correct next version number" do + expect(subject.send(:next_version_number_for_release_candidate, version_number)).to eq "0.1.0.rc2" + end + end + + context "when it is a patch version" do + let(:version_number) { "0.1.0" } + it "raises an error" do + expect { subject.send(:next_version_number_for_release_candidate, version_number) }.to raise_error(Decidim::MaintainersToolbox::ReleaserUtils::InvalidVersionTypeError) + end + end + end +end diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index c6cacde..7716202 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -46,32 +46,6 @@ end end - describe "#next_version_number_for_release_candidate" do - context "when it is a dev version" do - let(:version_number) { "0.1.0.dev" } - - it "returns the first release candidate" do - expect(subject.send(:next_version_number_for_release_candidate, version_number)).to eq "0.1.0.rc1" - end - end - - context "when it is a release candidate version" do - let(:version_number) { "0.1.0.rc1" } - - it "returns the correct next version number" do - expect(subject.send(:next_version_number_for_release_candidate, version_number)).to eq "0.1.0.rc2" - end - end - - context "when it is a patch version" do - let(:version_number) { "0.1.0" } - - it "raises an error" do - expect { subject.send(:next_version_number_for_release_candidate, version_number) }.to raise_error(Decidim::MaintainersToolbox::Releaser::InvalidVersionTypeError) - end - end - end - describe "#next_version_number_for_patch_release" do context "when it is a dev version" do let(:version_number) { "0.1.0.dev" } From d060c23037946eb459b3e11dfe26d0f3439a71f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 18:03:37 +0200 Subject: [PATCH 21/24] Move #next_version_number_for_patch_release method spec to ReleasePatchVersion spec --- .../release_patch_version_spec.rb | 27 ++++++++++++++++++- .../maintainers_toolbox/releaser_spec.rb | 26 ------------------ 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb b/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb index f8a3a8b..ae64200 100644 --- a/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb @@ -16,5 +16,30 @@ expect(subject.send(:release_branch)).to eq release_branch end end -end + describe "#next_version_number_for_patch_release" do + context "when it is a dev version" do + let(:version_number) { "0.1.0.dev" } + + it "returns the correct next version number" do + expect { subject.send(:next_version_number_for_patch_release, version_number) }.to raise_error(Decidim::MaintainersToolbox::ReleaserUtils::InvalidVersionTypeError) + end + end + + context "when it is a release candidate version" do + let(:version_number) { "0.1.0.rc1" } + + it "returns first patch number" do + expect(subject.send(:next_version_number_for_patch_release, version_number)).to eq "0.1.0" + end + end + + context "when it is a patch version" do + let(:version_number) { "0.1.0" } + + it "raises an error" do + expect(subject.send(:next_version_number_for_patch_release, version_number)).to eq "0.1.1" + end + end + end +end diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index 7716202..489091b 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -46,32 +46,6 @@ end end - describe "#next_version_number_for_patch_release" do - context "when it is a dev version" do - let(:version_number) { "0.1.0.dev" } - - it "returns the correct next version number" do - expect { subject.send(:next_version_number_for_patch_release, version_number) }.to raise_error(Decidim::MaintainersToolbox::Releaser::InvalidVersionTypeError) - end - end - - context "when it is a release candidate version" do - let(:version_number) { "0.1.0.rc1" } - - it "returns first patch number" do - expect(subject.send(:next_version_number_for_patch_release, version_number)).to eq "0.1.0" - end - end - - context "when it is a patch version" do - let(:version_number) { "0.1.0" } - - it "raises an error" do - expect(subject.send(:next_version_number_for_patch_release, version_number)).to eq "0.1.1" - end - end - end - describe "#old_version_number" do let(:decidim_version) { "0.1.0" } From 13e2d446fc330ab1acd35941e1755fa623203326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 18:06:40 +0200 Subject: [PATCH 22/24] Move rest of the methods specs to ReleaserUtils spec --- .../maintainers_toolbox/releaser_spec.rb | 40 ------------------- .../releaser_utils_spec.rb | 40 +++++++++++++++++++ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index 489091b..90ed03e 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -13,44 +13,4 @@ let(:tmp_repository_dir) { "/tmp/decidim-releaser-test-#{rand(1_000)}" } include_context "releaser repository" - - describe "#branch" do - it "returns the correct branch" do - expect(subject.send(:branch)).to eq release_branch - end - end - - describe "#parsed_version_number" do - context "when it is a dev version" do - let(:version_number) { "1.2.3.dev" } - - it "parses the version number" do - expect(subject.send(:parsed_version_number, version_number)).to eq([1, 2, 3]) - end - end - - context "when it is a release candidate version" do - let(:version_number) { "1.2.3.rc1" } - - it "parses the version number" do - expect(subject.send(:parsed_version_number, version_number)).to eq([1, 2, 3]) - end - end - - context "when it is a patch version" do - let(:version_number) { "1.2.3" } - - it "parses the version number" do - expect(subject.send(:parsed_version_number, version_number)).to eq([1, 2, 3]) - end - end - end - - describe "#old_version_number" do - let(:decidim_version) { "0.1.0" } - - it "returns the correct version number" do - expect(subject.send(:old_version_number)).to eq "0.1.0" - end - end end diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb index fc6ea52..87517c7 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_utils_spec.rb @@ -29,4 +29,44 @@ class DummyClass expect(new_version_number).to eq("0.99.0.rc2") end end + + describe "#branch" do + it "returns the correct branch" do + expect(subject.send(:branch)).to eq release_branch + end + end + + describe "#parsed_version_number" do + context "when it is a dev version" do + let(:version_number) { "1.2.3.dev" } + + it "parses the version number" do + expect(subject.send(:parsed_version_number, version_number)).to eq([1, 2, 3]) + end + end + + context "when it is a release candidate version" do + let(:version_number) { "1.2.3.rc1" } + + it "parses the version number" do + expect(subject.send(:parsed_version_number, version_number)).to eq([1, 2, 3]) + end + end + + context "when it is a patch version" do + let(:version_number) { "1.2.3" } + + it "parses the version number" do + expect(subject.send(:parsed_version_number, version_number)).to eq([1, 2, 3]) + end + end + end + + describe "#old_version_number" do + let(:decidim_version) { "0.1.0" } + + it "returns the correct version number" do + expect(subject.send(:old_version_number)).to eq "0.1.0" + end + end end From 5725152c8008d74a6e5779cd72eff7e816f0628f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 18:35:13 +0200 Subject: [PATCH 23/24] Add specs for sanity checks and fix bug in release candidate checks --- .../release_candidate_version.rb | 4 ++-- .../release_candidate_version_spec.rb | 18 ++++++++++++++++++ .../release_patch_version_spec.rb | 10 ++++++++++ .../maintainers_toolbox/releaser_spec.rb | 8 ++++++++ .../releaser_repository_shared_context.rb | 4 ++-- 5 files changed, 40 insertions(+), 4 deletions(-) diff --git a/lib/decidim/maintainers_toolbox/release_candidate_version.rb b/lib/decidim/maintainers_toolbox/release_candidate_version.rb index 8f808d6..c8742fd 100644 --- a/lib/decidim/maintainers_toolbox/release_candidate_version.rb +++ b/lib/decidim/maintainers_toolbox/release_candidate_version.rb @@ -66,7 +66,7 @@ def develop_branch? end def dev_version_number? - version_number.match? /dev$/ + @old_version_number.match? /dev$/ end def release_branch? @@ -74,7 +74,7 @@ def release_branch? end def rc_version_number? - version_number.match? /rc.$/ + @old_version_number.match? /rc.$/ end def prepare_next_development_version diff --git a/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb b/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb index c60fc1e..ce1aadd 100644 --- a/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/release_candidate_version_spec.rb @@ -42,4 +42,22 @@ end end end + + context "if this is release branch with a patch version" do + let(:decidim_version) { "0.99.0" } + let(:release_branch) { "release/0.99-stable" } + + it "exits" do + expect { subject.call }.to raise_error SystemExit + end + end + + context "if this is feature branch" do + let(:decidim_version) { "0.99.0.rc1" } + let(:release_branch) { "feature/fix-my-street" } + + it "exits" do + expect { subject.call }.to raise_error SystemExit + end + end end diff --git a/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb b/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb index ae64200..ff37929 100644 --- a/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/release_patch_version_spec.rb @@ -42,4 +42,14 @@ end end end + + context "if this is not a release branch" do + it "exits" do + ` + git switch --quiet develop + ` + + expect { subject.call }.to raise_error SystemExit + end + end end diff --git a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb index 90ed03e..bdb1d3f 100644 --- a/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb +++ b/spec/lib/decidim/maintainers_toolbox/releaser_spec.rb @@ -13,4 +13,12 @@ let(:tmp_repository_dir) { "/tmp/decidim-releaser-test-#{rand(1_000)}" } include_context "releaser repository" + + context "if there are unstaged changes" do + it "exits" do + `echo hello_world.txt > a_file.txt` + + expect { subject.call }.to raise_error SystemExit + end + end end diff --git a/spec/shared/releaser_repository_shared_context.rb b/spec/shared/releaser_repository_shared_context.rb index f4bab7c..bf8546c 100644 --- a/spec/shared/releaser_repository_shared_context.rb +++ b/spec/shared/releaser_repository_shared_context.rb @@ -6,8 +6,8 @@ let(:release_branch) { "release/0.99-stable" } before do - FileUtils.mkdir_p("#{tmp_repository_dir}/code") - Dir.chdir("#{tmp_repository_dir}/code") + FileUtils.mkdir_p("#{tmp_repository_dir}") + Dir.chdir("#{tmp_repository_dir}") ` git init --initial-branch=develop . git config user.email "decidim_releaser@example.com" From 8b7d92ef0a141e38c2ac88173be283cc3ca71212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Pereira=20de=20Lucena?= Date: Tue, 16 Jul 2024 18:35:28 +0200 Subject: [PATCH 24/24] Improve legibility in the finish message --- lib/decidim/maintainers_toolbox/release_candidate_version.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/decidim/maintainers_toolbox/release_candidate_version.rb b/lib/decidim/maintainers_toolbox/release_candidate_version.rb index c8742fd..94be899 100644 --- a/lib/decidim/maintainers_toolbox/release_candidate_version.rb +++ b/lib/decidim/maintainers_toolbox/release_candidate_version.rb @@ -154,6 +154,7 @@ def prepare_next_release_candidate_version 4. Usually, at this point, the release branch is deployed to Metadecidim during, at least, one week to validate the stability of the version. EOMESSAGE + puts "*" * 80 puts finish_message end