fastlane 1.63.1 → 1.64.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f856d6f6af4e0bf885b9472d0b1d4a935cb74ea4
4
- data.tar.gz: b578b4713ef937a906cb21eb8851776c0802c9f3
3
+ metadata.gz: 45dd5cf53c7177ddb32515a4ea523968bed241e7
4
+ data.tar.gz: 6180e4b81438d84dddd2a2c90a92c98693519f88
5
5
  SHA512:
6
- metadata.gz: a7356c5fa16111d39248728fe1eac89b4bdad3a1b7647153e9eafd163b0fc8d6284661e454c89024aae2ea7a8d20996a95633b6acfe49bfcab0ba852ff233d1b
7
- data.tar.gz: 1ab07e603d5a0d08b1fae7ba9d3fe77430850f009fc1ecc9e17586fa207ed910dd6391a22e84f4b522356f0db6a87f62dd871f07dd29445363cf299a8d6aed75
6
+ metadata.gz: e345f385b400bfd8703fb8b65b5760a957e33d583e17f0c0439969e310cca79e7a13b0cf271da5095409e9cdbd21e349d20447689e17d63dbe7135596e64df0a
7
+ data.tar.gz: 6b14e133ff543454b3919295a6f67437636b817795bdcdc9718310ad68f30bdb3b9eb665c64261a745ae21bb770de897ca36d618257814b9350ee7616fe87af4
@@ -12,7 +12,9 @@ module Fastlane
12
12
  alpha: params[:alpha],
13
13
  shield_io_timeout: params[:shield_io_timeout],
14
14
  glob: params[:glob],
15
- alpha_channel: params[:alpha_channel]
15
+ alpha_channel: params[:alpha_channel],
16
+ shield_gravity: params[:shield_gravity],
17
+ shield_no_resize: params[:shield_no_resize]
16
18
  }
17
19
  Badge::Runner.new.run(params[:path], options)
18
20
  end
@@ -100,6 +102,19 @@ module Fastlane
100
102
  is_string: false,
101
103
  verify_block: proc do |value|
102
104
  raise "alpha_channel is only a flag and should always be true".red unless value == true
105
+ end),
106
+ FastlaneCore::ConfigItem.new(key: :shield_gravity,
107
+ env_name: "FL_BADGE_SHIELD_GRAVITY",
108
+ description: "Position of shield on icon. Default: North - Choices include: NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast",
109
+ optional: true,
110
+ is_string: true),
111
+ FastlaneCore::ConfigItem.new(key: :shield_no_resize,
112
+ env_name: "FL_BADGE_SHIELD_NO_RESIZE",
113
+ description: "Shield image will no longer be resized to aspect fill the full icon. Instead it will only be shrinked to not exceed the icon graphic",
114
+ optional: true,
115
+ is_string: false,
116
+ verify_block: proc do |value|
117
+ raise "shield_no_resize is only a flag and should always be true".red unless value == true
103
118
  end)
104
119
  ]
105
120
  end
