fastlane-plugin-wpmreleasetoolkit 1.3.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_betabuild_prechecks.rb +11 -17
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_build_prechecks.rb +5 -10
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_beta.rb +9 -16
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_final_release.rb +8 -15
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_hotfix.rb +13 -22
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_bump_version_release.rb +11 -18
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_codefreeze_prechecks.rb +4 -10
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_completecodefreeze_prechecks.rb +2 -8
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_current_branch_is_hotfix.rb +1 -7
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_download_file_by_version.rb +1 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_finalize_prechecks.rb +2 -6
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_alpha_version.rb +1 -7
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_app_version.rb +1 -7
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_get_release_version.rb +1 -7
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_hotifx_prechecks.rb +4 -4
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/android/android_tag_build.rb +2 -8
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/check_translation_progress.rb +1 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/comment_on_pr.rb +89 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/common/create_release_action.rb +3 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_bump_version_hotfix.rb +30 -15
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_generate_strings_file_from_code.rb +115 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/actions/ios/ios_localize_project.rb +5 -6
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/an_metadata_update_helper.rb +1 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_git_helper.rb +1 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/android/android_version_helper.rb +33 -68
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/filesystem_helper.rb +3 -1
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/github_helper.rb +48 -8
- data/lib/fastlane/plugin/wpmreleasetoolkit/helper/interactive_prompt_reminder.rb +93 -0
- data/lib/fastlane/plugin/wpmreleasetoolkit/version.rb +1 -1
- metadata +27 -4
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Actions
|
5
|
+
module SharedValues
|
6
|
+
PR_COMMENT_REUSE_IDENTIFIER = :PR_COMMENT_REUSE_IDENTIFIER
|
7
|
+
end
|
8
|
+
|
9
|
+
class CommentOnPrAction < Action
|
10
|
+
def self.run(params)
|
11
|
+
require_relative '../../helper/github_helper'
|
12
|
+
|
13
|
+
reuse_identifier = Fastlane::Helper::GithubHelper.comment_on_pr(
|
14
|
+
project_slug: params[:project],
|
15
|
+
pr_number: params[:pr_number],
|
16
|
+
body: params[:body],
|
17
|
+
reuse_identifier: params[:reuse_identifier]
|
18
|
+
)
|
19
|
+
|
20
|
+
Actions.lane_context[SharedValues::PR_COMMENT_REUSE_IDENTIFIER] = reuse_identifier
|
21
|
+
|
22
|
+
reuse_identifier
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.description
|
26
|
+
'Post a comment on a given PR number (optionally updating an existing one)'
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.authors
|
30
|
+
['Automattic']
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.details
|
34
|
+
<<~DETAILS
|
35
|
+
If used just once, this method makes it nice and easy to post a quick comment to a GitHub PR.
|
36
|
+
|
37
|
+
Subsequent runs will allow you to update an existing comment as many times as you need to
|
38
|
+
(e.g. across multiple CI runs), by using a `:reuse_identifier` to identify the comment to update.
|
39
|
+
DETAILS
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.available_options
|
43
|
+
[
|
44
|
+
FastlaneCore::ConfigItem.new(
|
45
|
+
key: :access_token,
|
46
|
+
env_name: 'GITHUB_TOKEN',
|
47
|
+
description: 'The GitHub token to use for posting the comment',
|
48
|
+
type: String
|
49
|
+
),
|
50
|
+
FastlaneCore::ConfigItem.new(
|
51
|
+
key: :reuse_identifier,
|
52
|
+
description: 'If provided, the reuse identifier can identify an existing comment to overwrite',
|
53
|
+
type: String,
|
54
|
+
default_value: nil
|
55
|
+
),
|
56
|
+
FastlaneCore::ConfigItem.new(
|
57
|
+
key: :project,
|
58
|
+
description: 'The project slug (ex: `wordpress-mobile/wordpress-ios`)',
|
59
|
+
type: String
|
60
|
+
),
|
61
|
+
FastlaneCore::ConfigItem.new(
|
62
|
+
key: :pr_number,
|
63
|
+
description: 'The PR number',
|
64
|
+
type: Integer
|
65
|
+
),
|
66
|
+
FastlaneCore::ConfigItem.new(
|
67
|
+
key: :body,
|
68
|
+
description: 'The content of the comment',
|
69
|
+
type: String
|
70
|
+
),
|
71
|
+
]
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.output
|
75
|
+
[
|
76
|
+
['PR_COMMENT_REUSE_IDENTIFIER', 'The `reuse_identifier` for the most recently posted comment'],
|
77
|
+
]
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.return_value
|
81
|
+
'The `reuse_identifier` for the posted comment (useful for updating it later, if needed)'
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.is_supported?(platform)
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -10,7 +10,9 @@ module Fastlane
|
|
10
10
|
repository = params[:repository]
|
11
11
|
version = params[:version]
|
12
12
|
assets = params[:release_assets]
|
13
|
-
release_notes = params[:release_notes_file_path].nil? ? '' :
|
13
|
+
release_notes = params[:release_notes_file_path].nil? ? '' : File.read(params[:release_notes_file_path])
|
14
|
+
# Replace full URLS to PRs/Issues with shorthand, because GitHub does not render them properly otherwise.
|
15
|
+
release_notes.gsub!(%r{https://github.com/([^/]*/[^/]*)/(pulls?|issues?)/([0-9]*)}, '\1#\3')
|
14
16
|
prerelease = params[:prerelease]
|
15
17
|
|
16
18
|
UI.message("Creating draft release #{version} in #{repository}.")
|
@@ -9,14 +9,18 @@ module Fastlane
|
|
9
9
|
create_config(params[:previous_version], params[:version])
|
10
10
|
show_config()
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
update_deliverfile = params[:skip_deliver] == false
|
13
|
+
if update_deliverfile
|
14
|
+
UI.message 'Updating Fastlane deliver file...'
|
15
|
+
Fastlane::Helper::Ios::VersionHelper.update_fastlane_deliver(@new_short_version)
|
16
|
+
UI.message 'Done!'
|
17
|
+
end
|
18
|
+
|
15
19
|
UI.message 'Updating XcConfig...'
|
16
20
|
Fastlane::Helper::Ios::VersionHelper.update_xc_configs(@new_version, @new_short_version, @new_version_internal)
|
17
21
|
UI.message 'Done!'
|
18
22
|
|
19
|
-
Fastlane::Helper::Ios::GitHelper.commit_version_bump(include_deliverfile:
|
23
|
+
Fastlane::Helper::Ios::GitHelper.commit_version_bump(include_deliverfile: update_deliverfile, include_metadata: false)
|
20
24
|
|
21
25
|
UI.message 'Done.'
|
22
26
|
end
|
@@ -34,18 +38,29 @@ module Fastlane
|
|
34
38
|
end
|
35
39
|
|
36
40
|
def self.available_options
|
37
|
-
# Define all options your action supports.
|
38
|
-
|
39
|
-
# Below a few examples
|
40
41
|
[
|
41
|
-
FastlaneCore::ConfigItem.new(
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
42
|
+
FastlaneCore::ConfigItem.new(
|
43
|
+
key: :version,
|
44
|
+
env_name: 'FL_IOS_BUMP_VERSION_HOTFIX_VERSION',
|
45
|
+
description: 'The version of the hotfix',
|
46
|
+
is_string: true
|
47
|
+
),
|
48
|
+
FastlaneCore::ConfigItem.new(
|
49
|
+
key: :previous_version,
|
50
|
+
env_name: 'FL_IOS_BUMP_VERSION_HOTFIX_PREVIOUS_VERSION',
|
51
|
+
description: 'The version to branch from',
|
52
|
+
is_string: true
|
53
|
+
),
|
54
|
+
FastlaneCore::ConfigItem.new(
|
55
|
+
key: :skip_deliver,
|
56
|
+
env_name: 'FL_IOS_BUMP_VERSION_HOTFIX_SKIP_DELIVER',
|
57
|
+
description: 'Skips Deliverfile key update',
|
58
|
+
is_string: false, # Boolean parameter
|
59
|
+
optional: true,
|
60
|
+
# Don't skip the Deliverfile by default. At the time of writing, 2 out of 3 consumers
|
61
|
+
# still have a Deliverfile.
|
62
|
+
default_value: false
|
63
|
+
),
|
49
64
|
]
|
50
65
|
end
|
51
66
|
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
class IosGenerateStringsFileFromCodeAction < Action
|
4
|
+
def self.run(params)
|
5
|
+
files = files_matching(paths: params[:paths], exclude: params[:exclude])
|
6
|
+
flags = [('-q' if params[:quiet]), ('-SwiftUI' if params[:swiftui])].compact
|
7
|
+
flags += Array(params[:routines]).flat_map { |routine| ['-s', routine] }
|
8
|
+
cmd = ['genstrings', '-o', params[:output_dir], *flags, *files]
|
9
|
+
out = Actions.sh_control_output(*cmd, print_command: FastlaneCore::Globals.verbose?, print_command_output: true)
|
10
|
+
out = out.scrub.strip.split("\n")
|
11
|
+
errors = out.select { |line| line.include?('genstrings: error: ') }
|
12
|
+
UI.user_error!(errors.join("\n")) unless !params[:fail_on_error] || errors.empty?
|
13
|
+
out
|
14
|
+
end
|
15
|
+
|
16
|
+
# Adds the proper `**/*.{m,swift}` to the list of paths
|
17
|
+
def self.glob_pattern(path)
|
18
|
+
if path.end_with?('**') || path.end_with?('**/')
|
19
|
+
File.join(path, '*.{m,swift}')
|
20
|
+
elsif File.directory?(path) || path.end_with?('/')
|
21
|
+
File.join(path, '**', '*.{m,swift}')
|
22
|
+
else
|
23
|
+
path
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.files_matching(paths:, exclude:)
|
28
|
+
globbed_paths = paths.map { |p| glob_pattern(p) }
|
29
|
+
Dir.glob(globbed_paths).reject do |file|
|
30
|
+
exclude&.any? { |ex| File.fnmatch?(ex, file) }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#####################################################
|
35
|
+
# @!group Documentation
|
36
|
+
#####################################################
|
37
|
+
|
38
|
+
def self.description
|
39
|
+
'Generate the .strings files from your Objective-C and Swift code'
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.details
|
43
|
+
<<~DETAILS
|
44
|
+
Uses `genstrings` to generate the `.strings` files from your Objective-C and Swift code.
|
45
|
+
(especially `Localizable.strings` but it could generate more if the code uses custom tables).
|
46
|
+
|
47
|
+
You can provide a list of paths to scan but also paths to exclude. Both supports glob patterns.
|
48
|
+
You can also optionally provide a list of custom "routines" (aka macros or functions) that
|
49
|
+
`genstrings` should parse in addition to the usual `NSLocalizedString`. (see `-s` option of `genstrings`).
|
50
|
+
|
51
|
+
Tip: support for custom routines is useful if some of your targets define a helper function e.g.
|
52
|
+
`PodLocalizedString` to wrap calls to `Bundle.localizedString(forKey: key, value: value, table: nil)`,
|
53
|
+
just like the build-in `NSLocalizedString` does, but providing a custom bundle to look up the strings from.
|
54
|
+
DETAILS
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.available_options
|
58
|
+
[
|
59
|
+
FastlaneCore::ConfigItem.new(key: :paths,
|
60
|
+
env_name: 'FL_IOS_GENERATE_STRINGS_FILE_FROM_CODE_PATHS',
|
61
|
+
description: 'Array of paths to scan for `.m` and `.swift` files. The entries can also contain glob patterns',
|
62
|
+
type: Array,
|
63
|
+
default_value: ['.']),
|
64
|
+
FastlaneCore::ConfigItem.new(key: :exclude,
|
65
|
+
env_name: 'FL_IOS_GENERATE_STRINGS_FILE_FROM_CODE_EXCLUDE',
|
66
|
+
description: 'Array of paths or glob patterns to exclude from scanning',
|
67
|
+
type: Array,
|
68
|
+
default_value: []),
|
69
|
+
FastlaneCore::ConfigItem.new(key: :routines,
|
70
|
+
env_name: 'FL_IOS_GENERATE_STRINGS_FILE_FROM_CODE_ROUTINES',
|
71
|
+
description: 'Base name of the alternate methods to be parsed in addition to the standard `NSLocalizedString()` one. See the `-s` option in `man genstrings`',
|
72
|
+
type: Array,
|
73
|
+
default_value: []),
|
74
|
+
FastlaneCore::ConfigItem.new(key: :quiet,
|
75
|
+
env_name: 'FL_IOS_GENERATE_STRINGS_FILE_FROM_CODE_QUIET',
|
76
|
+
description: 'In quiet mode, `genstrings` will log warnings about duplicate values, but not about duplicate comments',
|
77
|
+
is_string: false, # Boolean
|
78
|
+
default_value: true),
|
79
|
+
FastlaneCore::ConfigItem.new(key: :swiftui,
|
80
|
+
env_name: 'FL_IOS_GENERATE_STRINGS_FILE_FROM_CODE_SWIFTUI',
|
81
|
+
description: "Should we include SwiftUI's `Text()` when parsing code with `genstrings`",
|
82
|
+
is_string: false, # Boolean
|
83
|
+
default_value: false),
|
84
|
+
FastlaneCore::ConfigItem.new(key: :output_dir,
|
85
|
+
env_name: 'FL_IOS_GENERATE_STRINGS_FILE_FROM_CODE_OUTPUT_DIR',
|
86
|
+
description: 'The path to the directory where the generated `.strings` files should be created',
|
87
|
+
type: String),
|
88
|
+
FastlaneCore::ConfigItem.new(key: :fail_on_error,
|
89
|
+
env_name: 'FL_IOS_GENERATE_STRINGS_FILE_FROM_CODE_FAIL_ON_ERROR',
|
90
|
+
description: 'If true, will fail with user_error! if `genstrings` printed any error while parsing',
|
91
|
+
is_string: false, # Boolean
|
92
|
+
default_value: true),
|
93
|
+
]
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.return_type
|
97
|
+
# Describes what type of data is expected to be returned
|
98
|
+
# see RETURN_TYPES in https://github.com/fastlane/fastlane/blob/master/fastlane/lib/fastlane/action.rb
|
99
|
+
:array_of_strings
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.return_value
|
103
|
+
'List of warning lines generated by genstrings on stdout'
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.authors
|
107
|
+
['Automattic']
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.is_supported?(platform)
|
111
|
+
[:ios, :mac].include?(platform)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -20,16 +20,15 @@ module Fastlane
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def self.details
|
23
|
-
'Gathers the string to localise'
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.available_options
|
23
|
+
'Gathers the string to localise. Deprecated in favor of the new `ios_generate_strings_file_from_code`'
|
27
24
|
end
|
28
25
|
|
29
|
-
def self.
|
26
|
+
def self.category
|
27
|
+
:deprecated
|
30
28
|
end
|
31
29
|
|
32
|
-
def self.
|
30
|
+
def self.deprecated_notes
|
31
|
+
'This action is deprecated in favor of `ios_generate_strings_file_from_code`'
|
33
32
|
end
|
34
33
|
|
35
34
|
def self.authors
|
@@ -50,7 +50,7 @@ module Fastlane
|
|
50
50
|
|
51
51
|
if line_count <= 1
|
52
52
|
# Single line output
|
53
|
-
fw.puts("msgid \"#{File.open(@content_file_path, 'r').read}\"")
|
53
|
+
fw.puts("msgid \"#{File.open(@content_file_path, 'r').read.rstrip}\"")
|
54
54
|
else
|
55
55
|
# Multiple line output
|
56
56
|
fw.puts('msgid ""')
|
@@ -13,7 +13,7 @@ module Fastlane
|
|
13
13
|
#
|
14
14
|
def self.commit_version_bump
|
15
15
|
require_relative './android_version_helper'
|
16
|
-
if Fastlane::Helper::Android::VersionHelper.
|
16
|
+
if File.exist?(Fastlane::Helper::Android::VersionHelper.version_properties_file)
|
17
17
|
Fastlane::Helper::GitHelper.commit(
|
18
18
|
message: 'Bump version number',
|
19
19
|
files: File.join(ENV['PROJECT_ROOT_FOLDER'], 'version.properties'),
|
@@ -26,14 +26,12 @@ module Fastlane
|
|
26
26
|
# "1.2" # Assuming build.gradle contains versionName "1.2.0"
|
27
27
|
# "1.2.3" # Assuming build.gradle contains versionName "1.2.3"
|
28
28
|
#
|
29
|
-
# @param [String] app The name of the app to be used for beta and alpha version update
|
30
|
-
#
|
31
29
|
# @return [String] The public-facing version number, extracted from the `versionName` of the `build.gradle` file.
|
32
30
|
# - If this version is a hotfix (more than 2 parts and 3rd part is non-zero), returns the "X.Y.Z" formatted string
|
33
31
|
# - Otherwise (not a hotfix / 3rd part of version is 0), returns "X.Y" formatted version number
|
34
32
|
#
|
35
|
-
def self.get_public_version
|
36
|
-
version = get_release_version
|
33
|
+
def self.get_public_version
|
34
|
+
version = get_release_version
|
37
35
|
vp = get_version_parts(version[VERSION_NAME])
|
38
36
|
return "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}" unless is_hotfix?(version)
|
39
37
|
|
@@ -42,12 +40,10 @@ module Fastlane
|
|
42
40
|
|
43
41
|
# Extract the version name and code from the release version of the app from `version.properties file`
|
44
42
|
#
|
45
|
-
# @param [String] product_name The name of the app to be used for beta and alpha version update
|
46
|
-
#
|
47
43
|
# @return [Hash] A hash with 2 keys "name" and "code" containing the extracted version name and code, respectively
|
48
44
|
#
|
49
|
-
def self.get_release_version
|
50
|
-
return get_version_from_properties(
|
45
|
+
def self.get_release_version
|
46
|
+
return get_version_from_properties() if File.exist?(version_properties_file)
|
51
47
|
|
52
48
|
section = ENV['HAS_ALPHA_VERSION'].nil? ? 'defaultConfig' : 'vanilla {'
|
53
49
|
gradle_path = self.gradle_path
|
@@ -56,66 +52,36 @@ module Fastlane
|
|
56
52
|
return { VERSION_NAME => name, VERSION_CODE => code }
|
57
53
|
end
|
58
54
|
|
59
|
-
def self.
|
60
|
-
|
61
|
-
|
62
|
-
return File.exist?(properties_file_path)
|
55
|
+
def self.version_properties_file
|
56
|
+
File.join(ENV['PROJECT_ROOT_FOLDER'] || '.', 'version.properties')
|
63
57
|
end
|
64
58
|
|
65
59
|
# Extract the version name and code from the `version.properties` file in the project root
|
66
60
|
#
|
67
|
-
# @param [String] product_name The name of the app to extract the version from e.g. wordpress, simplenote
|
68
61
|
# @param [Boolean] is_alpha true if the alpha version should be returned, false otherwise
|
69
62
|
#
|
70
63
|
# @return [Hash] A hash with 2 keys "name" and "code" containing the extracted version name and code, respectively
|
71
64
|
#
|
72
|
-
def self.get_version_from_properties(
|
73
|
-
|
74
|
-
version_name_key = [product_name, alpha_variant, 'versionName'].compact.join('.')
|
75
|
-
version_code_key = [product_name, alpha_variant, 'versionCode'].compact.join('.')
|
65
|
+
def self.get_version_from_properties(is_alpha: false)
|
66
|
+
return nil unless File.exist?(version_properties_file)
|
76
67
|
|
77
|
-
|
68
|
+
version_name_key = is_alpha ? 'alpha.versionName' : 'versionName'
|
69
|
+
version_code_key = is_alpha ? 'alpha.versionCode' : 'versionCode'
|
78
70
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
text = f.read
|
83
|
-
name = text.match(/#{version_name_key}=(\S*)/m)&.captures&.first
|
84
|
-
code = text.match(/#{version_code_key}=(\S*)/m)&.captures&.first
|
71
|
+
text = File.read(version_properties_file)
|
72
|
+
name = text.match(/#{version_name_key}=(\S*)/m)&.captures&.first
|
73
|
+
code = text.match(/#{version_code_key}=(\S*)/m)&.captures&.first
|
85
74
|
|
86
|
-
|
87
|
-
|
88
|
-
return nil if name.nil? || code.nil?
|
89
|
-
|
90
|
-
return { VERSION_NAME => name, VERSION_CODE => code.to_i }
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
# Returns the name of the flavor used for alpha builds
|
95
|
-
#
|
96
|
-
# @env HAS_ALPHA_VERSION Should contain the name of the flavor used for alpha
|
97
|
-
#
|
98
|
-
# @return [String] The flavor name as provided by the env var, defaulting to `zalpha` if the env var
|
99
|
-
# is not set or is set to '1' ('boolean' value used in legacy call sites)
|
100
|
-
def self.alpha_flavor_name
|
101
|
-
# TODO: Have each fastlane action which depends on this take the alpha flavor name as ConfigItem/parameter
|
102
|
-
# explicitly instead (and get rid of the HAS_ALPHA_VERSION global / env var after that)
|
103
|
-
|
104
|
-
# For now we pass the alpha flavor name by reusing the HAS_ALPHA_VERSION env var.
|
105
|
-
return ENV['HAS_ALPHA_VERSION'] if ENV['HAS_ALPHA_VERSION'] && ENV['HAS_ALPHA_VERSION'] != '1'
|
106
|
-
|
107
|
-
'zalpha' # Default value if HAS_ALPHA_VERSION is not set or hasn't been updated at call site to the flavor name instead of '1'
|
75
|
+
return name.nil? || code.nil? ? nil : { VERSION_NAME => name, VERSION_CODE => code.to_i }
|
108
76
|
end
|
109
77
|
|
110
78
|
# Extract the version name and code from the `version.properties` file in the project root
|
111
79
|
#
|
112
|
-
# @param [String] app The name of the app to be used for beta and alpha version update
|
113
|
-
#
|
114
80
|
# @return [Hash] A hash with 2 keys `"name"` and `"code"` containing the extracted version name and code, respectively,
|
115
81
|
# or `nil` if `$HAS_ALPHA_VERSION` is not defined.
|
116
82
|
#
|
117
|
-
def self.get_alpha_version
|
118
|
-
return get_version_from_properties(
|
83
|
+
def self.get_alpha_version
|
84
|
+
return get_version_from_properties(is_alpha: true) if File.exist?(version_properties_file)
|
119
85
|
|
120
86
|
return nil if ENV['HAS_ALPHA_VERSION'].nil?
|
121
87
|
|
@@ -312,12 +278,11 @@ module Fastlane
|
|
312
278
|
|
313
279
|
# Prints the current and next release version names to stdout, then returns the next release version
|
314
280
|
#
|
315
|
-
# @param [String] app The name of the app to be used for beta and alpha version update
|
316
281
|
# @return [String] The next release version name to use after bumping the currently used release version.
|
317
282
|
#
|
318
|
-
def self.bump_version_release
|
283
|
+
def self.bump_version_release
|
319
284
|
# Bump release
|
320
|
-
current_version = get_release_version
|
285
|
+
current_version = self.get_release_version
|
321
286
|
UI.message("Current version: #{current_version[VERSION_NAME]}")
|
322
287
|
new_version = calc_next_release_base_version(current_version)
|
323
288
|
UI.message("New version: #{new_version[VERSION_NAME]}")
|
@@ -328,24 +293,24 @@ module Fastlane
|
|
328
293
|
|
329
294
|
# Update the `version.properties` file with new `versionName` and `versionCode` values
|
330
295
|
#
|
331
|
-
# @param [String] app The name of the app to be used for beta and alpha version update
|
332
296
|
# @param [Hash] new_version_beta The version hash for the beta, containing values for keys "name" and "code"
|
333
297
|
# @param [Hash] new_version_alpha The version hash for the alpha , containing values for keys "name" and "code"
|
334
298
|
#
|
335
|
-
def self.update_versions(
|
336
|
-
if
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
299
|
+
def self.update_versions(new_version_beta, new_version_alpha)
|
300
|
+
if File.exist?(version_properties_file)
|
301
|
+
replacements = {
|
302
|
+
versionName: (new_version_beta || {})[VERSION_NAME],
|
303
|
+
versionCode: (new_version_beta || {})[VERSION_CODE],
|
304
|
+
'alpha.versionName': (new_version_alpha || {})[VERSION_NAME],
|
305
|
+
'alpha.versionCode': (new_version_alpha || {})[VERSION_CODE]
|
306
|
+
}
|
307
|
+
content = File.read(version_properties_file)
|
308
|
+
content.gsub!(/^(.*) ?=.*$/) do |line|
|
309
|
+
key = Regexp.last_match(1).to_sym
|
310
|
+
value = replacements[key]
|
311
|
+
value.nil? ? line : "#{key}=#{value}"
|
348
312
|
end
|
313
|
+
File.write(version_properties_file, content)
|
349
314
|
else
|
350
315
|
self.update_version(new_version_beta, ENV['HAS_ALPHA_VERSION'].nil? ? 'defaultConfig' : 'vanilla {')
|
351
316
|
self.update_version(new_version_alpha, 'defaultConfig') unless new_version_alpha.nil?
|
@@ -434,7 +399,7 @@ module Fastlane
|
|
434
399
|
#
|
435
400
|
# @return [Bool] true if the string is representing an integer value, false if not
|
436
401
|
#
|
437
|
-
def self.is_int?
|
402
|
+
def self.is_int?(string)
|
438
403
|
true if Integer(string) rescue false
|
439
404
|
end
|
440
405
|
|
@@ -36,7 +36,9 @@ module Fastlane
|
|
36
36
|
while continue
|
37
37
|
child_filenames = dir.children.map! { |x| File.basename(x) }
|
38
38
|
|
39
|
-
|
39
|
+
# The first case is for development – where the `.gemspec` is present in the project root
|
40
|
+
# The second case is for production – where there's no `.gemspec`, but the root dir of the plugin is named `fastlane-plugin-wpmreleasetoolkit-{version}`.
|
41
|
+
if child_filenames.include?('fastlane-plugin-wpmreleasetoolkit.gemspec') || File.basename(dir).start_with?('fastlane-plugin-wpmreleasetoolkit-')
|
40
42
|
continue = false
|
41
43
|
else
|
42
44
|
dir = dir.parent
|
@@ -1,23 +1,37 @@
|
|
1
1
|
require 'fastlane_core/ui/ui'
|
2
2
|
require 'octokit'
|
3
3
|
require 'open-uri'
|
4
|
+
require 'securerandom'
|
4
5
|
|
5
6
|
module Fastlane
|
6
7
|
UI = FastlaneCore::UI unless Fastlane.const_defined?('UI')
|
7
8
|
|
8
9
|
module Helper
|
9
10
|
class GithubHelper
|
11
|
+
def self.github_token!
|
12
|
+
token = [
|
13
|
+
'GHHELPER_ACCESS', # For historical reasons / backward compatibility
|
14
|
+
'GITHUB_TOKEN', # Used by the `gh` CLI tool
|
15
|
+
].map { |key| ENV[key] }
|
16
|
+
.compact
|
17
|
+
.first
|
18
|
+
|
19
|
+
token || UI.user_error!('Please provide a GitHub authentication token via the `GITHUB_TOKEN` environment variable')
|
20
|
+
end
|
21
|
+
|
10
22
|
def self.github_client
|
11
|
-
client
|
23
|
+
@@client ||= begin
|
24
|
+
client = Octokit::Client.new(access_token: github_token!)
|
12
25
|
|
13
|
-
|
14
|
-
|
15
|
-
|
26
|
+
# Fetch the current user
|
27
|
+
user = client.user
|
28
|
+
UI.message("Logged in as: #{user.name}")
|
16
29
|
|
17
|
-
|
18
|
-
|
30
|
+
# Auto-paginate to ensure we're not missing data
|
31
|
+
client.auto_paginate = true
|
19
32
|
|
20
|
-
|
33
|
+
client
|
34
|
+
end
|
21
35
|
end
|
22
36
|
|
23
37
|
def self.get_milestone(repository, release)
|
@@ -117,8 +131,11 @@ module Fastlane
|
|
117
131
|
file_name = File.basename(file_path)
|
118
132
|
download_path = File.join(download_folder, file_name)
|
119
133
|
|
134
|
+
download_url = github_client.contents(repository,
|
135
|
+
path: file_path,
|
136
|
+
ref: tag).download_url
|
120
137
|
begin
|
121
|
-
uri = URI.parse(
|
138
|
+
uri = URI.parse(download_url)
|
122
139
|
uri.open do |remote_file|
|
123
140
|
File.write(download_path, remote_file.read)
|
124
141
|
end
|
@@ -128,6 +145,29 @@ module Fastlane
|
|
128
145
|
|
129
146
|
download_path
|
130
147
|
end
|
148
|
+
|
149
|
+
# Creates (or updates an existing) GitHub PR Comment
|
150
|
+
def self.comment_on_pr(project_slug:, pr_number:, body:, reuse_identifier: SecureRandom.uuid)
|
151
|
+
client = github_client
|
152
|
+
comments = client.issue_comments(project_slug, pr_number)
|
153
|
+
|
154
|
+
reuse_marker = "<!-- REUSE_ID: #{reuse_identifier} -->"
|
155
|
+
|
156
|
+
existing_comment = comments.find do |comment|
|
157
|
+
# Only match comments posted by the owner of the GitHub Token, and with the given reuse ID
|
158
|
+
comment.user.id == client.user.id and comment.body.include?(reuse_marker)
|
159
|
+
end
|
160
|
+
|
161
|
+
comment_body = reuse_marker + body
|
162
|
+
|
163
|
+
if existing_comment.nil?
|
164
|
+
client.add_comment(project_slug, pr_number, comment_body)
|
165
|
+
else
|
166
|
+
client.update_comment(project_slug, existing_comment.id, comment_body)
|
167
|
+
end
|
168
|
+
|
169
|
+
reuse_identifier
|
170
|
+
end
|
131
171
|
end
|
132
172
|
end
|
133
173
|
end
|