Skip to content

[WIP] Automatic Version Numbering #350

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

Draft
wants to merge 11 commits into
base: trunk
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 3 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: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ _None_

### New Features

_None_
* Adds automatic version number calculation. [#350]

### Bug Fixes

Expand Down
2 changes: 1 addition & 1 deletion lib/fastlane/plugin/wpmreleasetoolkit.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Fastlane
module Wpmreleasetoolkit
# Return all .rb files inside the "actions" and "helper" directory
def self.all_classes
Dir[File.expand_path('**/{actions,helper}/**/*.rb', File.dirname(__FILE__))]
Dir[File.expand_path('**/{actions,helper,models}/**/*.rb', File.dirname(__FILE__))]
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
module Fastlane
module Actions
class NextRcVersionAction < Action
def self.run(params)
require 'octokit'
require 'git'
require_relative '../../helper/version_helper'

client = Octokit::Client.new(access_token: params[:access_token])
client.auto_paginate = true

helper = Fastlane::Helper::VersionHelper.new(
github_client: client,
git: Git.open(Dir.pwd)
)

version = Fastlane::Helper::Version.create(params[:version])
next_version = helper.next_rc_for_version(version, repository: params[:project])

UI.message "Next RC Version is #{next_version.rc}"

next_version
end

#####################################################
# @!group Documentation
#####################################################

def self.description
'Return the next RC Version for this branch'
end

def self.available_options
[
FastlaneCore::ConfigItem.new(
key: :access_token,
env_name: 'GITHUB_TOKEN',
description: 'The GitHub token to use when querying GitHub',
type: String,
sensitive: true
),
FastlaneCore::ConfigItem.new(
key: :version,
description: 'The current version',
type: String,
verify_block: proc { |v| UI.user_error!("Invalid version number: #{v}") if Fastlane::Helper::Version.create(v).nil? }
),
FastlaneCore::ConfigItem.new(
key: :project,
description: 'The project slug (ex: `wordpress-mobile/wordpress-ios`)',
type: String
),
FastlaneCore::ConfigItem.new(
key: :project_root,
env_name: 'PROJECT_ROOT_FOLDER',
description: 'The project root folder (that contains the .git directory)',
type: String,
default_value: Dir.pwd,
verify_block: proc { |v| UI.user_error!("Directory does not exist: #{v}") unless File.directory? v }
),
]
end

def self.authors
['Automattic']
end

def self.is_supported?(platform)
true
end
end
end
end
90 changes: 90 additions & 0 deletions lib/fastlane/plugin/wpmreleasetoolkit/helper/version_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module Fastlane
module Helper
class VersionHelper
def initialize(github_client:, git: nil)
@git = git || Git.open(Dir.pwd)
@github_client = github_client
end

# Generate a prototype build name based on the current branch and commit.
#
# Takes optional `branch:` and `commit:` arguments to generate a build name
# based on a different branch and commit.
def prototype_build_name(branch: nil, commit: nil)
branch ||= current_branch
commit ||= current_commit

"#{branch}-#{commit[:sha][0, 7]}"
end

# Generate a prototype build number based on the most recent commit.
#
# Takes an optional `commit:` argument to generate a build number based
# on a different commit.
def prototype_build_number(commit: nil)
commit ||= current_commit
commit[:date].to_i
end

# Generate an alpha build name based on the current branch and commit.
#
# Takes optional `branch:` and `commit:` arguments to generate a build name
# based on a different branch and commit.
def alpha_build_name(branch: nil, commit: nil)
branch ||= current_branch
commit ||= current_commit

"#{branch}-#{commit[:sha][0, 7]}"
end

# Generate an alpha number.
#
# Allows injecting a specific `DateTime` to derive the build number from
def alpha_build_number(now: DateTime.now)
now.to_i
end

# Find the newest rc of a specific version in a given GitHub repository.
def newest_rc_for_version(version, repository:)
tags = @github_client.tags(repository)

# GitHub Enterprise can return raw HTML if the connection isn't
#working, so we need to validate that this is what we expect it is

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Missing space after #.

UI.crash! 'Unable to connect to GitHub. Please try again later.' if !tags.is_a? Array

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Favor unless over if for negative conditions.


tags.map { |t| Version.create(t[:name]) }
.compact

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Align .compact with .map on line 55.

.filter { |v| v.is_different_rc_of(version) }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Align .filter with .map on line 55.

.filter(&:prerelease?)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Align .filter with .map on line 55.

.sort

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Align .sort with .map on line 55.

.reverse

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Align .reverse with .map on line 55.

.first

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 Align .first with .map on line 55.

end

# Given the current version of an app and its Git Repository,
# use the existing tags to figure out which RC version should be
# the next one.
def next_rc_for_version(version, repository:)
most_recent_rc_version = newest_rc_for_version(version, repository: repository)

# If there is no RC tag, this must be the first one ever
return version.next_rc_version if most_recent_rc_version.nil?

# If we have a previous RC for this version, we can just bump it
most_recent_rc_version.next_rc_version
end

private

# Get the most recent commit on the current branch of the Git repository
def current_commit
@git.log.first
end

# Get the most current branch of the Git repository
def current_branch
@git.current_branch
end
end
end
end
Loading