@@ -0,0 +1,102 @@
1
+ module Fastlane
2
+ module Actions
3
+ module SharedValues
4
+ BUILD_NUMBER_REPOSITORY = :BUILD_NUMBER_REPOSITORY
5
+ end
6
+
7
+ class GetBuildNumberRepositoryAction < Action
8
+ def self.is_svn?
9
+ Actions.sh 'svn info'
10
+ return true
11
+ rescue
12
+ return false
13
+ end
14
+
15
+ def self.is_git?
16
+ Actions.sh 'git rev-parse HEAD'
17
+ return true
18
+ rescue
19
+ return false
20
+ end
21
+
22
+ def self.is_git_svn?
23
+ Actions.sh 'git svn info'
24
+ return true
25
+ rescue
26
+ return false
27
+ end
28
+
29
+ def self.is_hg?
30
+ Actions.sh 'hg status'
31
+ return true
32
+ rescue
33
+ return false
34
+ end
35
+
36
+ def self.command(use_hg_revision_number)
37
+ if is_svn?
38
+ UI.message "Detected repo: svn"
39
+ return 'svn info | grep Revision | egrep -o "[0-9]+"'
40
+ elsif is_git_svn?
41
+ UI.message "Detected repo: git-svn"
42
+ return 'git svn info | grep Revision | egrep -o "[0-9]+"'
43
+ elsif is_git?
44
+ UI.message "Detected repo: git"
45
+ return 'git rev-parse --short HEAD'
46
+ elsif is_hg?
47
+ UI.message "Detected repo: hg"
48
+ if use_hg_revision_number
49
+ return 'hg parent --template {rev}'
50
+ else
51
+ return 'hg parent --template "{node|short}"'
52
+ end
53
+ else
54
+ raise "No repository detected"
55
+ end
56
+ end
57
+
58
+ def self.run(params)
59
+ build_number = Action.sh command(params[:use_hg_revision_number])
60
+ Actions.lane_context[SharedValues::BUILD_NUMBER_REPOSITORY] = build_number
61
+ build_number
62
+ end
63
+
64
+ #####################################################
65
+ # @!group Documentation
66
+ #####################################################
67
+
68
+ def self.description
69
+ "Get the build number from the current repository"
70
+ end
71
+
72
+ def self.available_options
73
+ [
74
+ FastlaneCore::ConfigItem.new(key: :use_hg_revision_number,
75
+ env_name: "USE_HG_REVISION_NUMBER",
76
+ description: "Use hg revision number instead of hash (ignored for non-hg repos)",
77
+ optional: true,
78
+ is_string: false,
79
+ default_value: false)
80
+ ]
81
+ end
82
+
83
+ def self.output
84
+ [
85
+ ['BUILD_NUMBER_REPOSITORY', 'The build number from the current repository']
86
+ ]
87
+ end
88
+
89
+ def self.return_value
90
+ "The build number from the current repository"
91
+ end
92
+
93
+ def self.authors
94
+ ["bartoszj", "pbrooks", "armadsen"]
95
+ end
96
+
97
+ def self.is_supported?(platform)
98
+ [:ios, :mac].include? platform
99
+ end
100
+ end
101
+ end
102
+ end
@@ -1,36 +1,71 @@
1
+ require 'pathname'
2
+ require 'shellwords'
3
+
1
4
  module Fastlane
2
5
  module Actions
3
6
  module SharedValues
4
- GRADLE_APK_OUTPUT_PATH = :APK_OUTPUT_PATH
7
+ GRADLE_APK_OUTPUT_PATH = :GRADLE_APK_OUTPUT_PATH
8
+ GRADLE_ALL_APK_OUTPUT_PATHS = :GRADLE_ALL_APK_OUTPUT_PATHS
5
9
  GRADLE_FLAVOR = :GRADLE_FLAVOR
10
+ GRADLE_BUILD_TYPE = :GRADLE_BUILD_TYPE
6
11
  end
7
12
 
8
13
  class GradleAction < Action
9
14
  def self.run(params)
10
15
  task = params[:task]
16
+ flavor = params[:flavor]
17
+ build_type = params[:build_type]
18
+
19
+ gradle_task = [task, flavor, build_type].join
20
+
21
+ project_dir = params[:project_dir]
22
+
23
+ gradle_path_param = params[:gradle_path] || './gradlew'
24
+
25
+ # Get the path to gradle, if it's an absolute path we take it as is, if it's relative we assume it's relative to the project_dir
26
+ gradle_path = if Pathname.new(gradle_path_param).absolute?
27
+ File.expand_path(gradle_path_param)
28
+ else
29
+ File.expand_path(File.join(project_dir, gradle_path_param))
30
+ end
31
+
32
+ # Ensure we ended up with a valid path to gradle
33
+ raise "Couldn't find gradlew at path '#{File.expand_path(gradle_path)}'".red unless File.exist?(gradle_path)
34
+
35
+ # Construct our flags
36
+ flags = []
37
+ flags << "-p #{project_dir.shellescape}"
38
+ flags << params[:properties].map { |k, v| "-P#{k}=#{v}" }.join(' ') unless params[:properties].nil?
39
+ flags << params[:flags] unless params[:flags].nil?
40
+
41
+ # Run the actual gradle task
42
+ gradle = Helper::GradleHelper.new(gradle_path: gradle_path)
43
+
44
+ # If these were set as properties, then we expose them back out as they might be useful to others
45
+ Actions.lane_context[SharedValues::GRADLE_BUILD_TYPE] = build_type if build_type
46
+ Actions.lane_context[SharedValues::GRADLE_FLAVOR] = flavor if flavor
47
+
48
+ # We run the actual gradle task
49
+ result = gradle.trigger(task: gradle_task, serial: params[:serial], flags: flags.join(' '))
50
+
51
+ # If we didn't build, then we return now, as it makes no sense to search for apk's in a non-`assemble` scenario
52
+ return result unless task.start_with?('assemble')
53
+
54
+ apk_search_path = File.join(project_dir, '*', 'build', 'outputs', 'apk', '*.apk')
55
+
56
+ # Our apk is now built, but there might actually be multiple ones that were built if a flavor was not specified in a multi-flavor project (e.g. `assembleRelease`), however we're not interested in unaligned apk's...
57
+ new_apks = Dir[apk_search_path].reject { |path| path =~ /^.*-unaligned.apk$/i}
58
+ new_apks = new_apks.map { |path| File.expand_path(path)}
11
59
 
