Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add single step mode #23

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ fastlane/README.md
fastlane/report.xml
coverage
test-results
.bundle/
vendor/bundle/
87 changes: 68 additions & 19 deletions lib/fastlane/plugin/semantic_release/actions/analyze_commits.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,46 @@ def self.is_releasable(params)
UI.message("Found a tag #{tag_name} associated with version #{version}")
end

next_version = find_next_version(
version: version,
hash: hash,
releases: params[:releases],
ignore_scopes: params[:ignore_scopes],
single_step: params[:single_step],
debug: params[:debug]
)

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
# Last release analysis
Actions.lane_context[SharedValues::RELEASE_LAST_TAG_HASH] = hash
Actions.lane_context[SharedValues::RELEASE_LAST_VERSION] = version

success_message = "Next version (#{next_version}) is higher than last version (#{version}). This version should be released."
UI.success(success_message) if is_next_version_releasable

is_next_version_releasable
end

def self.find_next_version(params)
version = params[:version]

# 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

# setup for single-step mode
single_step = params[:single_step]
bumped_major = false
bumped_minor = false
bumped_patch = false

# Get commits log between last version and head
splitted = get_commits_from_hash(
hash: hash,
hash: params[:hash],
debug: params[:debug]
)

Expand All @@ -107,14 +139,26 @@ def self.is_releasable(params)
end

if commit[:release] == "major" || commit[:is_breaking_change]
next_major += 1
next_minor = 0
next_patch = 0
unless bumped_major
next_major += 1
next_minor = 0
next_patch = 0
bumped_major = single_step
bumped_minor = single_step
bumped_patch = single_step
end
elsif commit[:release] == "minor"
next_minor += 1
next_patch = 0
unless bumped_minor
next_minor += 1
next_patch = 0
bumped_minor = single_step
bumped_patch = single_step
end
elsif commit[:release] == "patch"
next_patch += 1
unless bumped_patch
next_patch += 1
bumped_patch = single_step
end
end

next_version = "#{next_major}.#{next_minor}.#{next_patch}"
Expand All @@ -123,26 +167,24 @@ def self.is_releasable(params)

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
# 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

success_message = "Next version (#{next_version}) is higher than last version (#{version}). This version should be released."
UI.success(success_message) if is_next_version_releasable

is_next_version_releasable
return next_version
end

def self.is_codepush_friendly(params)
if params[:single_step]
# If single-step mode is selected, skip checking last codepush version
# as it is likely in the middle of a release.
UI.important("Skipping RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION because single_step was set")
Actions.lane_context[SharedValues::RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION] = "0.0.0"
return false
end

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
Expand All @@ -154,7 +196,7 @@ def self.is_codepush_friendly(params)

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.')
UI.error('This usually 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
Expand Down Expand Up @@ -252,6 +294,13 @@ def self.available_options
type: Array,
optional: true
),
FastlaneCore::ConfigItem.new(
key: :single_step,
description: "Only update the new version by the minimal amount",
default_value: false,
type: Boolean,
optional: true
),
FastlaneCore::ConfigItem.new(
key: :debug,
description: "True if you want to log out a debug info",
Expand Down
103 changes: 103 additions & 0 deletions spec/analyze_commits_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,109 @@ def execute_lane_test(params)
end
end

describe "single_step" do
it "should increment fix once and return true" do
commits = [
"docs: ...|",
"fix: ...|",
"fix: ...|"
]
test_analyze_commits(commits)

expect(execute_lane_test(match: 'v*', single_step: true)).to eq(true)
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_NEXT_VERSION]).to eq("1.0.9")
end

it "should increment feat but not fix and return true" do
commits = [
"docs: ...|",
"feat: ...|",
"fix: ...|"
]
test_analyze_commits(commits)

expect(execute_lane_test(match: 'v*', single_step: true)).to eq(true)
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_NEXT_VERSION]).to eq("1.1.0")
end

it "should increment major change but not fix and return true" do
commits = [
"docs: ...|",
"feat: ...|",
"fix: ...|BREAKING CHANGE: Test",
"fix: ...|"
]
test_analyze_commits(commits)

expect(execute_lane_test(match: 'v*', single_step: true)).to eq(true)
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_NEXT_VERSION]).to eq("2.0.0")
end

describe "disables codepush" do
it "should provide codepush last version" do
commits = [
"fix: ...|codepush: ok",
"fix: ...|codepush: ok",
"fix: ...|codepush: ok",
"fix: ...|codepush: ok",
"fix: ...|codepush: ok",
"fix: ...",
"fix: ...|codepush: ok",
"docs: ...|codepush: ok",
"feat: ...|codepush: ok",
"fix: ...|codepush: ok"
]
allow(Fastlane::Actions::AnalyzeCommitsAction).to receive(:get_last_tag).and_return('v0.0.0-1-g71ce4d8')
allow(Fastlane::Actions::AnalyzeCommitsAction).to receive(:get_commits_from_hash).and_return(commits)

expect(execute_lane_test(match: 'v*', single_step: true)).to eq(true)
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_NEXT_VERSION]).to eq("0.1.0")
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION]).to eq("0.0.0")
end

it "should accept only codepush: ok as codepush friendly commit" do
commits = [
"fix: ...|codepush: ok",
"fix: ...|codepush: ok",
"fix: ...|codepush: ok",
"fix: ...|codepush",
"fix: ...|codepush: ok",
"docs: ...|codepush: ok",
"feat: ...|codepush: ok",
"fix: ...|codepush: ok"
]
allow(Fastlane::Actions::AnalyzeCommitsAction).to receive(:get_last_tag).and_return('v0.0.0-1-g71ce4d8')
allow(Fastlane::Actions::AnalyzeCommitsAction).to receive(:get_commits_from_hash).and_return(commits)

expect(execute_lane_test(match: 'v*', single_step: true)).to eq(true)
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_NEXT_VERSION]).to eq("0.1.0")
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION]).to eq("0.0.0")
end

it "should docs, test, etc commits are codepush friendly automatically" do
commits = [
"fix: ...|codepush: ok",
"fix: ...|codepush: ok",
"fix: ...|codepush",
"test: ...",
"refactor: ...|codepush: ok",
"feat: ...|codepush: ok",
"perf: ...|codepush: ok",
"chore: ...",
"docs: ...",
"feat: ...|codepush: ok",
"fix: ...|codepush: ok"
]
allow(Fastlane::Actions::AnalyzeCommitsAction).to receive(:get_last_tag).and_return('v0.0.0-1-g71ce4d8')
allow(Fastlane::Actions::AnalyzeCommitsAction).to receive(:get_commits_from_hash).and_return(commits)

expect(execute_lane_test(match: 'v*', single_step: true)).to eq(true)
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_NEXT_VERSION]).to eq("0.1.0")
expect(Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::RELEASE_LAST_INCOMPATIBLE_CODEPUSH_VERSION]).to eq("0.0.0")
end
end
end

it "should return false since there is no change that would increase version" do
commits = [
"docs: ...|",
Expand Down