Skip to content

Commit

Permalink
Fix for taking into account commits with no PR (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
vegaro committed Oct 20, 2022
1 parent 01fccbc commit 0ec4b6a
Show file tree
Hide file tree
Showing 6 changed files with 896 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def self.validate_local_config_status_for_bump(new_branch, github_pr_token)
end

def self.calculate_next_snapshot_version(current_version)
Helper::VersioningHelper.increase_version(current_version, :minor, true)
Helper::VersioningHelper.calculate_next_version(current_version, :minor, true)
end

def self.create_github_release(release_version, release_description, upload_assets, repo_name, github_api_token)
Expand Down
84 changes: 53 additions & 31 deletions lib/fastlane/plugin/revenuecat_internal/helper/versioning_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@

module Fastlane
UI = FastlaneCore::UI unless Fastlane.const_defined?(:UI)
BUMP_VALUES = {
skip: 0,
patch: 1,
minor: 2,
major: 3
}

BUMP_PER_LABEL = {
major: %w[breaking].to_set,
Expand All @@ -21,32 +27,11 @@ def self.determine_next_version_using_labels(repo_name, github_token, rate_limit

commits = Helper::GitHubHelper.get_commits_since_old_version(github_token, old_version, repo_name)

type_of_bump = :patch
has_public_changes = false
public_change_labels = %w[breaking docs feat fix perf dependencies minor]
commits.each do |commit|
break if type_of_bump == :major

sha = commit["sha"]
items = Helper::GitHubHelper.get_pr_resp_items_for_sha(sha, github_token, rate_limit_sleep, repo_name)

UI.user_error!("Cannot determine next version. Multiple commits found for #{sha}") if items.size != 1

item = items.first
types_of_change = get_type_of_change_from_pr_info(item)
type_of_bump_for_change = get_type_of_bump_from_types_of_change(types_of_change)
type_of_bump = type_of_bump_for_change unless type_of_bump_for_change == :patch
changes_are_public = (types_of_change & public_change_labels).size > 0
type_of_bump = get_type_of_bump_from_commits(commits, github_token, rate_limit_sleep, repo_name)

has_public_changes = true if !has_public_changes && changes_are_public
end
UI.important("Type of bump after version #{old_version} is #{type_of_bump}")

unless has_public_changes
return old_version, :skip
end

return increase_version(old_version, type_of_bump, false), type_of_bump
return calculate_next_version(old_version, type_of_bump, false), type_of_bump
end

def self.auto_generate_changelog(repo_name, github_token, rate_limit_sleep)
Expand All @@ -64,7 +49,8 @@ def self.auto_generate_changelog(repo_name, github_token, rate_limit_sleep)
sha = commit["sha"]
items = Helper::GitHubHelper.get_pr_resp_items_for_sha(sha, github_token, rate_limit_sleep, repo_name)

if items.size == 1
case items.size
when 1
item = items.first

message = "#{item['title']} (##{item['number']})"
Expand All @@ -76,14 +62,23 @@ def self.auto_generate_changelog(repo_name, github_token, rate_limit_sleep)

line = "* #{message} via #{name} (@#{username})"
changelog_sections[section].push(line)
when 0
UI.important("Cannot find pull request associated to #{sha}. Using commit information and adding it to the Other section")
message = commit["commit"]["message"]
name = commit["commit"]["author"]["name"]
username = commit["author"]["login"]
line = "* #{message} via #{name} (@#{username})"
changelog_sections[:other].push(line)
else
UI.user_error!("Cannot generate changelog. Multiple commits found for #{sha}")
end
end
build_changelog_sections(changelog_sections)
end

def self.increase_version(current_version, type_of_bump, snapshot)
def self.calculate_next_version(current_version, type_of_bump, snapshot)
return current_version if type_of_bump == :skip

is_prerelease = %w(alpha beta rc).any? { |prerelease| current_version.include?(prerelease) }
is_valid_version = current_version.match?("^[0-9]+.[0-9]+.[0-9]+(-(alpha|beta|rc).[0-9]+)?$")

Expand All @@ -109,11 +104,7 @@ def self.increase_version(current_version, type_of_bump, snapshot)
end
end

if snapshot
"#{next_version}-SNAPSHOT"
else
next_version
end
snapshot ? "#{next_version}-SNAPSHOT" : next_version
end

private_class_method def self.latest_non_prerelease_version_number
Expand Down Expand Up @@ -160,8 +151,10 @@ def self.increase_version(current_version, type_of_bump, snapshot)
:major
elsif change_types.intersection(BUMP_PER_LABEL[:minor]).size > 0
:minor
else
elsif change_types.intersection(BUMP_PER_LABEL[:patch]).size > 0
:patch
else
:skip
end
end

Expand All @@ -171,6 +164,35 @@ def self.increase_version(current_version, type_of_bump, snapshot)
.select { |label| Helper::GitHubHelper::SUPPORTED_PR_LABELS.include?(label) }
.to_set
end

def self.get_type_of_bump_from_commits(commits, github_token, rate_limit_sleep, repo_name)
type_of_bump = :skip
commits.each do |commit|
break if type_of_bump == :major

sha = commit["sha"]
items = Helper::GitHubHelper.get_pr_resp_items_for_sha(sha, github_token, rate_limit_sleep, repo_name)

if items.size == 0
# skip this commit to minimize risk. If there are more commits, we'll use the current type_of_bump
# if there are no more commits, we'll skip the version bump
UI.important("There is no pull request associated with #{sha}")
next
elsif items.size > 1
UI.user_error!("Cannot determine next version. Multiple commits found for #{sha}")
end

item = items.first
commit_supported_labels = get_type_of_change_from_pr_info(item)
type_of_bump_for_commit = get_type_of_bump_from_types_of_change(commit_supported_labels)

puts("type_of_bump_for_commit #{type_of_bump_for_commit}")
puts("type_of_bump #{type_of_bump}")

type_of_bump = BUMP_VALUES.key([BUMP_VALUES[type_of_bump_for_commit], BUMP_VALUES[type_of_bump]].max)
end
type_of_bump
end
end
end
end
121 changes: 108 additions & 13 deletions spec/helper/versioning_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
let(:no_label_get_commit_1_response) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/no_label_get_commit_sha_a72c0435ecf71248f311900475e881cc07ac2eaf.json") }
end
let(:get_commits_response_no_pr) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commits_since_last_release_commit_with_no_pr.json") }
end
let(:get_commit_no_items) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commit_sha_4ceaceb20e700b92197daf8904f5c4e226625d8a.json") }
end

let(:hashes_to_responses) do
{
Expand Down Expand Up @@ -119,6 +125,34 @@
"### Other Changes\n" \
"* added a log when `autoSyncPurchases` is disabled (#1749) via aboedo (@aboedo)")
end

it 'change is classified as Other Changes if commit has no pr' do
setup_tag_stubs

allow(Fastlane::Actions::GithubApiAction).to receive(:run)
.with(server_url: server_url,
path: '/repos/RevenueCat/mock-repo-name/compare/1.11.0...HEAD',
http_method: http_method,
body: {},
api_token: 'mock-github-token')
.and_return(get_commits_response_no_pr)

allow(Fastlane::Actions::GithubApiAction).to receive(:run)
.with(server_url: server_url,
path: '/search/issues?q=repo:RevenueCat/mock-repo-name+is:pr+base:main+SHA:4ceaceb20e700b92197daf8904f5c4e226625d8a',
http_method: http_method,
body: {},
api_token: 'mock-github-token')
.and_return(get_commit_no_items)
expect_any_instance_of(Object).not_to receive(:sleep)
changelog = Fastlane::Helper::VersioningHelper.auto_generate_changelog(
'mock-repo-name',
'mock-github-token',
0
)
expect(changelog).to eq("### Other Changes\n" \
"* Updating great support link via Miguel José Carranza Guisado (@MiguelCarranza)")
end
end

describe '.determine_next_version_using_labels' do
Expand All @@ -134,6 +168,12 @@
let(:get_commits_response_skip) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commits_since_last_release_skip_release.json") }
end
let(:get_commits_response_no_pr) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commits_since_last_release_commit_with_no_pr.json") }
end
let(:get_commits_response_no_pr_more_commits) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commits_since_last_release_commit_with_no_pr_with_more_commits.json") }
end
let(:get_feat_commit_response) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commit_sha_a72c0435ecf71248f311900475e881cc07ac2eaf.json") }
end
Expand Down Expand Up @@ -164,6 +204,9 @@
let(:get_release_commit_response) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commit_sha_1285b6df6fb756d8b31337be9dabbf3ec5c0bbfe.json") }
end
let(:get_commit_no_items) do
{ body: File.read("#{File.dirname(__FILE__)}/../test_files/get_commit_sha_4ceaceb20e700b92197daf8904f5c4e226625d8a.json") }
end

let(:hashes_to_responses) do
{
Expand All @@ -173,7 +216,8 @@
'819dc620db5608fb952c852038a3560554161707' => get_ci_commit_response,
'7d77decbcc9098145d1efd4c2de078b6121c8906' => get_build_commit_response,
'6d37c766b6da55dcab67c201c93ba3d4ca538e55' => get_refactor_commit_response,
'1285b6df6fb756d8b31337be9dabbf3ec5c0bbfe' => get_release_commit_response
'1285b6df6fb756d8b31337be9dabbf3ec5c0bbfe' => get_release_commit_response,
'4ceaceb20e700b92197daf8904f5c4e226625d8a' => get_commit_no_items
}
end

Expand Down Expand Up @@ -301,72 +345,123 @@
)
end.to raise_exception(StandardError)
end

it 'skips if it finds commit without a pr associated' do
setup_commit_search_stubs(hashes_to_responses)

allow(Fastlane::Actions::GithubApiAction).to receive(:run)
.with(server_url: server_url,
path: '/repos/RevenueCat/mock-repo-name/compare/1.11.0...HEAD',
http_method: http_method,
body: {},
api_token: 'mock-github-token')
.and_return(get_commits_response_no_pr)
expect_any_instance_of(Object).not_to receive(:sleep)
next_version, type_of_bump = Fastlane::Helper::VersioningHelper.determine_next_version_using_labels(
'mock-repo-name',
'mock-github-token',
0
)
expect(next_version).to eq("1.11.0")
expect(type_of_bump).to eq(:skip)
end

it 'ignores commits without associated prs' do
setup_commit_search_stubs(hashes_to_responses)

allow(Fastlane::Actions::GithubApiAction).to receive(:run)
.with(server_url: server_url,
path: '/repos/RevenueCat/mock-repo-name/compare/1.11.0...HEAD',
http_method: http_method,
body: {},
api_token: 'mock-github-token')
.and_return(get_commits_response_no_pr_more_commits)
allow(Fastlane::Actions::GithubApiAction).to receive(:run)
.with(server_url: server_url,
path: '/search/issues?q=repo:RevenueCat/mock-repo-name+is:pr+base:main+SHA:a72c0435ecf71248f311900475e881cc07ac2eaf',
http_method: http_method,
body: {},
api_token: 'mock-github-token')
.and_return(get_breaking_commit_response)
expect_any_instance_of(Object).not_to receive(:sleep)
next_version, type_of_bump = Fastlane::Helper::VersioningHelper.determine_next_version_using_labels(
'mock-repo-name',
'mock-github-token',
0
)
expect(next_version).to eq("2.0.0")
expect(type_of_bump).to eq(:major)
end
end

describe '.increase_version' do
it 'increases patch version number' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3', :patch, false)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3', :patch, false)
expect(next_version).to eq('1.2.4')
end

it 'increases minor version number' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3', :minor, false)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3', :minor, false)
expect(next_version).to eq('1.3.0')
end