12
- gradle = Helper::GradleHelper.new(gradle_path: params[:gradle_path])
13
-
14
- result = gradle.trigger(task: task, flags: params[:flags], serial: params[:serial])
15
-
16
- return result unless task.start_with?("assemble")
17
-
18
- # We built our app. Store the path to the apk
19
- flavor = task.match(/assemble(\w*)/)
20
- if flavor and flavor[1]
21
- flavor = flavor[1].downcase # Release => release
22
- apk_path = Dir[File.join("app", "build", "outputs", "apk", "*-#{flavor}.apk")].last
23
- if apk_path
24
- Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] = File.expand_path(apk_path)
25
- else
26
- Helper.log.info "Couldn't find signed apk file at path '#{apk_path}'...".red
27
- if flavor == 'release'
28
- Helper.log.info "Make sure to enable code signing in your gradle task: ".red
29
- Helper.log.info "https://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle".red
30
- end
31
- end
32
- Actions.lane_context[SharedValues::GRADLE_FLAVOR] = flavor
33
- end
60
+ # We expose all of these new apk's
61
+ Actions.lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS] = new_apks
62
+
63
+ # We also take the most recent apk to return as SharedValues::GRADLE_APK_OUTPUT_PATH, this is the one that will be relevant for most projects that just build a single build variant (flavor + build type combo). In multi build variants this value is undefined
64
+ last_apk_path = new_apks.sort_by(&File.method(:mtime)).last
65
+ Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] = File.expand_path(last_apk_path) if last_apk_path
66
+
67
+ # Give a helpful message in case there were no new apk's. Remember we're only running this code when assembling, in which case we certainly expect there to be an apk
68
+ Helper.log.info 'Couldn\'t find any new signed apk files...'.red if new_apks.empty?
34
69
 
35
70
  return result
36
71
  end
@@ -40,54 +75,75 @@ module Fastlane
40
75
  #####################################################
41
76
 
42
77
  def self.description
43
- "All gradle related actions, including building and testing your Android app"
78
+ 'All gradle related actions, including building and testing your Android app'
44
79
  end
45
80
 
46
81
  def self.details
47
82
  [
48
- "Run `./gradlew tasks` to get a list of all available gradle tasks for your project"
83
+ 'Run `./gradlew tasks` to get a list of all available gradle tasks for your project'
49
84
  ].join("\n")
50
85
  end
51
86
 
52
87
  def self.available_options
53
88
  [
54
- FastlaneCore::ConfigItem.new(key: :serial,
55
- env_name: "FL_ANDROID_SERIAL",
56
- description: "Android serial, wich device should be used for this command",
57
- is_string: true,
58
- default_value: ""),
59
89
  FastlaneCore::ConfigItem.new(key: :task,
60
- env_name: "FL_GRADLE_TASK",
61
- description: "The gradle task you want to execute",
90
+ env_name: 'FL_GRADLE_TASK',
91
+ description: 'The gradle task you want to execute, e.g. `assemble` or `test`. For tasks such as `assembleMyFlavorRelease` you should use gradle(task: \'assemble\', flavor: \'Myflavor\', build_type: \'Release\')',
92
+ optional: false,
93
+ is_string: true),
94
+ FastlaneCore::ConfigItem.new(key: :flavor,
95
+ env_name: 'FL_GRADLE_FLAVOR',
96
+ description: 'The flavor that you want the task for, e.g. `MyFlavor`. If you are running the `assemble` task in a multi-flavor project, and you rely on Actions.lane_context[Actions.SharedValues::GRADLE_APK_OUTPUT_PATH] then you must specify a flavor here or else this value will be undefined',
97
+ optional: true,
98
+ is_string: true),
99
+ FastlaneCore::ConfigItem.new(key: :build_type,
100
+ env_name: 'FL_GRADLE_BUILD_TYPE',
101
+ description: 'The build type that you want the task for, e.g. `Release`. Useful for some tasks such as `assemble`',
102
+ optional: true,
62
103
  is_string: true),
63
104
  FastlaneCore::ConfigItem.new(key: :flags,
64
- env_name: "FL_GRADLE_FLAGS",
65
- description: "All parameter flags you want to pass to the gradle command, e.g. `--exitcode --xml file.xml`",
105
+ env_name: 'FL_GRADLE_FLAGS',
106
+ description: 'All parameter flags you want to pass to the gradle command, e.g. `--exitcode --xml file.xml`',
66
107
  optional: true,
67
108
  is_string: true),
109
+ FastlaneCore::ConfigItem.new(key: :project_dir,
110
+ env_name: 'FL_GRADLE_PROJECT_DIR',
111
+ description: 'The root directory of the gradle project. Defaults to `.`',
112
+ default_value: '.',
113
+ is_string: true),
68
114
  FastlaneCore::ConfigItem.new(key: :gradle_path,
69
- env_name: "FL_GRADLE_PATH",
70
- description: "The path to your `gradlew`",
115
+ env_name: 'FL_GRADLE_PATH',
116
+ description: 'The path to your `gradlew`. If you specify a relative path, it is assumed to be relative to the `project_dir`',
117
+ optional: true,
118
+ is_string: true),
119
+ FastlaneCore::ConfigItem.new(key: :properties,
120
+ env_name: 'FL_GRADLE_PROPERTIES',
121
+ description: 'Gradle properties to be exposed to the gradle script',
122
+ optional: true,
123
+ is_string: false),
124
+ FastlaneCore::ConfigItem.new(key: :serial,
125
+ env_name: 'FL_ANDROID_SERIAL',
126
+ description: 'Android serial, wich device should be used for this command',
71
127
  is_string: true,
72
- default_value: Dir["./gradlew"].last, # Using Dir to be nil when the file doesn't exist (import for validation)
73
- verify_block: proc do |value|
74
- raise "Couldn't find gradlew at path '#{File.expand_path(value)}'".red unless File.exist?(value)
75
- end)
128
+ default_value: '')
76
129
  ]
