diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4f2be7855..f23644c6c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,12 +1,12 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2024-02-07 17:44:01 UTC using RuboCop version 1.60.2. +# on 2024-08-28 16:05:17 UTC using RuboCop version 1.65.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 11 +# Offense count: 10 # Configuration parameters: EnforcedStyle, AllowedGems, Include. # SupportedStyles: Gemfile, gems.rb, gemspec # Include: **/*.gemspec, **/Gemfile, **/gems.rb @@ -34,7 +34,7 @@ Naming/MethodParameterName: - 'lib/fastlane/plugin/wpmreleasetoolkit/actions/android/an_update_metadata_source_action.rb' - 'lib/fastlane/plugin/wpmreleasetoolkit/actions/common/gp_update_metadata_source.rb' -# Offense count: 110 +# Offense count: 109 # Configuration parameters: NamePrefix, ForbiddenPrefixes, AllowedMethods, MethodDefinitionMacros. # NamePrefix: is_, has_, have_ # ForbiddenPrefixes: is_, has_, have_ @@ -51,8 +51,14 @@ Naming/VariableNumber: Exclude: - 'lib/fastlane/plugin/wpmreleasetoolkit/helper/configure_helper.rb' -# Offense count: 5 -# Configuration parameters: Prefixes. +# Offense count: 6 +# This cop supports unsafe autocorrection (--autocorrect-all). +RSpec/BeEq: + Exclude: + - 'spec/file_reference_spec.rb' + +# Offense count: 6 +# Configuration parameters: Prefixes, AllowedPatterns. # Prefixes: when, with, without RSpec/ContextWording: Exclude: @@ -60,11 +66,20 @@ RSpec/ContextWording: - 'spec/git_helper_spec.rb' - 'spec/ios_lint_localizations_spec.rb' -# Offense count: 62 -# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly. -# Include: **/*_spec*rb*, **/spec/**/* -RSpec/FilePath: - Enabled: false +# Offense count: 5 +# This cop supports safe autocorrection (--autocorrect). +# Configuration parameters: CustomTransform, IgnoredWords, DisallowedExamples. +# DisallowedExamples: works +RSpec/ExampleWording: + Exclude: + - 'spec/github_helper_spec.rb' + +# Offense count: 2 +# This cop supports safe autocorrection (--autocorrect). +RSpec/ExcessiveDocstringSpacing: + Exclude: + - 'spec/git_helper_spec.rb' + - 'spec/marketing_version_calculator_spec.rb' # Offense count: 25 # Configuration parameters: AssignmentOnly. @@ -73,14 +88,15 @@ RSpec/InstanceVariable: - 'spec/git_helper_spec.rb' - 'spec/ios_lint_localizations_spec.rb' -# Offense count: 122 +# Offense count: 146 # Configuration parameters: . # SupportedStyles: have_received, receive RSpec/MessageSpies: EnforcedStyle: receive # Offense count: 48 -# Configuration parameters: IgnoreSharedExamples. +# Configuration parameters: EnforcedStyle, IgnoreSharedExamples. +# SupportedStyles: always, named_only RSpec/NamedSubject: Exclude: - 'spec/android_version_helper_spec.rb' @@ -88,21 +104,72 @@ RSpec/NamedSubject: - 'spec/configuration_spec.rb' - 'spec/file_reference_spec.rb' -# Offense count: 14 +# Offense count: 20 +# Configuration parameters: AllowedGroups. RSpec/NestedGroups: Max: 5 -# Offense count: 7 +# Offense count: 54 +# Configuration parameters: AllowedPatterns. +# AllowedPatterns: ^expect_, ^assert_ +RSpec/NoExpectationExample: + Exclude: + - 'spec/android_firebase_test_spec.rb' + - 'spec/android_send_app_size_metrics_spec.rb' + - 'spec/firebase_test_runner_spec.rb' + - 'spec/get_prs_between_tags_spec.rb' + - 'spec/ios_download_strings_files_from_glotpress_spec.rb' + - 'spec/ios_generate_strings_file_from_code_spec.rb' + - 'spec/ios_lint_localizations_spec.rb' + - 'spec/ios_send_app_size_metrics_spec.rb' + - 'spec/release_notes_helper_spec.rb' + +# Offense count: 10 +# This cop supports unsafe autocorrection (--autocorrect-all). +RSpec/ReceiveMessages: + Exclude: + - 'spec/android_firebase_test_spec.rb' + - 'spec/file_reference_spec.rb' + - 'spec/firebase_device_spec.rb' + +# Offense count: 67 +# Configuration parameters: Include, CustomTransform, IgnoreMethods, IgnoreMetadata. +# Include: **/*_spec.rb +RSpec/SpecFilePathFormat: + Enabled: false + +# Offense count: 9 RSpec/StubbedMock: Exclude: - 'spec/encryption_helper_spec.rb' - 'spec/file_reference_spec.rb' + - 'spec/publish_release_spec.rb' + +# Offense count: 2 +RSpec/SubjectDeclaration: + Exclude: + - 'spec/file_reference_spec.rb' # Offense count: 6 RSpec/SubjectStub: Exclude: - 'spec/file_reference_spec.rb' +# Offense count: 18 +# This cop supports unsafe autocorrection (--autocorrect-all). +# Configuration parameters: EnforcedStyle. +# SupportedStyles: constant, string +RSpec/VerifiedDoubleReference: + Exclude: + - 'spec/copy_branch_protection_action_spec.rb' + - 'spec/create_release_backmerge_pull_request_spec.rb' + - 'spec/get_prs_between_tags_spec.rb' + - 'spec/github_helper_spec.rb' + - 'spec/remove_branch_protection_action_spec.rb' + - 'spec/set_branch_protection_action_spec.rb' + - 'spec/set_milestone_frozen_marker_action_spec.rb' + - 'spec/update_assigned_milestone_spec.rb' + # Offense count: 4 # Configuration parameters: IgnoreNameless, IgnoreSymbolicNames. RSpec/VerifiedDoubles: diff --git a/CHANGELOG.md b/CHANGELOG.md index e88771261..058c75323 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,11 @@ ### New Features -_None_ +- Added the `publish_github_release` action to publish existing GitHub draft releases [#585] ### Bug Fixes -_None_ +- Deprecated the `create_release` action, now renamed to `create_github_release` for consistency [#585] ### Internal Changes diff --git a/Gemfile.lock b/Gemfile.lock index f36943927..736ff8abd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,7 +26,7 @@ GEM base64 nkf rexml - activesupport (7.2.0) + activesupport (7.2.1) base64 bigdecimal concurrent-ruby (~> 1.0, >= 1.3.1) @@ -46,16 +46,16 @@ GEM ast (2.4.2) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.963.0) - aws-sdk-core (3.201.4) + aws-partitions (1.968.0) + aws-sdk-core (3.202.0) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.8) + aws-sigv4 (~> 1.9) jmespath (~> 1, >= 1.6.1) aws-sdk-kms (1.88.0) aws-sdk-core (~> 3, >= 3.201.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.157.0) + aws-sdk-s3 (1.159.0) aws-sdk-core (~> 3, >= 3.201.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) @@ -277,7 +277,7 @@ GEM signet (>= 0.16, < 2.a) hashdiff (1.1.1) highline (2.0.3) - http-cookie (1.0.6) + http-cookie (1.0.7) domain_name (~> 0.5) httpclient (2.8.3) i18n (1.14.5) @@ -297,7 +297,7 @@ GEM mini_magick (4.13.2) mini_mime (1.1.5) mini_portile2 (2.8.7) - minitest (5.24.1) + minitest (5.25.1) molinillo (0.8.0) multi_json (1.15.0) multipart-post (2.4.1) @@ -317,7 +317,7 @@ GEM options (2.3.2) optparse (0.5.0) os (1.1.4) - parallel (1.26.2) + parallel (1.26.3) parser (3.3.4.2) ast (~> 2.4.1) racc @@ -354,7 +354,7 @@ GEM rspec-mocks (~> 3.13.0) rspec-core (3.13.0) rspec-support (~> 3.13.0) - rspec-expectations (3.13.1) + rspec-expectations (3.13.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.13.0) rspec-mocks (3.13.1) @@ -374,13 +374,10 @@ GEM rubocop-ast (>= 1.31.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.32.0) + rubocop-ast (1.32.1) parser (>= 3.3.1.0) - rubocop-require_tools (0.1.2) - rubocop (>= 0.49.1) - rubocop-rspec (2.3.0) - rubocop (~> 1.0) - rubocop-ast (>= 1.1.0) + rubocop-rspec (3.0.0) + rubocop (~> 1.40) ruby-macho (2.5.1) ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) @@ -451,9 +448,8 @@ DEPENDENCIES rmagick (~> 5.3) rspec (~> 3.8) rspec_junit_formatter (~> 0.4.1) - rubocop (~> 1.0) - rubocop-require_tools (~> 0.1.2) - rubocop-rspec (= 2.3.0) + rubocop (~> 1.65) + rubocop-rspec (= 3.0) simplecov (~> 0.16.1) webmock yard diff --git a/fastlane-plugin-wpmreleasetoolkit.gemspec b/fastlane-plugin-wpmreleasetoolkit.gemspec index 73549df9b..9ab97fc9a 100644 --- a/fastlane-plugin-wpmreleasetoolkit.gemspec +++ b/fastlane-plugin-wpmreleasetoolkit.gemspec @@ -52,8 +52,7 @@ Gem::Specification.new do |spec| spec.add_development_dependency 'rmagick', '~> 5.3' spec.add_development_dependency 'rspec', '~> 3.8' spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4.1' - spec.add_development_dependency 'rubocop', '~> 1.0' - spec.add_development_dependency 'rubocop-require_tools', '~> 0.1.2' - spec.add_development_dependency 'rubocop-rspec', '2.3.0' + spec.add_development_dependency 'rubocop', '~> 1.65' + spec.add_development_dependency 'rubocop-rspec', '3.0' spec.add_development_dependency 'simplecov', '~> 0.16.1' end diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_release_action.rb b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_github_release_action.rb similarity index 93% rename from lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_release_action.rb rename to lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_github_release_action.rb index f294a362b..5672ea5ec 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_release_action.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_github_release_action.rb @@ -5,7 +5,7 @@ require_relative '../../helper/android/android_version_helper' module Fastlane module Actions - class CreateReleaseAction < Action + class CreateGithubReleaseAction < Action def self.run(params) repository = params[:repository] version = params[:version] @@ -100,5 +100,16 @@ def self.is_supported?(platform) true end end + + # For backwards compatibility + class CreateReleaseAction < CreateGithubReleaseAction + def self.category + :deprecated + end + + def self.deprecated_notes + "This action has been renamed `#{superclass.action_name}`" + end + end end end diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/publish_github_release_action.rb b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/publish_github_release_action.rb new file mode 100644 index 000000000..8629012db --- /dev/null +++ b/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/publish_github_release_action.rb @@ -0,0 +1,63 @@ +require 'fastlane/action' +require_relative '../../helper/github_helper' + +module Fastlane + module Actions + class PublishGithubReleaseAction < Action + def self.run(params) + repository = params[:repository] + name = params[:name] + prerelease = params[:prerelease] + + github_helper = Fastlane::Helper::GithubHelper.new(github_token: params[:github_token]) + + url = github_helper.publish_release( + repository: repository, + name: name, + prerelease: prerelease == :unchanged ? nil : prerelease + ) + UI.success("Successfully published GitHub Release #{name}. You can see it at '#{url}'") + url + end + + def self.description + 'Publish an existing GitHub Release still in draft mode' + end + + def self.authors + ['Automattic'] + end + + def self.return_value + 'The URL of the published GitHub Release' + end + + def self.details + 'Publish an existing GitHub Release still in draft mode' + end + + def self.available_options + [ + FastlaneCore::ConfigItem.new(key: :repository, + description: 'The slug (`/`) of the GitHub repository we want to create the release on', + optional: false, + type: String), + FastlaneCore::ConfigItem.new(key: :name, + description: 'The name (aka title) of the draft release to publish', + optional: false, + type: String), + FastlaneCore::ConfigItem.new(key: :prerelease, + description: 'True to publish as a pre-release. False to published as final. Don\'t provide a value to keep the same (non-)prerelease status as the one used in the Draft', + optional: true, + default_value: :unchanged, + type: Boolean), + Fastlane::Helper::GithubHelper.github_token_config_item, + ] + end + + def self.is_supported?(platform) + true + end + end + end +end diff --git a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb index c52e6c9e3..733b2a678 100644 --- a/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +++ b/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb @@ -186,7 +186,7 @@ def generate_release_notes(repository:, tag_name:, previous_tag:, target_commiti res.body end - # Returns the URL of the GitHub release pointing at a given tag + # Returns the URL of the published GitHub release pointing at a given tag # @param [String] repository The repository to create the GitHub release on. Typically a repo slug (/). # @param [String] tag_name The name of the git tag to get the associated release of # @@ -198,6 +198,31 @@ def get_release_url(repository:, tag_name:) nil end + # Publishes an existing GitHub Release still in draft mode. + # + # @param [String] repository The repository name, including the organization (e.g. `wordpress-mobile/wordpress-ios`) + # @param [String] name The name of the release to publish. + # @param [Boolean] prerelease Indicates if this should be created as a pre-release (i.e. for alpha/beta) + # + # @return [String] URL of the corresponding GitHub Release + # + def publish_release(repository:, name:, prerelease: nil) + releases = client.releases(repository) + release = releases.find { |r| r.name == name } + + UI.user_error!("No release found with name #{name}") unless release + + client.update_release( + release.url, + { + draft: false, + prerelease: prerelease + }.compact + ) + + release.html_url + end + # Downloads a file from the given GitHub tag # # @param [String] repository The repository name (including the organization) diff --git a/spec/publish_github_release_spec.rb b/spec/publish_github_release_spec.rb new file mode 100644 index 000000000..0aa629542 --- /dev/null +++ b/spec/publish_github_release_spec.rb @@ -0,0 +1,62 @@ +require 'spec_helper' + +describe Fastlane::Actions::PublishGithubReleaseAction do + let(:test_token) { 'ghp_fake_token' } + let(:test_repo) { 'repo-test/project-test' } + let(:test_name) { '1.0.0' } + let(:github_helper) { instance_double(Fastlane::Helper::GithubHelper) } + + before do + allow(Fastlane::Helper::GithubHelper).to receive(:new).and_return(github_helper) + end + + context 'when providing valid parameters' do + it 'publishes the release and returns the URL' do + allow(github_helper).to receive(:publish_release).with( + repository: test_repo, + name: test_name, + prerelease: nil + ).and_return('https://github.com/repo-test/project-test/releases/tag/1.0.0') + + result = run_described_fastlane_action( + github_token: test_token, + repository: test_repo, + name: test_name + ) + + expect(result).to eq('https://github.com/repo-test/project-test/releases/tag/1.0.0') + end + + it 'publishes a prerelease when specified' do + allow(github_helper).to receive(:publish_release).with( + repository: test_repo, + name: test_name, + prerelease: true + ).and_return('https://github.com/repo-test/project-test/releases/tag/1.0.0-beta') + + result = run_described_fastlane_action( + github_token: test_token, + repository: test_repo, + name: test_name, + prerelease: true + ) + + expect(result).to eq('https://github.com/repo-test/project-test/releases/tag/1.0.0-beta') + end + end + + context 'when successful' do + it 'prints a success message' do + allow(github_helper).to receive(:publish_release).and_return('https://github.com/repo-test/project-test/releases/tag/1.0.0') + + allow(Fastlane::UI).to receive(:success).with(anything).at_least(:once) + expect(Fastlane::UI).to receive(:success).with("Successfully published GitHub Release 1.0.0. You can see it at 'https://github.com/repo-test/project-test/releases/tag/1.0.0'") + + run_described_fastlane_action( + github_token: test_token, + repository: test_repo, + name: test_name + ) + end + end +end