Class: Fastlane::Actions::AnalyzeCommitsAction
- Inherits:
-
Action
- Object
- Action
- Fastlane::Actions::AnalyzeCommitsAction
- Defined in:
- lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb
Documentation collapse
- .authors ⇒ Object
- .available_options ⇒ Object
- .description ⇒ Object
- .details ⇒ Object
- .is_supported?(platform) ⇒ Boolean
- .output ⇒ Object
- .return_value ⇒ Object
Class Method Summary collapse
- .get_commits_from_hash(params) ⇒ Object
- .get_last_tag(params) ⇒ Object
- .get_last_tag_hash(params) ⇒ Object
- .is_codepush_friendly(params) ⇒ Object
- .is_releasable(params) ⇒ Object
- .run(params) ⇒ Object
Class Method Details
.authors ⇒ Object
331 332 333 334 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 331 def self. # So no one will ever forget your contribution to fastlane :) You are awesome btw! ["xotahal"] end |
.available_options ⇒ Object
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 233 def self. # Define all options your action supports. # Below a few examples [ FastlaneCore::ConfigItem.new( key: :match, description: "Match parameter of git describe. See man page of git describe for more info", verify_block: proc do |value| UI.user_error!("No match for analyze_commits action given, pass using `match: 'expr'`") unless value && !value.empty? end ), FastlaneCore::ConfigItem.new( key: :commit_format, 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", default_value: "default", is_string: false, verify_block: proc do |value| case value when String unless Helper::SemanticReleaseHelper.format_patterns.key?(value) UI.user_error!("Invalid format preset: #{value}") end pattern = Helper::SemanticReleaseHelper.format_patterns[value] when Regexp pattern = value else UI.user_error!("Invalid option type: #{value.inspect}") end Actions.lane_context[SharedValues::CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN] = pattern end ), FastlaneCore::ConfigItem.new( key: :releases, description: "Map types of commit to release (major, minor, patch)", default_value: { fix: "patch", feat: "minor" }, type: Hash ), FastlaneCore::ConfigItem.new( key: :codepush_friendly, description: "These types are consider as codepush friendly automatically", default_value: ["chore", "test", "docs"], type: Array, optional: true ), FastlaneCore::ConfigItem.new( key: :tag_version_match, description: "To parse version number from tag name", default_value: '\d+\.\d+\.\d+' ), FastlaneCore::ConfigItem.new( key: :ignore_scopes, description: "To ignore certain scopes when calculating releases", default_value: [], type: Array, optional: true ), FastlaneCore::ConfigItem.new( key: :show_version_path, description: "True if you want to print out the version calculated for each commit", default_value: true, type: Boolean, optional: true ), FastlaneCore::ConfigItem.new( key: :debug, description: "True if you want to log out a debug info", default_value: false, type: Boolean, optional: true ) ] end |
.description ⇒ Object
225 226 227 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 225 def self.description "Finds a tag of last release and determinates version of next release" end |
.details ⇒ Object
229 230 231 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 229 def self.details "This action will find a last release tag and analyze all commits since the tag. It uses conventional commits. Every time when commit is marked as fix or feat it will increase patch or minor number (you can setup this default behaviour). After all it will suggest if the version should be released or not." end |
.get_commits_from_hash(params) ⇒ Object
35 36 37 38 39 40 41 42 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 35 def self.get_commits_from_hash(params) commits = Helper::SemanticReleaseHelper.git_log( pretty: '%s|%b|>', start: params[:hash], debug: params[:debug] ) commits.split("|>") end |
.get_last_tag(params) ⇒ Object
21 22 23 24 25 26 27 28 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 21 def self.get_last_tag(params) # Try to find the tag command = "git describe --tags --match=#{params[:match]}" Actions.sh(command, log: params[:debug]) rescue UI.("Tag was not found for match pattern - #{params[:match]}") '' end |
.get_last_tag_hash(params) ⇒ Object
30 31 32 33 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 30 def self.get_last_tag_hash(params) command = "git rev-list -n 1 refs/tags/#{params[:tag_name]}" Actions.sh(command, log: params[:debug]).chomp end |
.is_codepush_friendly(params) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 158 def self.is_codepush_friendly(params) git_command = 'git rev-list --max-parents=0 HEAD' # Begining of the branch is taken for codepush analysis hash_lines = Actions.sh("#{git_command} | wc -l", log: params[:debug]).chomp hash = Actions.sh(git_command, log: params[:debug]).chomp next_major = 0 next_minor = 0 next_patch = 0 last_incompatible_codepush_version = '0.0.0' if hash_lines.to_i > 1 UI.error("#{git_command} resulted to more than 1 hash") UI.error('This usualy happens when you pull only part of a git history. Check out how you pull the repo! "git fetch" should be enough.') Actions.sh(git_command, log: true).chomp return false end # Get commits log between last version and head splitted = get_commits_from_hash( hash: hash, debug: params[:debug] ) releases = params[:releases] codepush_friendly = params[:codepush_friendly] format_pattern = lane_context[SharedValues::CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN] splitted.each do |line| # conventional commits are in format # type: subject (fix: app crash - for example) commit = Helper::SemanticReleaseHelper.parse_commit( commit_subject: line.split("|")[0], commit_body: line.split("|")[1], releases: releases, pattern: format_pattern, codepush_friendly: codepush_friendly ) if commit[:release] == "major" || commit[:is_breaking_change] next_major += 1 next_minor = 0 next_patch = 0 elsif commit[:release] == "minor" next_minor += 1 next_patch = 0 elsif commit[:release] == "patch" next_patch += 1 end unless commit[:is_codepush_friendly] last_incompatible_codepush_version = "#{next_major}.#{next_minor}.#{next_patch}" end end Actions.lane_context[SharedValues::RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION] = last_incompatible_codepush_version end |
.is_releasable(params) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 44 def self.is_releasable(params) # Hash of the commit where is the last version # If the tag is not found we are taking HEAD as reference hash = 'HEAD' # Default last version version = '0.0.0' tag = get_last_tag( match: params[:match], debug: params[:debug] ) if tag.empty? UI.("First commit of the branch is taken as a begining of next release") # If there is no tag found we taking the first commit of current branch hash = Actions.sh('git rev-list --max-parents=0 HEAD', log: params[:debug]).chomp else # Tag's format is v2.3.4-5-g7685948 # See git describe man page for more info tag_name = tag.split('-')[0...-2].join('-').strip parsed_version = tag_name.match(params[:tag_version_match]) if parsed_version.nil? 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.") end version = parsed_version[0] # Get a hash of last version tag hash = get_last_tag_hash( tag_name: tag_name, debug: params[:debug] ) UI.("Found a tag #{tag_name} associated with version #{version}") end # converts last version string to the int numbers next_major = (version.split('.')[0] || 0).to_i next_minor = (version.split('.')[1] || 0).to_i next_patch = (version.split('.')[2] || 0).to_i is_next_version_compatible_with_codepush = true # Get commits log between last version and head splitted = get_commits_from_hash( hash: hash, debug: params[:debug] ) UI.("Found #{splitted.length} commits since last release") releases = params[:releases] format_pattern = lane_context[SharedValues::CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN] splitted.each do |line| parts = line.split("|") subject = parts[0].strip # conventional commits are in format # type: subject (fix: app crash - for example) commit = Helper::SemanticReleaseHelper.parse_commit( commit_subject: subject, commit_body: parts[1], releases: releases, pattern: format_pattern ) unless commit[:scope].nil? # 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 scope = commit[:scope] scopes_to_ignore = params[:ignore_scopes] # if it is, we'll skip this commit when bumping versions next if scopes_to_ignore.include?(scope) #=> true end if commit[:release] == "major" || commit[:is_breaking_change] next_major += 1 next_minor = 0 next_patch = 0 elsif commit[:release] == "minor" next_minor += 1 next_patch = 0 elsif commit[:release] == "patch" next_patch += 1 end unless commit[:is_codepush_friendly] is_next_version_compatible_with_codepush = false end next_version = "#{next_major}.#{next_minor}.#{next_patch}" UI.("#{next_version}: #{subject}") if params[:show_version_path] end next_version = "#{next_major}.#{next_minor}.#{next_patch}" is_next_version_releasable = Helper::SemanticReleaseHelper.semver_gt(next_version, version) Actions.lane_context[SharedValues::RELEASE_ANALYZED] = true Actions.lane_context[SharedValues::RELEASE_IS_NEXT_VERSION_HIGHER] = is_next_version_releasable Actions.lane_context[SharedValues::RELEASE_IS_NEXT_VERSION_COMPATIBLE_WITH_CODEPUSH] = is_next_version_compatible_with_codepush # Last release analysis Actions.lane_context[SharedValues::RELEASE_LAST_TAG_HASH] = hash Actions.lane_context[SharedValues::RELEASE_LAST_VERSION] = version # Next release analysis Actions.lane_context[SharedValues::RELEASE_NEXT_MAJOR_VERSION] = next_major Actions.lane_context[SharedValues::RELEASE_NEXT_MINOR_VERSION] = next_minor Actions.lane_context[SharedValues::RELEASE_NEXT_PATCH_VERSION] = next_patch Actions.lane_context[SharedValues::RELEASE_NEXT_VERSION] = next_version = "Next version (#{next_version}) is higher than last version (#{version}). This version should be released." UI.success() if is_next_version_releasable is_next_version_releasable end |
.is_supported?(platform) ⇒ Boolean
336 337 338 339 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 336 def self.is_supported?(platform) # you can do things like true end |
.output ⇒ Object
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 308 def self.output # Define the shared values you are going to provide # Example [ ['RELEASE_ANALYZED', 'True if commits were analyzed.'], ['RELEASE_IS_NEXT_VERSION_HIGHER', 'True if next version is higher then last version'], ['RELEASE_IS_NEXT_VERSION_COMPATIBLE_WITH_CODEPUSH', 'True if next version is compatible with codepush'], ['RELEASE_LAST_TAG_HASH', 'Hash of commit that is tagged as a last version'], ['RELEASE_LAST_VERSION', 'Last version number - parsed from last tag.'], ['RELEASE_NEXT_MAJOR_VERSION', 'Major number of the next version'], ['RELEASE_NEXT_MINOR_VERSION', 'Minor number of the next version'], ['RELEASE_NEXT_PATCH_VERSION', 'Patch number of the next version'], ['RELEASE_NEXT_VERSION', 'Next version string in format (major.minor.patch)'], ['RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION', 'Last commit without codepush'], ['CONVENTIONAL_CHANGELOG_ACTION_FORMAT_PATTERN', 'The format pattern Regexp used to match commits (mainly for internal use)'] ] end |
.return_value ⇒ Object
326 327 328 329 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 326 def self.return_value # If your method provides a return value, you can describe here what it does "Returns true if the next version is higher then the last version" end |
.run(params) ⇒ Object
214 215 216 217 218 219 |
# File 'lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb', line 214 def self.run(params) is_next_version_releasable = is_releasable(params) is_codepush_friendly(params) is_next_version_releasable end |