77
130
  end
78
131
 
79
132
  def self.output
80
133
  [
81
- ['GRADLE_APK_OUTPUT_PATH', 'The path to the newly generated apk file']
134
+ ['GRADLE_APK_OUTPUT_PATH', 'The path to the newly generated apk file. Undefined in a multi-variant assemble scenario'],
135
+ ['GRADLE_ALL_APK_OUTPUT_PATHS', 'When running a multi-variant `assemble`, the array of signed apk\'s that were generated'],
136
+ ['GRADLE_FLAVOR', 'The flavor, e.g. `MyFlavor`'],
137
+ ['GRADLE_BUILD_TYPE', 'The build type, e.g. `Release`']
82
138
  ]
83
139
  end
84
140
 
85
141
  def self.return_value
86
- "The output of running the gradle task"
142
+ 'The output of running the gradle task'
87
143
  end
88
144
 
89
145
  def self.authors
90
- ["KrauseFx"]
146
+ ['KrauseFx', 'lmirosevic']
91
147
  end
92
148
 
93
149
  def self.is_supported?(platform)
@@ -30,7 +30,12 @@ module Fastlane
30
30
  Helper.log.info "Fetching the latest build number for version #{version_number}"
31
31
 
32
32
  train = app.build_trains[version_number]
33
- build_number = train.builds.map(&:build_version).map(&:to_i).sort.last
33
+ begin
34
+ build_number = train.builds.map(&:build_version).map(&:to_i).sort.last
35
+ rescue
36
+ raise "could not find a build on iTC - and 'initial_build_number' option is not set" unless params[:initial_build_number]
37
+ build_number = params[:initial_build_number]
38
+ end
34
39
 
35
40
  Helper.log.info "Latest upload is build number: #{build_number}"
36
41
  Actions.lane_context[SharedValues::LATEST_TESTFLIGHT_BUILD_NUMBER] = build_number
@@ -66,7 +71,13 @@ module Fastlane
66
71
  FastlaneCore::ConfigItem.new(key: :version,
67
72
  env_name: "LATEST_VERSION",
68
73
  description: "The version number whose latest build number we want",
69
- optional: true)
74
+ optional: true),
75
+ FastlaneCore::ConfigItem.new(key: :initial_build_number,
76
+ env_name: "INTITIAL_BUILD_NUMBER",
77
+ description: "sets the build number to given value if no build is in current train",
78
+ optional: true,
79
+ is_string: false)
80
+
70
81
  ]
71
82
  end
72
83
 
@@ -75,6 +75,11 @@ module Fastlane
75
75
  env_name: "MAILGUN_CI_BUILD_LINK",
76
76
  description: "CI Build Link",
77
77
  optional: true,
78
+ is_string: true),
79
+ FastlaneCore::ConfigItem.new(key: :template_path,
80
+ env_name: "MAILGUN_TEMPLATE_PATH",
81
+ description: "Mail HTML template",
82
+ optional: true,
78
83
  is_string: true)