it 'increases major version number' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3', :major, false)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3', :major, false)
expect(next_version).to eq('2.0.0')
end

it 'increases minor snapshot version number' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3', :minor, true)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3', :minor, true)
expect(next_version).to eq('1.3.0-SNAPSHOT')
end

it 'increases major snapshot version number' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3', :major, true)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3', :major, true)
expect(next_version).to eq('2.0.0-SNAPSHOT')
end

it 'keeps version with snapshot but removing alpha modifier if it appears' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3-alpha.1', :major, true)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3-alpha.1', :major, true)
expect(next_version).to eq('1.2.3-SNAPSHOT')
end

it 'keeps version with snapshot but removing beta modifier if it appears' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3-beta.1', :minor, true)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3-beta.1', :minor, true)
expect(next_version).to eq('1.2.3-SNAPSHOT')
end

it 'keeps version with snapshot but removing rc modifier if it appears' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3-beta.1', :patch, true)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3-beta.1', :patch, true)
expect(next_version).to eq('1.2.3-SNAPSHOT')
end

it 'keeps version but removing rc modifier if it appears' do
next_version = Fastlane::Helper::VersioningHelper.increase_version('1.2.3-beta.1', :patch, false)
next_version = Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3-beta.1', :patch, false)
expect(next_version).to eq('1.2.3')
end

