xcodebuild_rake 2.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gemrc +1 -0
- data/.gitignore +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/README.md +25 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/bin/xcodebuild_rake_init +8 -0
- data/docs/configuration.md +43 -0
- data/docs/installation.md +11 -0
- data/docs/prerequisites.md +34 -0
- data/docs/usage.md +71 -0
- data/lib/.DS_Store +0 -0
- data/lib/ExportOptions.plist +10 -0
- data/lib/model/build_configuration.rb +90 -0
- data/lib/model/release_configuration.rb +46 -0
- data/lib/model/test_destination.rb +41 -0
- data/lib/model/upload_configuration.rb +63 -0
- data/lib/modules/applause_tool.rb +18 -0
- data/lib/modules/plist.rb +31 -0
- data/lib/modules/s3.rb +19 -0
- data/lib/modules/xcode.rb +142 -0
- data/lib/modules/zip.rb +18 -0
- data/lib/tasks/applause_pod.rake +75 -0
- data/lib/tasks/framework.rake +49 -0
- data/lib/tasks/notify.rake +9 -0
- data/lib/tasks/podspec.rake +85 -0
- data/lib/tasks/testapp.rake +48 -0
- data/lib/tasks/version_number.rake +83 -0
- data/lib/xcodebuild_rake.rb +29 -0
- data/lib/xcodebuild_rake/version.rb +3 -0
- data/lib/xcodebuild_safe.sh +38 -0
- data/templates/Rakefile +54 -0
- data/templates/build.yaml +15 -0
- data/xcodebuild_rake.gemspec +32 -0
- metadata +157 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
# Copyright (c) 2017 Applause Inc. All rights reserved.
|
2
|
+
|
3
|
+
namespace :framework do
|
4
|
+
desc "Build the SDK binary"
|
5
|
+
task :build, [:setup_name] do |t, args|
|
6
|
+
setup_name = args[:setup_name]
|
7
|
+
setup = BuildConfiguration.load(setup_name)
|
8
|
+
Xcode.build_universal_framework setup_name, setup.release_configuration.output_path
|
9
|
+
end
|
10
|
+
|
11
|
+
desc "Compress SDK"
|
12
|
+
task :archive, [:setup_name] => :build do |t, args|
|
13
|
+
setup_name = args[:setup_name]
|
14
|
+
setup = BuildConfiguration.load(setup_name)
|
15
|
+
if (setup.release_configuration.plist && setup.release_configuration.output_path && setup.release_configuration.product_name)
|
16
|
+
framework_path = setup.release_configuration.output_path + '/' + setup.release_configuration.product_name + '.framework'
|
17
|
+
archived_framework_path = archived_framework_path(setup_name)
|
18
|
+
Zip.compress(framework_path, archived_framework_path)
|
19
|
+
puts "Compressed Framework path: #{archived_framework_path}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Upload SDK to S3"
|
24
|
+
task :upload, [:setup_name] => :archive do |t, args|
|
25
|
+
setup_name = args[:setup_name]
|
26
|
+
setup = BuildConfiguration.load(setup_name)
|
27
|
+
if (setup.release_configuration.plist && setup.release_configuration.output_path && setup.release_configuration.product_name &&
|
28
|
+
setup.release_configuration.s3_upload_folder && setup.release_configuration.s3_bucket)
|
29
|
+
archived_framework_path = archived_framework_path(setup_name)
|
30
|
+
s3_upload_path = s3_upload_path(setup_name)
|
31
|
+
url = S3.upload_file(archived_framework_path, s3_upload_path, setup.release_configuration.s3_bucket)
|
32
|
+
puts "Framework S3 url: #{url}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def archived_framework_path(setup_name)
|
37
|
+
setup = BuildConfiguration.load(setup_name)
|
38
|
+
version = Plist.version(setup.release_configuration.plist)
|
39
|
+
archived_framework_path = setup.release_configuration.output_path + '/' + setup.release_configuration.product_name + '-' + version + '.zip'
|
40
|
+
return archived_framework_path
|
41
|
+
end
|
42
|
+
|
43
|
+
def s3_upload_path(setup_name)
|
44
|
+
setup = BuildConfiguration.load(setup_name)
|
45
|
+
version = Plist.version(setup.release_configuration.plist)
|
46
|
+
s3_upload_path = setup.release_configuration.s3_upload_folder + '/' + version + '/' + setup.release_configuration.product_name + '-' + version + '.zip'
|
47
|
+
return s3_upload_path
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Copyright (c) 2017 Applause Inc. All rights reserved.
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'git'
|
5
|
+
require 'cocoapods'
|
6
|
+
|
7
|
+
PODSPEC_TEMPLATE_PATH = "./Applause-Podspecs/%{pod_name}/%{pod_name}.template"
|
8
|
+
PODSPEC_PATH = "./Applause-Podspecs/%{pod_name}/%{version}/%{pod_name}.podspec"
|
9
|
+
|
10
|
+
namespace :podspec do
|
11
|
+
|
12
|
+
desc "Generates podspec for given setup name"
|
13
|
+
task :generate, [:setup_name] do |t, args|
|
14
|
+
setup_name = args[:setup_name]
|
15
|
+
setup = BuildConfiguration.load(setup_name)
|
16
|
+
version = Plist.version(setup.release_configuration.plist)
|
17
|
+
pod_name = setup.release_configuration.pod_name
|
18
|
+
template_path = PODSPEC_TEMPLATE_PATH % {pod_name: pod_name, version: version}
|
19
|
+
podspec_path = PODSPEC_PATH % {pod_name: pod_name, version: version}
|
20
|
+
podspec = generate_podspec(template_path, version)
|
21
|
+
save_podspec(podspec_path, podspec)
|
22
|
+
end
|
23
|
+
|
24
|
+
task :verify, [:setup_name] do |t, args|
|
25
|
+
pod_name, version = properties_from_setup(args[:setup_name])
|
26
|
+
podspec_path = PODSPEC_PATH % {pod_name: pod_name, version: version}
|
27
|
+
if !lint_podspec(podspec_path)
|
28
|
+
raise "*** Podspec is not valid! ***"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Generates and commits podspec for given setup name"
|
33
|
+
task :commit, [:setup_name] => :generate do |t, args|
|
34
|
+
setup_name = args[:setup_name]
|
35
|
+
setup = BuildConfiguration.load(setup_name)
|
36
|
+
version = Plist.version(setup.release_configuration.plist)
|
37
|
+
pod_name = setup.release_configuration.pod_name
|
38
|
+
podspec_path = PODSPEC_PATH % {pod_name: pod_name, version: version}
|
39
|
+
commit_message = "Generated #{pod_name} Podspec for #{version}"
|
40
|
+
commit(podspec_path, commit_message)
|
41
|
+
end
|
42
|
+
|
43
|
+
def generate_podspec(template_path, version)
|
44
|
+
template_file = File.open(template_path)
|
45
|
+
template = template_file.read
|
46
|
+
podspec = template % {version: version}
|
47
|
+
puts "New podspec:"
|
48
|
+
puts podspec
|
49
|
+
return podspec
|
50
|
+
end
|
51
|
+
|
52
|
+
def save_podspec(podspec_path, podspec_contents)
|
53
|
+
dirname = File.dirname(podspec_path)
|
54
|
+
unless File.directory?(dirname)
|
55
|
+
FileUtils.mkdir_p(dirname)
|
56
|
+
end
|
57
|
+
File.open(podspec_path, 'w') {|f|
|
58
|
+
f.write(podspec_contents)
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def lint_podspec(podspec_path)
|
63
|
+
validator = Pod::Validator.new(podspec_path, [])
|
64
|
+
valid = validator.validate
|
65
|
+
if !valid
|
66
|
+
validator.print_results
|
67
|
+
else
|
68
|
+
puts "*** Podspec is valid! ***"
|
69
|
+
end
|
70
|
+
return valid
|
71
|
+
end
|
72
|
+
|
73
|
+
def commit(file, message)
|
74
|
+
sdk_repo = Git.open('.')
|
75
|
+
sdk_repo.add(file)
|
76
|
+
sdk_repo.commit(message)
|
77
|
+
end
|
78
|
+
|
79
|
+
def properties_from_setup(setup_name)
|
80
|
+
setup = BuildConfiguration.load(setup_name)
|
81
|
+
version = Plist.version(setup.release_configuration.plist)
|
82
|
+
pod_name = setup.release_configuration.pod_name
|
83
|
+
return [pod_name, version]
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright (c) 2017 Applause Inc. All rights reserved.
|
2
|
+
|
3
|
+
namespace :testapp do
|
4
|
+
desc "Updates test app application key"
|
5
|
+
task :configure, [:setup_name, :upload_configuration_name] do |t, args|
|
6
|
+
configuration = UploadConfiguration.load(args[:upload_configuration_name])
|
7
|
+
setup_name = args[:setup_name]
|
8
|
+
setup = BuildConfiguration.load(setup_name)
|
9
|
+
update_application_key(configuration.application_key, setup.release_configuration.plist)
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Builds application"
|
13
|
+
task :archive, [:setup_name, :upload_configuration_name] => :configure do |t, args|
|
14
|
+
setup_name = args[:setup_name]
|
15
|
+
setup = BuildConfiguration.load(setup_name)
|
16
|
+
output_path = setup.release_configuration.output_path
|
17
|
+
export_options_plist = setup.release_configuration.export_options_plist
|
18
|
+
if export_options_plist.nil?
|
19
|
+
Xcode.archive_and_export_ipa setup_name, output_path
|
20
|
+
else
|
21
|
+
Xcode.archive_and_export_ipa setup_name, output_path, export_options_plist
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "Uploads test app to sdk.applause.com"
|
26
|
+
task :publish, [:setup_name, :upload_configuration_name] => :archive do |t, args|
|
27
|
+
upload_configuration_name = args[:upload_configuration_name]
|
28
|
+
configuration = UploadConfiguration.load(upload_configuration_name)
|
29
|
+
ipa_path = ipa_path(args[:setup_name])
|
30
|
+
ApplauseTool.upload_app(ipa_path, configuration.company_id, configuration.app_id, configuration.publish_email, configuration.service, upload_configuration_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_application_key(application_key, plist_path)
|
34
|
+
result = `/usr/libexec/PlistBuddy -c "Set :ATCApplicationId #{application_key}" "#{plist_path}"`
|
35
|
+
if result.length > 0
|
36
|
+
puts "Error: #{result}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def ipa_path(setup_name)
|
41
|
+
config = BuildConfiguration.load(setup_name)
|
42
|
+
file_name = config.release_configuration.product_name ? config.release_configuration.product_name : config.scheme
|
43
|
+
archive_folder = File.join(Dir.pwd, config.release_configuration.output_path)
|
44
|
+
ipa_name = file_name + ".ipa"
|
45
|
+
ipa_path = File.join(archive_folder, ipa_name)
|
46
|
+
return ipa_path
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# Copyright (c) 2017 Applause Inc. All rights reserved.
|
2
|
+
|
3
|
+
namespace :version_number do
|
4
|
+
desc "Removes suffix from version string in Info.plist file"
|
5
|
+
task :remove_suffix, [:setup_name] do |t, args|
|
6
|
+
setup_name = args[:setup_name]
|
7
|
+
setup = BuildConfiguration.load(setup_name)
|
8
|
+
plist_path = setup.release_configuration.plist
|
9
|
+
version = Plist.version(plist_path)
|
10
|
+
version_without_suffix = version_without_suffix(version)
|
11
|
+
set_version(plist_path, version_without_suffix)
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "Updates build number to current commits count"
|
15
|
+
task :update_sdk_build_version, [:setup_name] do |t, args|
|
16
|
+
setup_name = args[:setup_name]
|
17
|
+
update_build_number_for_setup(setup_name)
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Updates test apps versions and build numbers to values from SDK"
|
21
|
+
task :update_test_apps_versions, [:setup_name] do |t, args|
|
22
|
+
setup_name = args[:setup_name]
|
23
|
+
set_test_apps_versions(setup_name)
|
24
|
+
update_test_app_code_version(setup_name)
|
25
|
+
end
|
26
|
+
|
27
|
+
def update_build_number_to_commits_count(info_plist_path)
|
28
|
+
commits_count = `git rev-list HEAD --count`.strip
|
29
|
+
result = Plist.set_build_number("#{info_plist_path}", "#{commits_count}")
|
30
|
+
if result.length > 0
|
31
|
+
puts "Error: #{result}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
def update_test_app_code_version(setup_name)
|
37
|
+
setup = BuildConfiguration.load(setup_name)
|
38
|
+
plist_path = setup.release_configuration.plist
|
39
|
+
version = Plist.version(plist_path)
|
40
|
+
build_number = Plist.build_number(plist_path)
|
41
|
+
code_files = setup.release_configuration.test_apps_version_code_files
|
42
|
+
code_files.each { |file|
|
43
|
+
update_code_file_version(file, "#{version} (#{build_number})")
|
44
|
+
} unless code_files.nil?
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
def update_code_file_version(file_path, version)
|
49
|
+
text = File.read(file_path)
|
50
|
+
new_contents = text.gsub("###VERSION###", version)
|
51
|
+
File.open(file_path, "w") { |file| file.puts new_contents }
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def set_test_apps_versions(setup_name)
|
56
|
+
setup = BuildConfiguration.load(setup_name)
|
57
|
+
plist_path = setup.release_configuration.plist
|
58
|
+
version = Plist.version(plist_path)
|
59
|
+
build_number = Plist.build_number(plist_path)
|
60
|
+
test_apps_plists = setup.release_configuration.test_apps_plists
|
61
|
+
test_apps_plists.each { |plist|
|
62
|
+
update_application_version(plist, version, build_number)
|
63
|
+
} unless test_apps_plists.nil?
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
def update_build_number_for_setup(setup_name)
|
68
|
+
setup = BuildConfiguration.load(setup_name)
|
69
|
+
plist_path = setup.release_configuration.plist
|
70
|
+
update_build_number_to_commits_count(plist_path)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
def version_without_suffix(version)
|
75
|
+
return version.split("-")[0]
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
def update_application_version(info_plist_path, version, build_number)
|
80
|
+
Plist.set_version(info_plist_path, version)
|
81
|
+
Plist.set_build_number(info_plist_path, build_number)
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# Copyright (c) 2016 Applause Inc. All rights reserved.
|
2
|
+
|
3
|
+
require "xcodebuild_rake/version"
|
4
|
+
|
5
|
+
ROOT_DIR = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
#Load all rake tasks
|
8
|
+
Dir.glob(File.join(ROOT_DIR, "tasks", "*.rake")) { |script|
|
9
|
+
load script
|
10
|
+
}
|
11
|
+
|
12
|
+
#Load all classes
|
13
|
+
Dir.glob(File.join(ROOT_DIR, "model", "*.rb")) { |script|
|
14
|
+
require "#{script}"
|
15
|
+
}
|
16
|
+
|
17
|
+
#Load all modules
|
18
|
+
Dir.glob(File.join(ROOT_DIR, "modules", "*.rb")) { |script|
|
19
|
+
require "#{script}"
|
20
|
+
include self.class.const_get(File.basename(script).gsub('.rb','').split("_").map{|ea| ea.capitalize}.join(""))
|
21
|
+
}
|
22
|
+
|
23
|
+
Rake::FileUtilsExt.verbose(false)
|
24
|
+
|
25
|
+
### BUILD SCRIPT FUNCTIONS ###
|
26
|
+
|
27
|
+
def display_version()
|
28
|
+
puts File.open("./xcodebuild_rake/version", "rb").read
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/bin/bash --login
|
2
|
+
|
3
|
+
# Cf. http://stackoverflow.com/questions/33041109
|
4
|
+
#
|
5
|
+
# Xcode 7 (incl. 7.0.1) seems to have a dependency on the system ruby.
|
6
|
+
# xcodebuild is screwed up by using rvm to map to another non-system
|
7
|
+
# ruby†. This script is a fix that allows you call xcodebuild in a
|
8
|
+
# "safe" rvm environment, but will not (AFAIK) affect the "external"
|
9
|
+
# rvm setting.
|
10
|
+
#
|
11
|
+
# The script is a drop in replacement for your xcodebuild call.
|
12
|
+
#
|
13
|
+
# xcodebuild arg1 ... argn
|
14
|
+
#
|
15
|
+
# would become
|
16
|
+
#
|
17
|
+
# path/to/xcbuild-safe.sh arg1 ... argn
|
18
|
+
#
|
19
|
+
# -----
|
20
|
+
# † Because, you know, that *never* happens when you are building
|
21
|
+
# Xcode projects, say with abstruse tools like Rake or CocoaPods.
|
22
|
+
|
23
|
+
# This allows you to use rvm in a script. Otherwise you get a BS
|
24
|
+
# error along the lines of "cannot use rvm as function". Jeez.
|
25
|
+
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"
|
26
|
+
|
27
|
+
# Cause rvm to use system ruby. AFAIK, this is effective only for
|
28
|
+
# the scope of this script.
|
29
|
+
rvm use system
|
30
|
+
|
31
|
+
unset RUBYLIB
|
32
|
+
unset RUBYOPT
|
33
|
+
unset BUNDLE_BIN_PATH
|
34
|
+
unset _ORIGINAL_GEM_PATH
|
35
|
+
unset BUNDLE_GEMFILE
|
36
|
+
|
37
|
+
set -x # echoes commands
|
38
|
+
xcodebuild "$@" # calls xcodebuild with all the arguments passed to this
|
data/templates/Rakefile
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'xcodebuild_rake'
|
3
|
+
|
4
|
+
S3_BUCKET = ''
|
5
|
+
|
6
|
+
PRODUCT_NAME = 'MyProject' #Replace 'MyProject' with your project name
|
7
|
+
INFO_PLIST = File.join(PRODUCT_NAME, 'Info.plist') #If your Info property list file is named differently, or is located elswhere, add proper path here
|
8
|
+
|
9
|
+
desc 'Display build script version'
|
10
|
+
task :version do
|
11
|
+
display_version
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'Cleans the project, including the build directory'
|
15
|
+
task :clean do
|
16
|
+
Xcode.clean
|
17
|
+
rm_rf BUILD_DIR
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Builds project using "Default" setup (see build.yaml)'
|
21
|
+
task :build => :clean do
|
22
|
+
Xcode.build
|
23
|
+
end
|
24
|
+
|
25
|
+
desc 'Builds project using "Default" setup (see build.yaml) but without cleaning'
|
26
|
+
task :incremental_build do
|
27
|
+
Xcode.build
|
28
|
+
end
|
29
|
+
|
30
|
+
desc 'Executes test for the project using "Specs" setup (see build.yaml)'
|
31
|
+
task :test => :clean do
|
32
|
+
test "Specs"
|
33
|
+
end
|
34
|
+
|
35
|
+
desc 'Executes test for the project using "Specs" setup (see build.yaml) but without cleaning'
|
36
|
+
task :incremental_test do
|
37
|
+
test "Specs"
|
38
|
+
end
|
39
|
+
|
40
|
+
task :update_build_number do
|
41
|
+
version_number:update_build_number_to_commits_count INFO_PLIST
|
42
|
+
end
|
43
|
+
|
44
|
+
desc 'Archives app using "Default" (see build.yaml) - use this task for distribution'
|
45
|
+
task :archive => [:clean, :update_build_number] do
|
46
|
+
Xcode.archive
|
47
|
+
end
|
48
|
+
|
49
|
+
task :release => :archive do
|
50
|
+
config = BuildConfiguration.load('Default')
|
51
|
+
app_url, archive_url = S3.upload_archived_app "#{BUILD_DIR}/#{config.scheme}.ipa", "#{BUILD_DIR}/#{config.scheme}.xcarchive.zip", INFO_PLIST, S3_BUCKET
|
52
|
+
puts "App was uploaded: #{app_url}"
|
53
|
+
puts "App's Xcode archive was uploaded: #{archive_url}"
|
54
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'xcodebuild_rake/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "xcodebuild_rake"
|
8
|
+
spec.version = XcodebuildRake::VERSION
|
9
|
+
spec.authors = ["Łukasz Przytuła", "Aleksander Zubala"]
|
10
|
+
spec.email = ["lprzytula@applause.com", "azubala@applause.com"]
|
11
|
+
|
12
|
+
spec.summary = "Xcodebuild helpers for rake"
|
13
|
+
spec.description = "This gem contains useful helpers for building and testing iOS/watchOS/tvOS/macOS apps using rake."
|
14
|
+
spec.homepage = "https://github.com/ApplauseAQI/xcodebuild-rake"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = "bin"
|
21
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ["lib"]
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.13"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
|
27
|
+
spec.add_runtime_dependency 'xcpretty'
|
28
|
+
spec.add_runtime_dependency 'terminal-notifier', '~> 1.6.3'
|
29
|
+
spec.add_runtime_dependency 'aws-sdk', '~> 2.1.2'
|
30
|
+
|
31
|
+
spec.post_install_message = "Thanks for using xcodebuild_rake!"
|
32
|
+
end
|