79
84
 
80
85
  ]
@@ -98,11 +103,11 @@ module Fastlane
98
103
  from: "#{options[:from]}<#{options[:postmaster]}>",
99
104
  to: "#{options[:to]}",
100
105
  subject: options[:subject],
101
- html: mail_teplate(options)
102
- mail_teplate(options)
106
+ html: mail_template(options)
107
+ mail_template(options)
103
108
  end
104
109
 
105
- def self.mail_teplate(options)
110
+ def self.mail_template(options)
106
111
  hash = {
107
112
  author: Actions.git_author_email,
108
113
  last_commit: Actions.last_git_commit_message,
@@ -111,10 +116,18 @@ module Fastlane
111
116
  }
112
117
  hash[:success] = options[:success]
113
118
  hash[:ci_build_link] = options[:ci_build_link]
114
- Fastlane::ErbTemplateHelper.render(
115
- Fastlane::ErbTemplateHelper.load("mailgun_html_template"),
116
- hash
117
- )
119
+
120
+ # grabs module
121
+ eth = Fastlane::ErbTemplateHelper
122
+
123
+ # create html from template
124
+ html_template_path = options[:template_path]
125
+ if html_template_path && File.exist?(html_template_path)
126
+ html_template = eth.load_from_path(html_template_path)
127
+ else
128
+ html_template = eth.load("mailgun_html_template")
129
+ end
130
+ eth.render(html_template, hash)
118
131
  end
119
132
 
120
133
  end
@@ -7,8 +7,9 @@ module Fastlane
7
7
 
8
8
  class OclintAction < Action
9
9
  def self.run(params)
10
- if `which oclint`.to_s.length == 0 and !Helper.test?
11
- raise "You have to install oclint. Fore more details: ".red + "http://docs.oclint.org/en/stable/intro/installation.html".yellow
10
+ oclint_path = params[:oclint_path]
11
+ if `which #{oclint_path}`.to_s.empty? and !Helper.test?
12
+ raise "You have to install oclint or provide path to oclint binary. Fore more details: ".red + "http://docs.oclint.org/en/stable/intro/installation.html".yellow
12
13
  end
13
14
 
14
15
  compile_commands = params[:compile_commands]
@@ -64,7 +65,7 @@ module Fastlane
64
65
 
65
66
  command = [
66
67
  command_prefix,
67
- 'oclint',
68
+ oclint_path,
68
69
  oclint_args,
69
70
  '"' + files.join('" "') + '"'
70
71
  ].join(' ')
@@ -84,6 +85,11 @@ module Fastlane
84
85
 
85
86
  def self.available_options
