Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ _None_
### Internal Changes

- Updates `activesupport` to `6.1.7.1`, addressing [a security issue](https://github.com/advisories/GHSA-j6gc-792m-qgm2). This is a major version change, but as the dependency is internal-only, it shouldn't be a breaking change for clients. [#441]
- Add the explicit dependency to `xcodeproj (~> 1.22)`, used in this case to replace the previous manual parsing of `.xcconfig` files. [#451]

## 6.3.0

Expand Down
1 change: 1 addition & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ PATH
progress_bar (~> 1.3)
rake (>= 12.3, < 14.0)
rake-compiler (~> 1.0)
xcodeproj (~> 1.22)

GEM
remote: https://rubygems.org/
Expand Down
1 change: 1 addition & 0 deletions fastlane-plugin-wpmreleasetoolkit.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'progress_bar', '~> 1.3'
spec.add_dependency 'rake', '>= 12.3', '< 14.0'
spec.add_dependency 'rake-compiler', '~> 1.0'
spec.add_dependency 'xcodeproj', '~> 1.22'

# `google-cloud-storage` is required by fastlane, but we pin it in case it's not in the future
spec.add_dependency 'google-cloud-storage', '~> 1.31'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'xcodeproj'

module Fastlane
module Helper
module Ios
Expand All @@ -23,6 +25,9 @@ module VersionHelper
#
def self.get_xcconfig_public_version(xcconfig_file:)
version = read_long_version_from_config_file(xcconfig_file)

UI.user_error!(".xcconfig file doesn't have a version configured") if version.nil?

vp = get_version_parts(version)
return "#{vp[MAJOR_NUMBER]}.#{vp[MINOR_NUMBER]}" unless is_hotfix?(version)

Expand Down Expand Up @@ -306,19 +311,15 @@ def self.read_build_number_from_config_file(filePath)
# Read the value of a given key from an `.xcconfig` file.
#
# @param [String] key The xcconfig key to get the value for
# @param [String] filePath The path to the `.xcconfig` file to read the value from
# @param [String] file_path The path to the `.xcconfig` file to read the value from
#
# @return [String] The value for the given key, or `nil` if the key was not found.
#
def self.read_from_config_file(key, filePath)
File.open(filePath, 'r') do |f|
f.each_line do |line|
line = line.strip()
return line.split('=')[1] if line.start_with?("#{key}=")
end
end
def self.read_from_config_file(key, file_path)
UI.user_error!(".xcconfig file #{file_path} not found") unless File.exist?(file_path)

return nil
config = Xcodeproj::Config.new(file_path)
config.attributes[key]
end

# Ensure that the version provided is only composed of number parts and return the validated string
Expand Down
70 changes: 58 additions & 12 deletions spec/ios_get_app_version_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,85 @@
describe Fastlane::Actions::IosGetAppVersionAction do
describe 'getting the public app version from the provided .xcconfig file' do
it 'parses the xcconfig file format correctly and gets the public version' do
xcconfig_mock_content = <<~CONTENT
// a comment
VERSION_SHORT = 6
VERSION_LONG = 6.30.0
CONTENT

expect_version(xcconfig_mock_content: xcconfig_mock_content, expected_version: '6.30')
end

it 'parses the xcconfig file format correctly and gets the public hotfix version' do
xcconfig_mock_content = <<~CONTENT
VERSION_SHORT = 6
// a comment
VERSION_LONG = 6.30.1
CONTENT

expect_version(xcconfig_mock_content: xcconfig_mock_content, expected_version: '6.30.1')
end

it 'parses the xcconfig with keys without spacing and gets the public version' do
xcconfig_mock_content = <<~CONTENT
// a comment
VERSION_SHORT=6
VERSION_LONG=6.30.0
CONTENT

allow(File).to receive(:exist?).and_return(true)

expect_version(xcconfig_mock_content: xcconfig_mock_content, expected_version: '6.30')
end

it 'parses the xcconfig file format correctly and gets the public hotfix version' do
it 'parses the xcconfig with keys without spacing and gets the public hotfix version' do
xcconfig_mock_content = <<~CONTENT
VERSION_SHORT=6
// a comment
VERSION_LONG=6.30.1
CONTENT

allow(File).to receive(:exist?).and_return(true)

expect_version(xcconfig_mock_content: xcconfig_mock_content, expected_version: '6.30.1')
end

def expect_version(xcconfig_mock_content:, expected_version:)
xcconfig_mock_file_path = File.join('mock', 'file', 'path')
it 'fails to extract the version from an xcconfig file with an invalid format' do
xcconfig_mock_content = <<~CONTENT
VERSION_SHORT = 6
VERSION_LONG 6.30.1
CONTENT

expect do
expect_version(xcconfig_mock_content: xcconfig_mock_content, expected_version: 'n/a')
end.to raise_error(FastlaneCore::Interface::FastlaneError)
end

it 'throws an error when the file is not found' do
file_path = 'file/not/found'

allow(File).to receive(:open).with(xcconfig_mock_file_path, 'r').and_yield(StringIO.new(xcconfig_mock_content))
expect do
run_described_fastlane_action(
public_version_xcconfig_file: file_path
)
end.to raise_error(FastlaneCore::Interface::FastlaneError)
end

it "throws an error when there isn't a version configured in the .xcconfig file" do
xcconfig_mock_content = <<~CONTENT
VERSION_SHORT = 6
// a comment
CONTENT

expect do
expect_version(xcconfig_mock_content: xcconfig_mock_content, expected_version: 'n/a')
end.to raise_error(FastlaneCore::Interface::FastlaneError)
end

version_result = run_described_fastlane_action(
public_version_xcconfig_file: xcconfig_mock_file_path
)
def expect_version(xcconfig_mock_content:, expected_version:)
with_tmp_file(named: 'mock_xcconfig.xcconfig', content: xcconfig_mock_content) do |tmp_file_path|
version_result = run_described_fastlane_action(
public_version_xcconfig_file: tmp_file_path
)

expect(version_result).to eq(expected_version)
expect(version_result).to eq(expected_version)
end
end
end
end