ETLane 0.1.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Lanes/CommonFastfile +322 -0
- data/Lanes/ExampleAppfile +31 -0
- data/Scripts/Package.resolved +16 -0
- data/Scripts/Package.swift +26 -0
- data/Scripts/README.md +3 -0
- metadata +49 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: '09b7a6a431d95a787e1c8071545b9d6808d4cd20e50e51b5912b83cc38b52e4d'
|
4
|
+
data.tar.gz: 7e68797c237de69e55ea50012fbc88b61f70a39b80beb44544987850976e6e72
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f26cdb1c032c33f01a51e6a3fd97d5a452e968e0d7eb56274780cac8f7506e1b881b6aad548a942061f694596d2364e4bbb1d159a9d1b5dcbf9ce6b01bdb721f
|
7
|
+
data.tar.gz: 646ff2101de9044f35330d239062677cc30308cf603baeeccc8a899893a80db736a8050fcb8694c8dea09c318b11a5e9a650a3a2bd61c6cfa448ce61bfb54277
|
@@ -0,0 +1,322 @@
|
|
1
|
+
fastlane_version "2.68.2"
|
2
|
+
|
3
|
+
default_platform :ios
|
4
|
+
|
5
|
+
platform :ios do
|
6
|
+
|
7
|
+
product_bundle_identifier = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
8
|
+
distribute_group_name = ENV["DISTRIBUTE_GROUP_NAME"]
|
9
|
+
project_name = ENV["PROJECT_NAME"]
|
10
|
+
|
11
|
+
build_folder = File.join(Dir.pwd, "..", "build")
|
12
|
+
last_commit_path = File.join(Dir.pwd, "last_commit")
|
13
|
+
scripts_dir = File.join(Dir.pwd, "../Pods/ETLane/Scripts")
|
14
|
+
|
15
|
+
desc "Push a new beta build to TestFlight"
|
16
|
+
lane :beta do |options|
|
17
|
+
setup_new_session(options)
|
18
|
+
provisioning_profile = "AppStore_#{product_bundle_identifier}"
|
19
|
+
username = options[:username]
|
20
|
+
|
21
|
+
get_certificates(output_path: build_folder, username: username)
|
22
|
+
profile_uuid = get_provisioning_profile(output_path: build_folder, username: username, app_identifier: product_bundle_identifier)
|
23
|
+
provisioningProfiles = Hash.new
|
24
|
+
provisioningProfiles[product_bundle_identifier] = profile_uuid
|
25
|
+
extension_bundle_ids = ENV["EXTENSION_BUNDLE_IDS"].split(",")
|
26
|
+
for extension_bundle_id in extension_bundle_ids do
|
27
|
+
extension_bundle_identifier = "#{product_bundle_identifier}.#{extension_bundle_id}"
|
28
|
+
extension_profile_uuid = get_provisioning_profile(output_path: build_folder, username: username, app_identifier: extension_bundle_identifier)
|
29
|
+
provisioningProfiles[extension_bundle_identifier] = extension_profile_uuid
|
30
|
+
end
|
31
|
+
|
32
|
+
team_id = CredentialsManager::AppfileConfig.try_fetch_value(:team_id)
|
33
|
+
build_app(
|
34
|
+
workspace: "#{project_name}.xcworkspace",
|
35
|
+
export_xcargs: "PROVISIONING_PROFILE_SPECIFIER='#{provisioning_profile}' DEVELOPMENT_TEAM='#{team_id}' CODE_SIGN_STYLE='Manual'",
|
36
|
+
scheme: project_name,
|
37
|
+
output_directory: build_folder,
|
38
|
+
include_bitcode: false,
|
39
|
+
skip_profile_detection: false,
|
40
|
+
export_options: {
|
41
|
+
method: "app-store",
|
42
|
+
signingStyle: "manual",
|
43
|
+
provisioningProfiles: provisioningProfiles
|
44
|
+
},
|
45
|
+
)
|
46
|
+
last_commit = File.read(last_commit_path)
|
47
|
+
changelog = changelog_from_git_commits(
|
48
|
+
quiet: true,
|
49
|
+
between: [last_commit, "HEAD"], # Optional, lets you specify a revision/tag range between which to collect commit info
|
50
|
+
pretty: "– %s",# Optional, lets you provide a custom format to apply to each commit when generating the changelog text
|
51
|
+
date_format: "short",# Optional, lets you provide an additional date format to dates within the pretty-formatted string
|
52
|
+
match_lightweight_tag: false, # Optional, lets you ignore lightweight (non-annotated) tags when searching for the last tag
|
53
|
+
merge_commit_filtering: "exclude_merges" # Optional, lets you filter out merge commits
|
54
|
+
)
|
55
|
+
puts changelog
|
56
|
+
build_number = get_build_number()
|
57
|
+
version = get_version_number(target: project_name) + " (" + build_number + ")"
|
58
|
+
branch_name = "feature/#{build_number}"
|
59
|
+
sh("git", "checkout", "-B", branch_name)
|
60
|
+
increment_and_push()
|
61
|
+
ENV["FL_CHANGELOG"] = nil
|
62
|
+
|
63
|
+
beta_app_review_info = {}
|
64
|
+
if ENV["ET_BETA_APP_REVIEW_INFO"]
|
65
|
+
beta_app_review_info = eval(ENV["ET_BETA_APP_REVIEW_INFO"])
|
66
|
+
end
|
67
|
+
|
68
|
+
exception = nil
|
69
|
+
begin
|
70
|
+
upload_to_testflight(
|
71
|
+
username: username,
|
72
|
+
beta_app_review_info: beta_app_review_info,
|
73
|
+
changelog: "",
|
74
|
+
groups: ["#{distribute_group_name}"]
|
75
|
+
)
|
76
|
+
tag = get_version_number(target: project_name) + "." + build_number
|
77
|
+
add_git_tag(
|
78
|
+
tag: tag
|
79
|
+
)
|
80
|
+
rescue => ex
|
81
|
+
exception = ex
|
82
|
+
UI.error(ex)
|
83
|
+
end
|
84
|
+
|
85
|
+
if exception == nil
|
86
|
+
if changelog
|
87
|
+
# Сохраним текущий комит
|
88
|
+
File.write(last_commit_path, last_git_commit[:commit_hash])
|
89
|
+
git_add(path: last_commit_path)
|
90
|
+
commit_bump(message: "Freeze changelog")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
work_branch = ENV["ET_BRANCH"] || 'master'
|
94
|
+
sh("git", "checkout", work_branch)
|
95
|
+
sh("git", "pull", "origin", work_branch)
|
96
|
+
sh("git", "merge", branch_name)
|
97
|
+
sh("git", "branch", "-D", branch_name)
|
98
|
+
push_to_git_remote
|
99
|
+
if exception == nil
|
100
|
+
post_message(changelog: changelog, version: version)
|
101
|
+
else
|
102
|
+
raise exception
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
lane :metadata do |options|
|
108
|
+
setup_new_session(options)
|
109
|
+
username = options[:username]
|
110
|
+
skip_screenshots = options[:skip_screenshots] != nil ? options[:skip_screenshots] : false
|
111
|
+
upload_preview = options[:upload_preview] != nil ? options[:upload_preview] : false
|
112
|
+
skip_metadata = options[:skip_metadata] != nil ? options[:skip_metadata] : false
|
113
|
+
google_sheet_tsv = ENV["GOOGLE_SHEET_TSV"]
|
114
|
+
|
115
|
+
metadata_path = File.join(build_folder, "metadata")
|
116
|
+
FileUtils.rm_rf(metadata_path)
|
117
|
+
screenshots_path = File.join(build_folder, "screenshots")
|
118
|
+
preview_path = File.join(build_folder, "previews")
|
119
|
+
download_screenshots = !skip_screenshots
|
120
|
+
if download_screenshots
|
121
|
+
FileUtils.rm_rf(screenshots_path)
|
122
|
+
end
|
123
|
+
|
124
|
+
cocoapods(
|
125
|
+
try_repo_update_on_error: true,
|
126
|
+
use_bundle_exec: true,
|
127
|
+
)
|
128
|
+
|
129
|
+
Dir.chdir(scripts_dir) do
|
130
|
+
sh(
|
131
|
+
"swift", "run", "Resources",
|
132
|
+
google_sheet_tsv,
|
133
|
+
"--output", "#{build_folder}",
|
134
|
+
"--download-screenshots", "#{download_screenshots}",
|
135
|
+
"--figma-token", "#{ENV["FIGMA_TOKEN"]}",
|
136
|
+
"--figma-project-id", "#{ENV["FIGMA_PROJECT_ID"]}",
|
137
|
+
"--figma-page", "#{ENV["FIGMA_SCREENSHOTS_PAGE_ID"]}"
|
138
|
+
)
|
139
|
+
end
|
140
|
+
# include_in_app_purchases` flag to `false`
|
141
|
+
# run_precheck_before_submit to false
|
142
|
+
ENV["DELIVER_METADATA_PATH"] = metadata_path
|
143
|
+
ENV["DELIVER_SCREENSHOTS_PATH"] = "#{screenshots_path}"
|
144
|
+
ENV["DELIVER_SKIP_METADATA"] = "#{skip_metadata}"
|
145
|
+
ENV["DELIVER_SKIP_SCREENSHOTS"] = "#{skip_screenshots}"
|
146
|
+
ENV["DELIVER_SKIP_BINARY_UPLOAD"] = "true"
|
147
|
+
ENV["DELIVER_FORCE"] = "true"
|
148
|
+
ENV["DELIVER_SUBMIT_FOR_REVIEW"] = "false"
|
149
|
+
ENV["DELIVER_USERNAME"] = username
|
150
|
+
ENV["DELIVER_IGNORE_LANGUAGE_DIRECTORY_VALIDATION"] = "true"
|
151
|
+
ENV["DELIVER_OVERWRITE_SCREENSHOTS"] = "true"
|
152
|
+
ENV["PRECHECK_INCLUDE_IN_APP_PURCHASES"] = "false"
|
153
|
+
ENV["DELIVER_RUN_PRECHECK_BEFORE_SUBMIT"] = "false"
|
154
|
+
|
155
|
+
begin
|
156
|
+
deliver(
|
157
|
+
# edit_live: true,
|
158
|
+
)
|
159
|
+
rescue => ex
|
160
|
+
UI.error(ex)
|
161
|
+
if ex.to_s.start_with?("The app name you entered is already being used.")
|
162
|
+
UI.error("Try to detect issue...")
|
163
|
+
deliver(
|
164
|
+
# edit_live: true,
|
165
|
+
individual_metadata_items: ['name', 'keywords', 'description'],
|
166
|
+
)
|
167
|
+
else
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
if upload_preview
|
172
|
+
ENV["FASTLANE_ITUNES_TRANSPORTER_PATH"] = "/Applications/Transporter.app/Contents/itms/"
|
173
|
+
ENV["FASTLANE_ITUNES_TRANSPORTER_USE_SHELL_SCRIPT"] = "1"
|
174
|
+
previews(username: username)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
lane :post_message do |options|
|
179
|
+
version = options[:version] ? options[:version] : get_version_number(target: project_name) + " (" + get_build_number() + ")"
|
180
|
+
changelog = options[:changelog]
|
181
|
+
slack(
|
182
|
+
message: "App successfully uploaded to TestFlight.",
|
183
|
+
success: true,
|
184
|
+
default_payloads: [],
|
185
|
+
attachment_properties: {
|
186
|
+
fields: [
|
187
|
+
{
|
188
|
+
title: "Build number",
|
189
|
+
value: version,
|
190
|
+
},
|
191
|
+
{
|
192
|
+
title: "Changelog",
|
193
|
+
value: changelog,
|
194
|
+
},
|
195
|
+
]
|
196
|
+
}
|
197
|
+
)
|
198
|
+
end
|
199
|
+
|
200
|
+
# fastlane action new_version bump_type:patch|minor|major
|
201
|
+
lane :new_version do |options|
|
202
|
+
bump_type = options[:bump_type] ? options[:bump_type] : "patch"
|
203
|
+
increment_and_push(bump_type: bump_type, push: true)
|
204
|
+
end
|
205
|
+
|
206
|
+
lane :increment_and_push do |options|
|
207
|
+
increment_build_number
|
208
|
+
bump_type = options[:bump_type]
|
209
|
+
if bump_type
|
210
|
+
increment_version_number(
|
211
|
+
bump_type: bump_type
|
212
|
+
)
|
213
|
+
end
|
214
|
+
commit_bump(message: "Bump up version")
|
215
|
+
if options[:push]
|
216
|
+
push_to_git_remote
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
lane :rlz_minor do
|
221
|
+
rlz(bump_type: "minor")
|
222
|
+
end
|
223
|
+
|
224
|
+
lane :rlz do |options|
|
225
|
+
version = options[:version]
|
226
|
+
if version.to_s.empty?
|
227
|
+
bump_type = options[:bump_type]
|
228
|
+
if bump_type.to_s.empty?
|
229
|
+
version_bump_podspec(bump_type: "patch")
|
230
|
+
else
|
231
|
+
version_bump_podspec(bump_type: bump_type)
|
232
|
+
end
|
233
|
+
version = lane_context[SharedValues::PODSPEC_VERSION_NUMBER]
|
234
|
+
else
|
235
|
+
version_bump_podspec(version_number: version)
|
236
|
+
end
|
237
|
+
|
238
|
+
git_commit(
|
239
|
+
message: "Bump up version to #{version}",
|
240
|
+
path: ["./*"]
|
241
|
+
)
|
242
|
+
add_git_tag(
|
243
|
+
tag: version
|
244
|
+
)
|
245
|
+
push_to_git_remote
|
246
|
+
pod_push(allow_warnings: true, use_bundle_exec: true)
|
247
|
+
end
|
248
|
+
|
249
|
+
lane :commit_bump do |options|
|
250
|
+
commit_version_bump(
|
251
|
+
message: options[:message],
|
252
|
+
force: true,
|
253
|
+
xcodeproj: "#{project_name}.xcodeproj"
|
254
|
+
)
|
255
|
+
end
|
256
|
+
|
257
|
+
lane :add_group_to_tf_build do |options|
|
258
|
+
fastlane_require 'spaceship'
|
259
|
+
|
260
|
+
spaceship = Spaceship::Tunes.login(options[:username])
|
261
|
+
spaceship.team_id = fastlane_itc_team_id
|
262
|
+
app = Spaceship::Tunes::Application.find(product_bundle_identifier)
|
263
|
+
build = Spaceship::TestFlight::Build.latest(app_id: app.apple_id, platform: 'ios')
|
264
|
+
group = Spaceship::TestFlight::Group.find(app_id: app.apple_id, group_name: distribute_group_name)
|
265
|
+
build.add_group!(group)
|
266
|
+
# Find team id
|
267
|
+
# teamInfo = spaceship.teams.select { |team| team['contentProvider']['name'].strip.downcase == team_name.strip.downcase }.first
|
268
|
+
# team_id = teamInfo['contentProvider']['contentProviderId'] if teamInfo
|
269
|
+
end
|
270
|
+
|
271
|
+
# Получить полный список всех team_id & itc_team_id нужные для Appfile
|
272
|
+
lane :first_time do |options|
|
273
|
+
require "spaceship"
|
274
|
+
applePassword = options[:password]
|
275
|
+
apple_id = options[:username] ? username = options[:username] : CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
|
276
|
+
clientTunes = Spaceship::Tunes.login(apple_id, applePassword)
|
277
|
+
client = Spaceship::Portal.login(apple_id, applePassword)
|
278
|
+
|
279
|
+
strClientTunes = ""
|
280
|
+
clientTunes.teams.each do |team|
|
281
|
+
UI.message "#{team['contentProvider']['name']} (#{team['contentProvider']['contentProviderId']})"
|
282
|
+
strClientTunes << "#{team['contentProvider']['name']} (#{team['contentProvider']['contentProviderId']})||"
|
283
|
+
end
|
284
|
+
puts "ItunesTeamNames: #{strClientTunes[0..-3]}"
|
285
|
+
|
286
|
+
strDevPortal = ""
|
287
|
+
client.teams.each do |team|
|
288
|
+
UI.message "#{team['name']} (#{team['teamId']})"
|
289
|
+
strDevPortal << "#{team['name']} (#{team['teamId']})||"
|
290
|
+
end
|
291
|
+
puts "DevTeamNames: #{strDevPortal[0..-3]}"
|
292
|
+
end
|
293
|
+
|
294
|
+
lane :setup_new_session do |options|
|
295
|
+
if ENV["ET_USE_SESSION"]
|
296
|
+
session = retrieve_fastlane_session(options)
|
297
|
+
ENV["FASTLANE_SESSION"] = session
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
lane :retrieve_fastlane_session do |options|
|
302
|
+
# runs shell
|
303
|
+
username = options[:username]
|
304
|
+
spaceauth_output = `bundle exec fastlane spaceauth -u #{username}`
|
305
|
+
# regex the output for the value we need
|
306
|
+
fastlane_session_regex = %r{Pass the following via the FASTLANE_SESSION environment variable:\n(?<session>.+)\n\n\nExample:\n.+}
|
307
|
+
new_session = nil
|
308
|
+
if match = spaceauth_output.match(fastlane_session_regex)
|
309
|
+
# Strip out the fancy formatting
|
310
|
+
new_session = match[:session].gsub("\e[4m\e[36m", "").gsub("\e[0m\e[0m", "")
|
311
|
+
end
|
312
|
+
|
313
|
+
# Yell and quit if unable to parse out session from spaceauth output
|
314
|
+
if new_session.nil?
|
315
|
+
puts "Unable to obtain new session via fastlane spaceauth"
|
316
|
+
exit 1
|
317
|
+
else
|
318
|
+
new_session
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
app_identifier "" # The bundle identifier of your app
|
2
|
+
apple_id "e.tyutyuev@gmail.com" # Your Apple email address
|
3
|
+
# You can run getTeamNames from CommonFastfile to get it
|
4
|
+
team_name ""
|
5
|
+
team_id "" # Developer Portal Team ID
|
6
|
+
itc_team_id "" # AppsetoreConnect Portal Team ID
|
7
|
+
|
8
|
+
# https://my.slack.com/services/new/incoming-webhook/
|
9
|
+
ENV["SLACK_URL"] = ""
|
10
|
+
ENV["PROJECT_NAME"] = ""
|
11
|
+
ENV["DISTRIBUTE_GROUP_NAME"] = ""
|
12
|
+
ENV["FASTLANE_SKIP_DOCS"] = "1"
|
13
|
+
ENV["EXTENSION_BUNDLE_IDS"] = ""
|
14
|
+
ENV["GOOGLE_SHEET_TSV"] = ""
|
15
|
+
ENV["DELIVER_REJECT_IF_POSSIBLE"] = "true"
|
16
|
+
ENV["PILOT_BETA_APP_FEEDBACK"] = "teanet@mail.ru"
|
17
|
+
ENV["PILOT_DISTRIBUTE_EXTERNAL"] = "false"
|
18
|
+
ENV["PILOT_SKIP_WAITING_FOR_BUILD_PROCESSING"] = "false"
|
19
|
+
ENV["ET_BETA_APP_REVIEW_INFO"] = {
|
20
|
+
contact_email: "teanet@mail.ru",
|
21
|
+
contact_first_name: "Eugene",
|
22
|
+
contact_last_name: "Tutuev",
|
23
|
+
contact_phone: "79833087335",
|
24
|
+
demo_account_required: false,
|
25
|
+
demo_account_name: "",
|
26
|
+
demo_account_password: "",
|
27
|
+
notes: ""
|
28
|
+
}.to_s
|
29
|
+
ENV["FIGMA_TOKEN"] = ""
|
30
|
+
ENV["FIGMA_PROJECT_ID"] = ""
|
31
|
+
|
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"object": {
|
3
|
+
"pins": [
|
4
|
+
{
|
5
|
+
"package": "swift-argument-parser",
|
6
|
+
"repositoryURL": "https://github.com/apple/swift-argument-parser",
|
7
|
+
"state": {
|
8
|
+
"branch": null,
|
9
|
+
"revision": "9564d61b08a5335ae0a36f789a7d71493eacadfc",
|
10
|
+
"version": "0.3.2"
|
11
|
+
}
|
12
|
+
}
|
13
|
+
]
|
14
|
+
},
|
15
|
+
"version": 1
|
16
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
// swift-tools-version:5.1
|
2
|
+
// The swift-tools-version declares the minimum version of Swift required to build this package.
|
3
|
+
|
4
|
+
import PackageDescription
|
5
|
+
|
6
|
+
let package = Package(
|
7
|
+
name: "Scripts",
|
8
|
+
platforms: [.macOS(.v10_15)],
|
9
|
+
dependencies: [
|
10
|
+
.package(url: "https://github.com/apple/swift-argument-parser", .upToNextMinor(from: "0.3.0")),
|
11
|
+
],
|
12
|
+
targets: [
|
13
|
+
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
14
|
+
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
15
|
+
.target(
|
16
|
+
name: "Common",
|
17
|
+
dependencies: []),
|
18
|
+
.target(
|
19
|
+
name: "Resources",
|
20
|
+
dependencies: [
|
21
|
+
"Common",
|
22
|
+
.product(name: "ArgumentParser", package: "swift-argument-parser"),
|
23
|
+
]
|
24
|
+
),
|
25
|
+
]
|
26
|
+
)
|
data/Scripts/README.md
ADDED
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ETLane
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.42
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- teanet
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-05-28 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: 'Xcode helper for upload builds and metadata
|
14
|
+
|
15
|
+
'
|
16
|
+
email:
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- Lanes/CommonFastfile
|
22
|
+
- Lanes/ExampleAppfile
|
23
|
+
- Scripts/Package.resolved
|
24
|
+
- Scripts/Package.swift
|
25
|
+
- Scripts/README.md
|
26
|
+
homepage: https://github.com/teanet/ETLane
|
27
|
+
licenses:
|
28
|
+
- MIT
|
29
|
+
metadata: {}
|
30
|
+
post_install_message:
|
31
|
+
rdoc_options: []
|
32
|
+
require_paths:
|
33
|
+
- lib
|
34
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ">="
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
39
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
requirements: []
|
45
|
+
rubygems_version: 3.0.3
|
46
|
+
signing_key:
|
47
|
+
specification_version: 4
|
48
|
+
summary: A short description of ETLane.
|
49
|
+
test_files: []
|