86
87
  [
88
+ FastlaneCore::ConfigItem.new(key: :oclint_path,
89
+ env_name: 'FL_OCLINT_PATH',
90
+ description: 'The path to oclint binary',
91
+ default_value: 'oclint',
92
+ optional: true),
87
93
  FastlaneCore::ConfigItem.new(key: :compile_commands,
88
94
  env_name: 'FL_OCLINT_COMPILE_COMMANDS',
89
95
  description: 'The json compilation database, use xctool reporter \'json-compilation-database\'',
@@ -231,6 +231,16 @@ module Fastlane
231
231
  html_obj = bucket.objects.create(html_file_name, html_render.to_s, acl: :public_read)
232
232
  version_obj = bucket.objects.create(version_file_name, version_render.to_s, acl: :public_read)
233
233
 
234
+ # When you enable versioning on a S3 bucket,
235
+ # writing to an object will create an object version
236
+ # instead of replacing the existing object.
237
+ # http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/ObjectVersion.html
238
+ if plist_obj.kind_of? AWS::S3::ObjectVersion
239
+ plist_obj = plist_obj.object
240
+ html_obj = html_obj.object
241
+ version_obj = version_obj.object
242
+ end
243
+
234
244
  # Setting actionand environment variables
235
245
  Actions.lane_context[SharedValues::S3_PLIST_OUTPUT_PATH] = plist_obj.public_url.to_s
236
246
  ENV[SharedValues::S3_PLIST_OUTPUT_PATH.to_s] = plist_obj.public_url.to_s
@@ -241,7 +251,7 @@ module Fastlane
241
251
  Actions.lane_context[SharedValues::S3_VERSION_OUTPUT_PATH] = version_obj.public_url.to_s
242
252
  ENV[SharedValues::S3_VERSION_OUTPUT_PATH.to_s] = version_obj.public_url.to_s
243
253
 
244
- Helper.log.info "Successfully uploaded ipa file to '#{html_obj.public_url}'".green
254
+ Helper.log.info "Successfully uploaded ipa file to '#{Actions.lane_context[SharedValues::S3_IPA_OUTPUT_PATH]}'".green
245
255
  end
246
256
 
247
257
  #
@@ -8,56 +8,10 @@ module Fastlane
8
8
  [:ios, :mac].include? platform
9
9
  end
10
10
 
11
- def self.is_svn?
12
- Actions.sh 'svn info'
13
- return true
14
- rescue
15
- return false
16
- end
17
-
18
- def self.is_git?
19
- Actions.sh 'git rev-parse HEAD'
20
- return true
21
- rescue
22
- return false
23
- end
24
-
25
- def self.is_git_svn?
26
- Actions.sh 'git svn info'
27
- return true
28
- rescue
29
- return false
30
- end
31
-
32
- def self.is_hg?
33
- Actions.sh 'hg status'
34
- return true
35
- rescue
36
- return false
37
- end
38
-
39
11
  def self.run(params)
40
- if is_svn?
41
- Helper.log.info "Detected repo: svn"
42
- command = 'svn info | grep Revision | egrep -o "[0-9]+"'
43
- elsif is_git_svn?
44
- Helper.log.info "Detected repo: git-svn"
45
- command = 'git svn info | grep Revision | egrep -o "[0-9]+"'
46
- elsif is_git?
47
- Helper.log.info "Detected repo: git"
48
- command = 'git rev-parse --short HEAD'
49
- elsif is_hg?
50
- Helper.log.info "Detected repo: hg"
51
- if params[:use_hg_revision_number]
52
- command = 'hg parent --template {rev}'
53
- else
54
- command = 'hg parent --template "{node|short}"'
55
- end
56
- else
57
- raise "No repository detected"
58
- end
59
-
60
- build_number = Actions.sh command
12
+ build_number = Fastlane::Actions::GetBuildNumberRepositoryAction.run(
13
+ use_hg_revision_number: params[:use_hg_revision_number]
14
+ )
61
15
 
62
16
  Fastlane::Actions::IncrementBuildNumberAction.run(build_number: build_number)
63
17
  end
@@ -0,0 +1,80 @@
1
+ module Fastlane
2
+ module Actions
3
+ module SharedValues
4
+ UPDATE_ICLOUD_CONTAINER_IDENTIFIERS = :UPDATE_ICLOUD_CONTAINER_IDENTIFIERS
5
+ end
6
+
7
+ class UpdateIcloudContainerIdentifiersAction < Action
8
+ require 'plist'
9
+
10
+ def self.run(params)
11
+ entitlements_file = params[:entitlements_file]
12
+ UI.message "Entitlements File: #{entitlements_file}"
13
+
14
+ # parse entitlements
15
+ result = Plist.parse_xml(entitlements_file)
16
+ UI.error "Entitlements file at '#{entitlements_file}' cannot be parsed." unless result
17
+
18
+ # get iCloud container field
19
+ icloud_container_key = 'com.apple.developer.icloud-container-identifiers'
20
+ icloud_container_value = result[icloud_container_key]
21
+ UI.error "No existing iCloud container field specified. Please specify an iCloud container in the entitlements file." unless icloud_container_value
22
+
23
+ # get uniquity container field
24
+ ubiquity_container_key = 'com.apple.developer.ubiquity-container-identifiers'
25
+ ubiquity_container_value = result[ubiquity_container_key]
26
+ UI.error "No existing ubiquity container field specified. Please specify an ubiquity container in the entitlements file." unless ubiquity_container_value
27
+
28
+ # set iCloud container identifiers
29
+ result[icloud_container_key] = params[:icloud_container_identifiers]
30
+ result[ubiquity_container_key] = params[:icloud_container_identifiers]
31
+
32
+ # save entitlements file
33
+ result.save_plist(entitlements_file)
34
+
35
+ UI.message "Old iCloud Container Identifiers: #{icloud_container_value}"
36
+ UI.message "Old Ubiquity Container Identifiers: #{ubiquity_container_value}"
37
+
38
+ UI.success "New iCloud Container Identifiers set: #{result[icloud_container_key]}"
39
+ UI.success "New Ubiquity Container Identifiers set: #{result[ubiquity_container_key]}"
40
+
41
+ Actions.lane_context[SharedValues::UPDATE_ICLOUD_CONTAINER_IDENTIFIERS] = result[icloud_container_key]
42
+ end
43
+
44
+ def self.description
45
+ "This action changes the iCloud container identifiers in the entitlements file"
46
+ end
47
+
48
+ def self.available_options
49
+ [
50
+ FastlaneCore::ConfigItem.new(key: :entitlements_file,
51
+ env_name: "FL_UPDATE_ICLOUD_CONTAINER_IDENTIFIERS_ENTITLEMENTS_FILE_PATH",
52
+ description: "The path to the entitlement file which contains the iCloud container identifiers",
53
+ verify_block: proc do |value|
54
+ UI.user_error!("Please pass a path to an entitlements file. ") unless value.include? ".entitlements"
55
+ UI.user_error!("Could not find entitlements file") if !File.exist?(value) and !Helper.is_test?
56
+ end),
57
+ FastlaneCore::ConfigItem.new(key: :icloud_container_identifiers,
58
+ env_name: "FL_UPDATE_ICLOUD_CONTAINER_IDENTIFIERS_IDENTIFIERS",
59
+ description: "An Array of unique identifiers for the iCloud containers. Eg. ['iCloud.com.test.testapp']",
60
+ is_string: false,
61
+ verify_block: proc do |value|
62
+ UI.user_error!("The parameter icloud_container_identifiers needs to be an Array.") unless value.kind_of? Array
63
+ end)
64
+ ]
65
+ end
66
+
67
+ def self.output
68
+ ['UPDATE_ICLOUD_CONTAINER_IDENTIFIERS', 'The new iCloud Container Identifiers']
69
+ end
70
+
71
+ def self.authors
72
+ ["JamesKuang"]
73
+ end
74
+
75
+ def self.is_supported?(platform)
76
+ platform == :ios
77
+ end
78
+ end
79
+ end
80
+ end
@@ -9,7 +9,7 @@ module Fastlane
9
9
  class VerifyBuildAction < Action
10
10
  def self.run(params)
11
11
  Dir.mktmpdir do |dir|
12
- app_path = self.app_path(dir)
12
+ app_path = self.app_path(params, dir)
13
13
 
14
14
  values = self.gather_cert_info(app_path)
15
15
 
@@ -21,8 +21,8 @@ module Fastlane
21
21
  end
22
22
  end
23
23
 
24
- def self.app_path(dir)
25
- ipa_path = Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] || ''
24
+ def self.app_path(params, dir)
25
+ ipa_path = params[:ipa_path] || Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] || ''
26
26
  raise "Unable to find ipa file '#{ipa_path}'." unless File.exist?(ipa_path)
