Merge branch 'master' of github.com:microsoft/fastlane-plugin-appcenter into feature/auto-create-app-parameters
This commit is contained in:
Коммит
e78680bb06
|
@ -36,8 +36,10 @@ The action parameters `api_token` and `owner_name` can also be omitted when thei
|
||||||
- `APPCENTER_APP_NAME` - App name. If there is no app with such name, you will be prompted to create one
|
- `APPCENTER_APP_NAME` - App name. If there is no app with such name, you will be prompted to create one
|
||||||
- `APPCENTER_DISTRIBUTE_APK` - Build release path for android build
|
- `APPCENTER_DISTRIBUTE_APK` - Build release path for android build
|
||||||
- `APPCENTER_DISTRIBUTE_IPA` - Build release path for ios build
|
- `APPCENTER_DISTRIBUTE_IPA` - Build release path for ios build
|
||||||
- `APPCENTER_DISTRIBUTE_DSYM` - Path to your symbols file. For iOS provide path to app.dSYM.zip
|
- `APPCENTER_DISTRIBUTE_DSYM` - Path to your symbols (app.dSYM.zip) file
|
||||||
- `APPCENTER_DISTRIBUTE_UPLOAD_DSYM_ONLY` - Flag to upload only the dSYM file to App Center
|
- `APPCENTER_DISTRIBUTE_UPLOAD_DSYM_ONLY` - Flag to upload only the dSYM file to App Center
|
||||||
|
- `APPCENTER_DISTRIBUTE_ANDROID_MAPPING` - Path to your Android mapping.txt file
|
||||||
|
- `APPCENTER_DISTRIBUTE_UPLOAD_ANDROID_MAPPING_ONLY` - Flag to upload only the mapping file to App Center
|
||||||
- `APPCENTER_DISTRIBUTE_DESTINATIONS` - Comma separated list of destination names. Both distribution groups and stores are supported. All names are required to be of the same destination type. Default is `Collaborators`.
|
- `APPCENTER_DISTRIBUTE_DESTINATIONS` - Comma separated list of destination names. Both distribution groups and stores are supported. All names are required to be of the same destination type. Default is `Collaborators`.
|
||||||
- `APPCENTER_DISTRIBUTE_DESTINATION_TYPE` - Destination type of distribution destination. `group` and `store` are supported. Default is `group`
|
- `APPCENTER_DISTRIBUTE_DESTINATION_TYPE` - Destination type of distribution destination. `group` and `store` are supported. Default is `group`
|
||||||
- `APPCENTER_DISTRIBUTE_MANDATORY_UPDATE` - Require users to update to this release
|
- `APPCENTER_DISTRIBUTE_MANDATORY_UPDATE` - Require users to update to this release
|
||||||
|
|
|
@ -152,10 +152,10 @@ lane :test do
|
||||||
owner_name: ENV["TEST_APPCENTER_OWNER_NAME"],
|
owner_name: ENV["TEST_APPCENTER_OWNER_NAME"],
|
||||||
app_name: "MyApplication",
|
app_name: "MyApplication",
|
||||||
apk: "./fastlane/app-release.apk",
|
apk: "./fastlane/app-release.apk",
|
||||||
upload_dsym_only: true,
|
upload_mapping_only: true,
|
||||||
build_number: "3",
|
build_number: "3",
|
||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
dsym: "./fastlane/mapping.txt",
|
mapping: "./fastlane/mapping.txt",
|
||||||
notify_testers: false
|
notify_testers: false
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -45,6 +45,7 @@ module Fastlane
|
||||||
|
|
||||||
UI.message("Starting dSYM upload...")
|
UI.message("Starting dSYM upload...")
|
||||||
|
|
||||||
|
# TODO: this should eventually be removed once we have warned of deprecation for long enough
|
||||||
if File.extname(dsym_path) == ".txt"
|
if File.extname(dsym_path) == ".txt"
|
||||||
file_name = File.basename(dsym_path)
|
file_name = File.basename(dsym_path)
|
||||||
dsym_upload_details = Helper::AppcenterHelper.create_mapping_upload(api_token, owner_name, app_name, file_name ,build_number, version)
|
dsym_upload_details = Helper::AppcenterHelper.create_mapping_upload(api_token, owner_name, app_name, file_name ,build_number, version)
|
||||||
|
@ -57,11 +58,37 @@ module Fastlane
|
||||||
upload_url = dsym_upload_details['upload_url']
|
upload_url = dsym_upload_details['upload_url']
|
||||||
|
|
||||||
UI.message("Uploading dSYM...")
|
UI.message("Uploading dSYM...")
|
||||||
Helper::AppcenterHelper.upload_dsym(api_token, owner_name, app_name, dsym_path, symbol_upload_id, upload_url)
|
Helper::AppcenterHelper.upload_symbol(api_token, owner_name, app_name, dsym_path, "Apple", symbol_upload_id, upload_url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.run_mapping_upload(params)
|
||||||
|
values = params.values
|
||||||
|
api_token = params[:api_token]
|
||||||
|
owner_name = params[:owner_name]
|
||||||
|
app_name = params[:app_name]
|
||||||
|
mapping = params[:mapping]
|
||||||
|
build_number = params[:build_number]
|
||||||
|
version = params[:version]
|
||||||
|
|
||||||
|
if mapping == nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
UI.message("Starting mapping upload...")
|
||||||
|
mapping_name = File.basename(mapping)
|
||||||
|
symbol_upload_details = Helper::AppcenterHelper.create_mapping_upload(api_token, owner_name, app_name, mapping_name, build_number, version)
|
||||||
|
|
||||||
|
if symbol_upload_details
|
||||||
|
symbol_upload_id = symbol_upload_details['symbol_upload_id']
|
||||||
|
upload_url = symbol_upload_details['upload_url']
|
||||||
|
|
||||||
|
UI.message("Uploading mapping...")
|
||||||
|
Helper::AppcenterHelper.upload_symbol(api_token, owner_name, app_name, mapping, "Android", symbol_upload_id, upload_url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# run whole upload process for release
|
# run whole upload process for release
|
||||||
def self.run_release_upload(params)
|
def self.run_release_upload(params)
|
||||||
values = params.values
|
values = params.values
|
||||||
|
@ -168,11 +195,13 @@ module Fastlane
|
||||||
def self.run(params)
|
def self.run(params)
|
||||||
values = params.values
|
values = params.values
|
||||||
upload_dsym_only = params[:upload_dsym_only]
|
upload_dsym_only = params[:upload_dsym_only]
|
||||||
|
upload_mapping_only = params[:upload_mapping_only]
|
||||||
|
|
||||||
# if app found or successfully created
|
# if app found or successfully created
|
||||||
if self.get_or_create_app(params)
|
if self.get_or_create_app(params)
|
||||||
self.run_release_upload(params) unless upload_dsym_only
|
self.run_release_upload(params) unless upload_dsym_only || upload_mapping_only
|
||||||
self.run_dsym_upload(params)
|
self.run_dsym_upload(params) unless upload_mapping_only
|
||||||
|
self.run_mapping_upload(params) unless upload_dsym_only
|
||||||
end
|
end
|
||||||
|
|
||||||
return values if Helper.test?
|
return values if Helper.test?
|
||||||
|
@ -274,8 +303,10 @@ module Fastlane
|
||||||
optional: true,
|
optional: true,
|
||||||
type: String,
|
type: String,
|
||||||
verify_block: proc do |value|
|
verify_block: proc do |value|
|
||||||
|
deprecated_files = [".txt"]
|
||||||
if value
|
if value
|
||||||
UI.user_error!("Couldn't find dSYM file at path '#{value}'") unless File.exist?(value)
|
UI.user_error!("Couldn't find dSYM file at path '#{value}'") unless File.exist?(value)
|
||||||
|
UI.message("Support for *.txt has been deprecated. Please use --mapping parameter or APPCENTER_DISTRIBUTE_ANDROID_MAPPING environment variable instead.") if deprecated_files.include? File.extname(value)
|
||||||
end
|
end
|
||||||
end),
|
end),
|
||||||
|
|
||||||
|
@ -286,6 +317,26 @@ module Fastlane
|
||||||
is_string: false,
|
is_string: false,
|
||||||
default_value: false),
|
default_value: false),
|
||||||
|
|
||||||
|
FastlaneCore::ConfigItem.new(key: :mapping,
|
||||||
|
env_name: "APPCENTER_DISTRIBUTE_ANDROID_MAPPING",
|
||||||
|
description: "Path to your Android mapping.txt",
|
||||||
|
optional: true,
|
||||||
|
type: String,
|
||||||
|
verify_block: proc do |value|
|
||||||
|
accepted_formats = [".txt"]
|
||||||
|
if value
|
||||||
|
UI.user_error!("Couldn't find mapping file at path '#{value}'") unless File.exist?(value)
|
||||||
|
UI.user_error!("Only \"*.txt\" formats are allowed, you provided \"#{File.name(value)}\"") unless accepted_formats.include? File.extname(value)
|
||||||
|
end
|
||||||
|
end),
|
||||||
|
|
||||||
|
FastlaneCore::ConfigItem.new(key: :upload_mapping_only,
|
||||||
|
env_name: "APPCENTER_DISTRIBUTE_UPLOAD_ANDROID_MAPPING_ONLY",
|
||||||
|
description: "Flag to upload only the mapping.txt file to App Center",
|
||||||
|
optional: true,
|
||||||
|
is_string: false,
|
||||||
|
default_value: false),
|
||||||
|
|
||||||
FastlaneCore::ConfigItem.new(key: :group,
|
FastlaneCore::ConfigItem.new(key: :group,
|
||||||
env_name: "APPCENTER_DISTRIBUTE_GROUP",
|
env_name: "APPCENTER_DISTRIBUTE_GROUP",
|
||||||
description: "Comma separated list of Distribution Group names",
|
description: "Comma separated list of Distribution Group names",
|
||||||
|
@ -382,6 +433,9 @@ module Fastlane
|
||||||
apk: "./app-release.apk",
|
apk: "./app-release.apk",
|
||||||
destinations: "Testers",
|
destinations: "Testers",
|
||||||
destination_type: "group",
|
destination_type: "group",
|
||||||
|
build_number: "3",
|
||||||
|
version: "1.0.0",
|
||||||
|
mapping: "./mapping.txt",
|
||||||
release_notes: "release notes",
|
release_notes: "release notes",
|
||||||
notify_testers: false
|
notify_testers: false
|
||||||
)',
|
)',
|
||||||
|
|
|
@ -123,8 +123,8 @@ module Fastlane
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# committs or aborts dsym upload
|
# committs or aborts symbol upload
|
||||||
def self.update_dsym_upload(api_token, owner_name, app_name, symbol_upload_id, status)
|
def self.update_symbol_upload(api_token, owner_name, app_name, symbol_upload_id, status)
|
||||||
connection = self.connection
|
connection = self.connection
|
||||||
|
|
||||||
response = connection.patch do |req|
|
response = connection.patch do |req|
|
||||||
|
@ -146,27 +146,30 @@ module Fastlane
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# upload dSYM files to specified upload url
|
# upload symbol (dSYM or mapping) files to specified upload url
|
||||||
# if succeed, then commits the upload
|
# if succeed, then commits the upload
|
||||||
# otherwise aborts
|
# otherwise aborts
|
||||||
def self.upload_dsym(api_token, owner_name, app_name, dsym, symbol_upload_id, upload_url)
|
def self.upload_symbol(api_token, owner_name, app_name, symbol, symbol_type, symbol_upload_id, upload_url)
|
||||||
connection = self.connection(upload_url, true)
|
connection = self.connection(upload_url, true)
|
||||||
|
|
||||||
response = connection.put do |req|
|
response = connection.put do |req|
|
||||||
req.headers['x-ms-blob-type'] = "BlockBlob"
|
req.headers['x-ms-blob-type'] = "BlockBlob"
|
||||||
req.headers['Content-Length'] = File.size(dsym).to_s
|
req.headers['Content-Length'] = File.size(symbol).to_s
|
||||||
req.headers['internal-request-source'] = "fastlane"
|
req.headers['internal-request-source'] = "fastlane"
|
||||||
req.body = Faraday::UploadIO.new(dsym, 'application/octet-stream') if dsym && File.exist?(dsym)
|
req.body = Faraday::UploadIO.new(symbol, 'application/octet-stream') if symbol && File.exist?(symbol)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
logType = "dSYM" if (symbol_type == "Apple")
|
||||||
|
logType = "mapping" if (symbol_type == "Android")
|
||||||
|
|
||||||
case response.status
|
case response.status
|
||||||
when 200...300
|
when 200...300
|
||||||
self.update_dsym_upload(api_token, owner_name, app_name, symbol_upload_id, 'committed')
|
self.update_symbol_upload(api_token, owner_name, app_name, symbol_upload_id, 'committed')
|
||||||
UI.success("dSYM uploaded")
|
UI.success("#{logType} uploaded")
|
||||||
else
|
else
|
||||||
UI.error("Error uploading dSYM #{response.status}: #{response.body}")
|
UI.error("Error uploading #{logType} #{response.status}: #{response.body}")
|
||||||
self.update_dsym_upload(api_token, owner_name, app_name, symbol_upload_id, 'aborted')
|
self.update_symbol_upload(api_token, owner_name, app_name, symbol_upload_id, 'aborted')
|
||||||
UI.error("dSYM upload aborted")
|
UI.error("#{logType} upload aborted")
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,6 +38,16 @@ def stub_create_dsym_upload(status)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stub_create_mapping_upload(status, version, build, file_name = "mapping.txt")
|
||||||
|
stub_request(:post, "https://api.appcenter.ms/v0.1/apps/owner/app/symbol_uploads")
|
||||||
|
.with(body: "{\"symbol_type\":\"AndroidProguard\",\"file_name\":\"#{file_name}\",\"build\":\"3\",\"version\":\"1.0.0\"}",)
|
||||||
|
.to_return(
|
||||||
|
status: status,
|
||||||
|
body: "",
|
||||||
|
headers: { 'Content-Type' => 'application/json' }
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
def stub_upload_build(status)
|
def stub_upload_build(status)
|
||||||
stub_request(:post, "https://upload.com/")
|
stub_request(:post, "https://upload.com/")
|
||||||
.to_return(status: status, body: "", headers: {})
|
.to_return(status: status, body: "", headers: {})
|
||||||
|
@ -48,6 +58,11 @@ def stub_upload_dsym(status)
|
||||||
.to_return(status: status, body: "", headers: {})
|
.to_return(status: status, body: "", headers: {})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stub_upload_mapping(status)
|
||||||
|
stub_request(:put, "https://upload_dsym.com/")
|
||||||
|
.to_return(status: status, body: "", headers: {})
|
||||||
|
end
|
||||||
|
|
||||||
def stub_update_release_upload(status, release_status)
|
def stub_update_release_upload(status, release_status)
|
||||||
stub_request(:patch, "https://api.appcenter.ms/v0.1/apps/owner/app/release_uploads/upload_id")
|
stub_request(:patch, "https://api.appcenter.ms/v0.1/apps/owner/app/release_uploads/upload_id")
|
||||||
.with(
|
.with(
|
||||||
|
@ -64,6 +79,14 @@ def stub_update_dsym_upload(status, release_status)
|
||||||
.to_return(status: status, body: "{\"release_id\":\"1\"}", headers: { 'Content-Type' => 'application/json' })
|
.to_return(status: status, body: "{\"release_id\":\"1\"}", headers: { 'Content-Type' => 'application/json' })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stub_update_mapping_upload(status, release_status)
|
||||||
|
stub_request(:patch, "https://api.appcenter.ms/v0.1/apps/owner/app/symbol_uploads/symbol_upload_id")
|
||||||
|
.with(
|
||||||
|
body: "{\"status\":\"#{release_status}\"}"
|
||||||
|
)
|
||||||
|
.to_return(status: status, body: "{\"release_id\":\"1\"}", headers: { 'Content-Type' => 'application/json' })
|
||||||
|
end
|
||||||
|
|
||||||
def stub_get_destination(status, destination_type = "group", destination_name = "Testers")
|
def stub_get_destination(status, destination_type = "group", destination_name = "Testers")
|
||||||
stub_request(:get, "https://api.appcenter.ms/v0.1/apps/owner/app/distribution_#{destination_type}s/#{destination_name}")
|
stub_request(:get, "https://api.appcenter.ms/v0.1/apps/owner/app/distribution_#{destination_type}s/#{destination_name}")
|
||||||
.to_return(status: status, body: "{\"id\":\"1\"}", headers: { 'Content-Type' => 'application/json' })
|
.to_return(status: status, body: "{\"id\":\"1\"}", headers: { 'Content-Type' => 'application/json' })
|
||||||
|
@ -746,6 +769,81 @@ describe Fastlane::Actions::AppcenterUploadAction do
|
||||||
end").runner.execute(:test)
|
end").runner.execute(:test)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "allows to send android mappings" do
|
||||||
|
stub_check_app(200)
|
||||||
|
stub_create_release_upload(200)
|
||||||
|
stub_upload_build(200)
|
||||||
|
stub_update_release_upload(200, 'committed')
|
||||||
|
stub_update_release(200)
|
||||||
|
stub_get_destination(200)
|
||||||
|
stub_add_to_destination(200)
|
||||||
|
stub_get_release(200)
|
||||||
|
stub_create_mapping_upload(200, "1.0.0", "3")
|
||||||
|
stub_upload_mapping(200)
|
||||||
|
stub_update_mapping_upload(200, "committed")
|
||||||
|
|
||||||
|
Fastlane::FastFile.new.parse("lane :test do
|
||||||
|
appcenter_upload({
|
||||||
|
api_token: 'xxx',
|
||||||
|
owner_name: 'owner',
|
||||||
|
app_name: 'app',
|
||||||
|
apk: './spec/fixtures/appfiles/apk_file_empty.apk',
|
||||||
|
mapping: './spec/fixtures/symbols/mapping.txt',
|
||||||
|
build_number: '3',
|
||||||
|
version: '1.0.0',
|
||||||
|
destinations: 'Testers',
|
||||||
|
destination_type: 'group'
|
||||||
|
})
|
||||||
|
end").runner.execute(:test)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows to send android mappings with custom name" do
|
||||||
|
stub_check_app(200)
|
||||||
|
stub_create_release_upload(200)
|
||||||
|
stub_upload_build(200)
|
||||||
|
stub_update_release_upload(200, 'committed')
|
||||||
|
stub_update_release(200)
|
||||||
|
stub_get_destination(200)
|
||||||
|
stub_add_to_destination(200)
|
||||||
|
stub_get_release(200)
|
||||||
|
stub_create_mapping_upload(200, "1.0.0", "3", "renamed-mapping.txt")
|
||||||
|
stub_upload_mapping(200)
|
||||||
|
stub_update_mapping_upload(200, "committed")
|
||||||
|
|
||||||
|
Fastlane::FastFile.new.parse("lane :test do
|
||||||
|
appcenter_upload({
|
||||||
|
api_token: 'xxx',
|
||||||
|
owner_name: 'owner',
|
||||||
|
app_name: 'app',
|
||||||
|
apk: './spec/fixtures/appfiles/apk_file_empty.apk',
|
||||||
|
mapping: './spec/fixtures/symbols/renamed-mapping.txt',
|
||||||
|
build_number: '3',
|
||||||
|
version: '1.0.0',
|
||||||
|
destinations: 'Testers',
|
||||||
|
destination_type: 'group'
|
||||||
|
})
|
||||||
|
end").runner.execute(:test)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "allows to send only android mappings" do
|
||||||
|
stub_check_app(200)
|
||||||
|
stub_create_mapping_upload(200, "1.0.0", "3", "renamed-mapping.txt")
|
||||||
|
stub_upload_mapping(200)
|
||||||
|
stub_update_mapping_upload(200, "committed")
|
||||||
|
|
||||||
|
Fastlane::FastFile.new.parse("lane :test do
|
||||||
|
appcenter_upload({
|
||||||
|
api_token: 'xxx',
|
||||||
|
owner_name: 'owner',
|
||||||
|
app_name: 'app',
|
||||||
|
upload_mapping_only: true,
|
||||||
|
mapping: './spec/fixtures/symbols/renamed-mapping.txt',
|
||||||
|
build_number: '3',
|
||||||
|
version: '1.0.0'
|
||||||
|
})
|
||||||
|
end").runner.execute(:test)
|
||||||
|
end
|
||||||
|
|
||||||
it "zips dSYM files if dsym parameter is folder" do
|
it "zips dSYM files if dsym parameter is folder" do
|
||||||
stub_check_app(200)
|
stub_check_app(200)
|
||||||
stub_create_release_upload(200)
|
stub_create_release_upload(200)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче