fastlane-plugin-semantic_release 1.9.2 → 1.14.1
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/semantic_release/actions/analyze_commits.rb +111 -32
- data/lib/fastlane/plugin/semantic_release/actions/conventional_changelog.rb +20 -3
- data/lib/fastlane/plugin/semantic_release/helper/semantic_release_helper.rb +11 -4
- data/lib/fastlane/plugin/semantic_release/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 75df4d8576b964aa25eb049f7327b6dca63e183e6ed2ee338a9bed8c52364c35
|
4
|
+
data.tar.gz: '08f19dc2c0343275cd8ad6df77e34c3cead327543beaab51ed6211005466977a'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1fe944d2e2bb270c994d168fd5c0df781b425e7e92d53535f98fd13b72eb86d153ac76800374453769653ebc14359dcf9ca0db77858361a1b53661705f5b187d
|
7
|
+
data.tar.gz: 3eff9484e9f5d5bef71a0a8252daa782a9301401886371516a8c3bb041bd137413bf49defaccdabee5477aa18313b800cced10745a4edd790539ae5e5cee0fed
|
@@ -6,6 +6,7 @@ module Fastlane
|
|
6
6
|
module SharedValues
|
7
7
|
RELEASE_ANALYZED = :RELEASE_ANALYZED
|
8
8
|
RELEASE_IS_NEXT_VERSION_HIGHER = :RELEASE_IS_NEXT_VERSION_HIGHER
|
9
|
+
RELEASE_IS_NEXT_VERSION_COMPATIBLE_WITH_CODEPUSH = :RELEASE_IS_NEXT_VERSION_COMPATIBLE_WITH_CODEPUSH
|
9
10
|
RELEASE_LAST_TAG_HASH = :RELEASE_LAST_TAG_HASH
|
10
11
|
RELEASE_LAST_VERSION = :RELEASE_LAST_VERSION
|
11
12
|
RELEASE_NEXT_MAJOR_VERSION = :RELEASE_NEXT_MAJOR_VERSION
|
@@ -13,6 +14,7 @@ module Fastlane
|
|
13
14
|
RELEASE_NEXT_PATCH_VERSION = :RELEASE_NEXT_PATCH_VERSION
|
14
15
|
RELEASE_NEXT_VERSION = :RELEASE_NEXT_VERSION
|
15
16
|
RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION = :RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION
|
17
|
+
CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN = :CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN
|
16
18
|
end
|
17
19
|
|
18
20
|
class AnalyzeCommitsAction < Action
|
@@ -39,47 +41,83 @@ module Fastlane
|
|
39
41
|
commits.split("|>")
|
40
42
|
end
|
41
43
|
|
42
|
-
def self.
|
43
|
-
#
|
44
|
-
|
45
|
-
hash = 'HEAD'
|
46
|
-
# Default last version
|
47
|
-
version = '0.0.0'
|
44
|
+
def self.get_beginning_of_next_sprint(params)
|
45
|
+
# command to get first commit
|
46
|
+
git_command = 'git rev-list --max-parents=0 HEAD'
|
48
47
|
|
49
|
-
tag = get_last_tag(
|
50
|
-
match: params[:match],
|
51
|
-
debug: params[:debug]
|
52
|
-
)
|
48
|
+
tag = get_last_tag(match: params[:match], debug: params[:debug])
|
53
49
|
|
50
|
+
# if tag doesn't exist it get's first commit or fallback tag (v*.*.*)
|
54
51
|
if tag.empty?
|
55
|
-
UI.message("
|
52
|
+
UI.message("It couldn't match tag for #{params[:match]}. Check if first commit can be taken as a beginning of next release")
|
56
53
|
# If there is no tag found we taking the first commit of current branch
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
UI.user_error!("Error while parsing version from tag #{tag_name} by using tag_version_match - #{params[:tag_version_match]}. Please check if the tag contains version as you expect and if you are using single brackets for tag_version_match parameter.")
|
54
|
+
hash_lines = Actions.sh("#{git_command} | wc -l", log: params[:debug]).chomp
|
55
|
+
|
56
|
+
if hash_lines.to_i == 1
|
57
|
+
UI.message("First commit of the branch is taken as a begining of next release")
|
58
|
+
return {
|
59
|
+
# here we know this command will return 1 line
|
60
|
+
hash: Actions.sh(git_command, log: params[:debug]).chomp
|
61
|
+
}
|
66
62
|
end
|
67
63
|
|
68
|
-
|
69
|
-
#
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
64
|
+
# neighter matched tag and first hash could be used - as fallback we try vX.Y.Z
|
65
|
+
UI.message("It couldn't match tag for #{params[:match]} and couldn't use first commit. Check if tag vX.Y.Z can be taken as a begining of next release")
|
66
|
+
tag = get_last_tag(match: "v*", debug: params[:debug])
|
67
|
+
|
68
|
+
# even fallback tag doesn't work
|
69
|
+
if tag.empty?
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
end
|
74
73
|
|
75
|
-
|
74
|
+
# Tag's format is v2.3.4-5-g7685948
|
75
|
+
# See git describe man page for more info
|
76
|
+
tag_name = tag.split('-')[0...-2].join('-').strip
|
77
|
+
parsed_version = tag_name.match(params[:tag_version_match])
|
78
|
+
|
79
|
+
if parsed_version.nil?
|
80
|
+
UI.user_error!("Error while parsing version from tag #{tag_name} by using tag_version_match - #{params[:tag_version_match]}. Please check if the tag contains version as you expect and if you are using single brackets for tag_version_match parameter.")
|
76
81
|
end
|
77
82
|
|
83
|
+
version = parsed_version[0]
|
84
|
+
# Get a hash of last version tag
|
85
|
+
hash = get_last_tag_hash(
|
86
|
+
tag_name: tag_name,
|
87
|
+
debug: params[:debug]
|
88
|
+
)
|
89
|
+
|
90
|
+
UI.message("Found a tag #{tag_name} associated with version #{version}")
|
91
|
+
|
92
|
+
return {
|
93
|
+
hash: hash,
|
94
|
+
version: version
|
95
|
+
}
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.is_releasable(params)
|
99
|
+
# Hash of the commit where is the last version
|
100
|
+
beginning = get_beginning_of_next_sprint(params)
|
101
|
+
|
102
|
+
unless beginning
|
103
|
+
UI.error('It could not find a begining of this sprint. How to fix this:')
|
104
|
+
UI.error('-- ensure there is only one commit with --max-parents=0 (this command should return one line: "git rev-list --max-parents=0 HEAD")')
|
105
|
+
UI.error('-- tell us explicitely where the release starts by adding tag like this: vX.Y.Z (where X.Y.Z is version from which it starts computing next version number)')
|
106
|
+
return false
|
107
|
+
end
|
108
|
+
|
109
|
+
# Default last version
|
110
|
+
version = beginning[:version] || '0.0.0'
|
111
|
+
# If the tag is not found we are taking HEAD as reference
|
112
|
+
hash = beginning[:hash] || 'HEAD'
|
113
|
+
|
78
114
|
# converts last version string to the int numbers
|
79
115
|
next_major = (version.split('.')[0] || 0).to_i
|
80
116
|
next_minor = (version.split('.')[1] || 0).to_i
|
81
117
|
next_patch = (version.split('.')[2] || 0).to_i
|
82
118
|
|
119
|
+
is_next_version_compatible_with_codepush = true
|
120
|
+
|
83
121
|
# Get commits log between last version and head
|
84
122
|
splitted = get_commits_from_hash(
|
85
123
|
hash: hash,
|
@@ -89,13 +127,17 @@ module Fastlane
|
|
89
127
|
UI.message("Found #{splitted.length} commits since last release")
|
90
128
|
releases = params[:releases]
|
91
129
|
|
130
|
+
format_pattern = lane_context[SharedValues::CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN]
|
92
131
|
splitted.each do |line|
|
132
|
+
parts = line.split("|")
|
133
|
+
subject = parts[0].strip
|
93
134
|
# conventional commits are in format
|
94
135
|
# type: subject (fix: app crash - for example)
|
95
136
|
commit = Helper::SemanticReleaseHelper.parse_commit(
|
96
|
-
commit_subject:
|
97
|
-
commit_body:
|
98
|
-
releases: releases
|
137
|
+
commit_subject: subject,
|
138
|
+
commit_body: parts[1],
|
139
|
+
releases: releases,
|
140
|
+
pattern: format_pattern
|
99
141
|
)
|
100
142
|
|
101
143
|
unless commit[:scope].nil?
|
@@ -117,8 +159,12 @@ module Fastlane
|
|
117
159
|
next_patch += 1
|
118
160
|
end
|
119
161
|
|
162
|
+
unless commit[:is_codepush_friendly]
|
163
|
+
is_next_version_compatible_with_codepush = false
|
164
|
+
end
|
165
|
+
|
120
166
|
next_version = "#{next_major}.#{next_minor}.#{next_patch}"
|
121
|
-
UI.message("#{next_version}: #{
|
167
|
+
UI.message("#{next_version}: #{subject}") if params[:show_version_path]
|
122
168
|
end
|
123
169
|
|
124
170
|
next_version = "#{next_major}.#{next_minor}.#{next_patch}"
|
@@ -127,6 +173,7 @@ module Fastlane
|
|
127
173
|
|
128
174
|
Actions.lane_context[SharedValues::RELEASE_ANALYZED] = true
|
129
175
|
Actions.lane_context[SharedValues::RELEASE_IS_NEXT_VERSION_HIGHER] = is_next_version_releasable
|
176
|
+
Actions.lane_context[SharedValues::RELEASE_IS_NEXT_VERSION_COMPATIBLE_WITH_CODEPUSH] = is_next_version_compatible_with_codepush
|
130
177
|
# Last release analysis
|
131
178
|
Actions.lane_context[SharedValues::RELEASE_LAST_TAG_HASH] = hash
|
132
179
|
Actions.lane_context[SharedValues::RELEASE_LAST_VERSION] = version
|
@@ -167,6 +214,7 @@ module Fastlane
|
|
167
214
|
releases = params[:releases]
|
168
215
|
codepush_friendly = params[:codepush_friendly]
|
169
216
|
|
217
|
+
format_pattern = lane_context[SharedValues::CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN]
|
170
218
|
splitted.each do |line|
|
171
219
|
# conventional commits are in format
|
172
220
|
# type: subject (fix: app crash - for example)
|
@@ -174,6 +222,7 @@ module Fastlane
|
|
174
222
|
commit_subject: line.split("|")[0],
|
175
223
|
commit_body: line.split("|")[1],
|
176
224
|
releases: releases,
|
225
|
+
pattern: format_pattern,
|
177
226
|
codepush_friendly: codepush_friendly
|
178
227
|
)
|
179
228
|
|
@@ -227,6 +276,27 @@ module Fastlane
|
|
227
276
|
UI.user_error!("No match for analyze_commits action given, pass using `match: 'expr'`") unless value && !value.empty?
|
228
277
|
end
|
229
278
|
),
|
279
|
+
FastlaneCore::ConfigItem.new(
|
280
|
+
key: :commit_format,
|
281
|
+
description: "The commit format to apply. Presets are 'default' or 'angular', or you can provide your own Regexp. Note: the supplied regex _must_ have 4 capture groups, in order: type, scope, has_exclamation_mark, and subject",
|
282
|
+
default_value: "default",
|
283
|
+
is_string: false,
|
284
|
+
verify_block: proc do |value|
|
285
|
+
case value
|
286
|
+
when String
|
287
|
+
unless Helper::SemanticReleaseHelper.format_patterns.key?(value)
|
288
|
+
UI.user_error!("Invalid format preset: #{value}")
|
289
|
+
end
|
290
|
+
|
291
|
+
pattern = Helper::SemanticReleaseHelper.format_patterns[value]
|
292
|
+
when Regexp
|
293
|
+
pattern = value
|
294
|
+
else
|
295
|
+
UI.user_error!("Invalid option type: #{value.inspect}")
|
296
|
+
end
|
297
|
+
Actions.lane_context[SharedValues::CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN] = pattern
|
298
|
+
end
|
299
|
+
),
|
230
300
|
FastlaneCore::ConfigItem.new(
|
231
301
|
key: :releases,
|
232
302
|
description: "Map types of commit to release (major, minor, patch)",
|
@@ -252,6 +322,13 @@ module Fastlane
|
|
252
322
|
type: Array,
|
253
323
|
optional: true
|
254
324
|
),
|
325
|
+
FastlaneCore::ConfigItem.new(
|
326
|
+
key: :show_version_path,
|
327
|
+
description: "True if you want to print out the version calculated for each commit",
|
328
|
+
default_value: true,
|
329
|
+
type: Boolean,
|
330
|
+
optional: true
|
331
|
+
),
|
255
332
|
FastlaneCore::ConfigItem.new(
|
256
333
|
key: :debug,
|
257
334
|
description: "True if you want to log out a debug info",
|
@@ -268,13 +345,15 @@ module Fastlane
|
|
268
345
|
[
|
269
346
|
['RELEASE_ANALYZED', 'True if commits were analyzed.'],
|
270
347
|
['RELEASE_IS_NEXT_VERSION_HIGHER', 'True if next version is higher then last version'],
|
348
|
+
['RELEASE_IS_NEXT_VERSION_COMPATIBLE_WITH_CODEPUSH', 'True if next version is compatible with codepush'],
|
271
349
|
['RELEASE_LAST_TAG_HASH', 'Hash of commit that is tagged as a last version'],
|
272
350
|
['RELEASE_LAST_VERSION', 'Last version number - parsed from last tag.'],
|
273
351
|
['RELEASE_NEXT_MAJOR_VERSION', 'Major number of the next version'],
|
274
352
|
['RELEASE_NEXT_MINOR_VERSION', 'Minor number of the next version'],
|
275
353
|
['RELEASE_NEXT_PATCH_VERSION', 'Patch number of the next version'],
|
276
354
|
['RELEASE_NEXT_VERSION', 'Next version string in format (major.minor.patch)'],
|
277
|
-
['RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION', 'Last commit without codepush']
|
355
|
+
['RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION', 'Last commit without codepush'],
|
356
|
+
['CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN', 'The format pattern Regexp used to match commits (mainly for internal use)']
|
278
357
|
]
|
279
358
|
end
|
280
359
|
|
@@ -35,7 +35,7 @@ module Fastlane
|
|
35
35
|
hash: last_tag_hash,
|
36
36
|
debug: params[:debug]
|
37
37
|
)
|
38
|
-
parsed = parse_commits(commits)
|
38
|
+
parsed = parse_commits(commits, params)
|
39
39
|
|
40
40
|
commit_url = params[:commit_url]
|
41
41
|
format = params[:format]
|
@@ -172,17 +172,27 @@ module Fastlane
|
|
172
172
|
end
|
173
173
|
end
|
174
174
|
|
175
|
-
def self.parse_commits(commits)
|
175
|
+
def self.parse_commits(commits, params)
|
176
176
|
parsed = []
|
177
177
|
# %s|%b|%H|%h|%an|%at
|
178
|
+
format_pattern = lane_context[SharedValues::CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN]
|
178
179
|
commits.each do |line|
|
179
180
|
splitted = line.split("|")
|
180
181
|
|
181
182
|
commit = Helper::SemanticReleaseHelper.parse_commit(
|
182
183
|
commit_subject: splitted[0],
|
183
|
-
commit_body: splitted[1]
|
184
|
+
commit_body: splitted[1],
|
185
|
+
pattern: format_pattern
|
184
186
|
)
|
185
187
|
|
188
|
+
unless commit[:scope].nil?
|
189
|
+
# if this commit has a scope, then we need to inspect to see if that is one of the scopes we're trying to exclude
|
190
|
+
scope = commit[:scope]
|
191
|
+
scopes_to_ignore = params[:ignore_scopes]
|
192
|
+
# if it is, we'll skip this commit when bumping versions
|
193
|
+
next if scopes_to_ignore.include?(scope) #=> true
|
194
|
+
end
|
195
|
+
|
186
196
|
commit[:hash] = splitted[2]
|
187
197
|
commit[:short_hash] = splitted[3]
|
188
198
|
commit[:author_name] = splitted[4]
|
@@ -271,6 +281,13 @@ module Fastlane
|
|
271
281
|
type: Boolean,
|
272
282
|
optional: true
|
273
283
|
),
|
284
|
+
FastlaneCore::ConfigItem.new(
|
285
|
+
key: :ignore_scopes,
|
286
|
+
description: "To ignore certain scopes when calculating releases",
|
287
|
+
default_value: [],
|
288
|
+
type: Array,
|
289
|
+
optional: true
|
290
|
+
),
|
274
291
|
FastlaneCore::ConfigItem.new(
|
275
292
|
key: :debug,
|
276
293
|
description: "True if you want to log out a debug info",
|
@@ -5,6 +5,13 @@ module Fastlane
|
|
5
5
|
|
6
6
|
module Helper
|
7
7
|
class SemanticReleaseHelper
|
8
|
+
def self.format_patterns
|
9
|
+
return {
|
10
|
+
"default" => /^(docs|fix|feat|chore|style|refactor|perf|test)(?:\((.*)\))?(!?)\: (.*)/,
|
11
|
+
"angular" => /^(\w*)(?:\((.*)\))?(): (.*)/
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
8
15
|
# class methods that you define here become available in your action
|
9
16
|
# as `Helper::SemanticReleaseHelper.your_method`
|
10
17
|
#
|
@@ -18,7 +25,7 @@ module Fastlane
|
|
18
25
|
commit_body = params[:commit_body]
|
19
26
|
releases = params[:releases]
|
20
27
|
codepush_friendly = params[:codepush_friendly]
|
21
|
-
pattern =
|
28
|
+
pattern = params[:pattern]
|
22
29
|
breaking_change_pattern = /BREAKING CHANGES?: (.*)/
|
23
30
|
codepush_pattern = /codepush?: (.*)/
|
24
31
|
|
@@ -32,13 +39,13 @@ module Fastlane
|
|
32
39
|
|
33
40
|
unless matched.nil?
|
34
41
|
type = matched[1]
|
35
|
-
scope = matched[
|
42
|
+
scope = matched[2]
|
36
43
|
|
37
44
|
result[:is_valid] = true
|
38
45
|
result[:type] = type
|
39
46
|
result[:scope] = scope
|
40
|
-
result[:has_exclamation_mark] = matched[
|
41
|
-
result[:subject] = matched[
|
47
|
+
result[:has_exclamation_mark] = matched[3] == '!'
|
48
|
+
result[:subject] = matched[4]
|
42
49
|
|
43
50
|
unless releases.nil?
|
44
51
|
result[:release] = releases[type.to_sym]
|
@@ -1 +1 @@
|
|
1
|
-
module Fastlane module SemanticRelease VERSION = "1.
|
1
|
+
module Fastlane module SemanticRelease VERSION = "1.14.1" end end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-semantic_release
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.14.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jiří Otáhal
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|