27
27
  ipa_path = File.expand_path(ipa_path)
28
28
 
@@ -67,7 +67,10 @@ module Fastlane
67
67
  values['provisioning_uuid'] = plist['UUID']
68
68
  values['team_name'] = plist['TeamName']
69
69
 
70
- raise "Inconsistent identifier found" unless plist['Entitlements']['application-identifier'] == "#{values['team_identifier']}.#{values['bundle_identifier']}"
70
+ application_identifier_prefix = plist['ApplicationIdentifierPrefix'][0]
71
+ full_bundle_identifier = "#{application_identifier_prefix}.#{values['bundle_identifier']}"
72
+
73
+ raise "Inconsistent identifier found; #{plist['Entitlements']['application-identifier']}, found in the embedded.mobileprovision file, should match #{full_bundle_identifier}, which is embedded in the codesign identity" unless plist['Entitlements']['application-identifier'] == full_bundle_identifier
71
74
  raise "Inconsistent identifier found" unless plist['Entitlements']['com.apple.developer.team-identifier'] == values['team_identifier']
72
75
 
73
76
  values
@@ -100,22 +103,22 @@ module Fastlane
100
103
 
101
104
  def self.evaulate(params, values)
102
105
  if params[:provisioning_type]
103
- raise "Mismatched provisioning_type '#{params[:provisioning_type]}'".red unless params[:provisioning_type] == values['provisioning_type']
106
+ raise "Mismatched provisioning_type. Required: '#{params[:provisioning_type]}''; Found: '#{values['provisioning_type']}'".red unless params[:provisioning_type] == values['provisioning_type']
104
107
  end
105
108
  if params[:provisioning_uuid]
106
- raise "Mismatched provisioning_uuid '#{params[:provisioning_uuid]}'".red unless params[:provisioning_uuid] == values['provisioning_uuid']
109
+ raise "Mismatched provisioning_uuid. Required: '#{params[:provisioning_uuid]}'; Found: '#{values['provisioning_uuid']}'".red unless params[:provisioning_uuid] == values['provisioning_uuid']
107
110
  end
108
111
  if params[:team_identifier]