it 'fails if given snapshot version to bump' do
expect do
Fastlane::Helper::VersioningHelper.increase_version('1.2.3-SNAPSHOT', :patch, false)
Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3-SNAPSHOT', :patch, false)
end.to raise_exception(StandardError)
end

it 'fails if given unsupported version to bump' do
expect do
Fastlane::Helper::VersioningHelper.increase_version('1.2.3-alpha', :patch, false)
Fastlane::Helper::VersioningHelper.calculate_next_version('1.2.3-alpha', :patch, false)
end.to raise_exception(StandardError)
end
end

def setup_commit_search_stubs(hashes_to_responses)
def setup_tag_stubs
allow(Fastlane::Actions).to receive(:sh).with('git fetch --tags -f')
allow(Fastlane::Actions).to receive(:sh)
.with("git tag", log: false)
.and_return("0.1.0\n0.1.1\n1.11.0\n1.1.1.1\n1.1.1-alpha.1\n1.10.1")
end

def setup_commit_search_stubs(hashes_to_responses)
setup_tag_stubs
allow(Fastlane::Actions::GithubApiAction).to receive(:run)
.with(server_url: server_url,
path: '/repos/RevenueCat/mock-repo-name/compare/1.11.0...HEAD',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"total_count": 0,
"incomplete_results": false,
"items": [

]
}
Loading

0 comments on commit 0ec4b6a

Please sign in to comment.