109
- raise "Mismatched team_identifier '#{params[:team_identifier]}'".red unless params[:team_identifier] == values['team_identifier']
112
+ raise "Mismatched team_identifier. Required: '#{params[:team_identifier]}'; Found: '#{values['team_identifier']}'".red unless params[:team_identifier] == values['team_identifier']
110
113
  end
111
114
  if params[:team_name]
112
- raise "Mismatched team_name '#{params[:team_name]}'".red unless params[:team_name] == values['team_name']
115
+ raise "Mismatched team_name. Required: '#{params[:team_name]}'; Found: 'values['team_name']'".red unless params[:team_name] == values['team_name']
113
116
  end
114
117
  if params[:app_name]
115
- raise "Mismatched app_name '#{params[:app_name]}'".red unless params[:app_name] == values['app_name']
118
+ raise "Mismatched app_name. Required: '#{params[:app_name]}'; Found: '#{values['app_name']}'".red unless params[:app_name] == values['app_name']
116
119
  end
117
120
  if params[:bundle_identifier]
118
- raise "Mismatched bundle_identifier '#{params[:bundle_identifier]}'".red unless params[:bundle_identifier] == values['bundle_identifier']
121
+ raise "Mismatched bundle_identifier. Required: '#{params[:bundle_identifier]}'; Found: '#{values['bundle_identifier']}'".red unless params[:bundle_identifier] == values['bundle_identifier']
119
122
  end
120
123
 
121
124
  UI.success "Build is verified, have a 🍪."
@@ -161,6 +164,10 @@ module Fastlane
161
164
  FastlaneCore::ConfigItem.new(key: :bundle_identifier,
162
165
  env_name: "FL_VERIFY_BUILD_BUNDLE_IDENTIFIER",
163
166
  description: "Required bundle identifier",
167
+ optional: true),
168
+ FastlaneCore::ConfigItem.new(key: :ipa_path,
169
+ env_name: "FL_VERIFY_BUILD_IPA_PATH",
170
+ description: "Explicitly set the ipa path",
164
171
  optional: true)
165
172
  ]
166
173
  end
@@ -23,10 +23,11 @@ module Fastlane
23
23
  end
24
24
 
25
25
  # Run a certain action
26
- def trigger(task: nil, flags: nil, serial:nil)
26
+ def trigger(task: nil, flags: nil, serial: nil)
27
27
  # raise "Could not find gradle task '#{task}' in the list of available tasks".red unless task_available?(task)
28
- android_serial = serial != "" ? "ANDROID_SERIAL=#{serial}" : nil
29
- command = [android_serial, gradle_path, task, flags].join(" ")
28
+
29
+ android_serial = (serial != "") ? "ANDROID_SERIAL=#{serial}" : nil
30
+ command = [android_serial, gradle_path, task, flags].reject(&:nil?).join(" ")
30
31
  Action.sh(command)
31
32
  end
32
33
 
@@ -1,3 +1,3 @@
1
1
  module Fastlane
2
- VERSION = '1.63.1'.freeze
2
+ VERSION = '1.64.0'.freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.63.1
4
+ version: 1.64.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-25 00:00:00.000000000 Z
11
+ date: 2016-03-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: krausefx-shenzhen
@@ -673,6 +673,7 @@ files:
673
673
  - lib/fastlane/actions/frameit.rb
674
674
  - lib/fastlane/actions/gcovr.rb
675
675
  - lib/fastlane/actions/get_build_number.rb
676
+ - lib/fastlane/actions/get_build_number_repository.rb
676
677
  - lib/fastlane/actions/get_github_release.rb
677
678
  - lib/fastlane/actions/get_info_plist_value.rb
678
679
  - lib/fastlane/actions/get_ipa_info_plist_value.rb
@@ -763,6 +764,7 @@ files:
763
764
  - lib/fastlane/actions/update_app_group_identifiers.rb
764
765
  - lib/fastlane/actions/update_app_identifier.rb
765
766
  - lib/fastlane/actions/update_fastlane.rb
767
+ - lib/fastlane/actions/update_icloud_container_identifiers.rb
766
768
  - lib/fastlane/actions/update_info_plist.rb
767
769
  - lib/fastlane/actions/update_project_code_signing.rb
768
770
  - lib/fastlane/actions/update_project_provisioning.rb
@@ -828,7 +830,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
828
830
  version: '0'
829
831
  requirements: []
830
832
  rubyforge_project:
831
- rubygems_version: 2.4.6
833
+ rubygems_version: 2.2.2
832
834
  signing_key:
833
835
  specification_version: 4
834
836
  summary: Connect all iOS deployment tools into one streamlined workflow