fastlane-plugin-sapfire 1.0.0
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/LICENSE +21 -0
- data/README.md +135 -0
- data/lib/fastlane/plugin/sapfire/actions/app_certification_action.rb +79 -0
- data/lib/fastlane/plugin/sapfire/actions/associate_ms_store_action.rb +263 -0
- data/lib/fastlane/plugin/sapfire/actions/build_uwp_app_action.rb +55 -0
- data/lib/fastlane/plugin/sapfire/actions/dotnet_select_action.rb +46 -0
- data/lib/fastlane/plugin/sapfire/actions/ensure_dotnet_version_action.rb +123 -0
- data/lib/fastlane/plugin/sapfire/actions/ms_credentials_action.rb +91 -0
- data/lib/fastlane/plugin/sapfire/actions/msbuild_action.rb +45 -0
- data/lib/fastlane/plugin/sapfire/actions/msbuild_select_action.rb +53 -0
- data/lib/fastlane/plugin/sapfire/actions/nuget_pack_action.rb +46 -0
- data/lib/fastlane/plugin/sapfire/actions/update_uwp_signing_settings_action.rb +73 -0
- data/lib/fastlane/plugin/sapfire/actions/upload_ms_store_action.rb +218 -0
- data/lib/fastlane/plugin/sapfire/actions/upload_nuget_action.rb +95 -0
- data/lib/fastlane/plugin/sapfire/actions_base/msbuild_action_base.rb +42 -0
- data/lib/fastlane/plugin/sapfire/helper/ms_devcenter_helper.rb +292 -0
- data/lib/fastlane/plugin/sapfire/helper/sapfire_helper.rb +55 -0
- data/lib/fastlane/plugin/sapfire/msbuild/module.rb +34 -0
- data/lib/fastlane/plugin/sapfire/msbuild/options.rb +123 -0
- data/lib/fastlane/plugin/sapfire/msbuild/runner.rb +171 -0
- data/lib/fastlane/plugin/sapfire/sln_project/block.rb +30 -0
- data/lib/fastlane/plugin/sapfire/sln_project/global_block.rb +147 -0
- data/lib/fastlane/plugin/sapfire/sln_project/module.rb +14 -0
- data/lib/fastlane/plugin/sapfire/sln_project/project_block.rb +82 -0
- data/lib/fastlane/plugin/sapfire/sln_project/root_block.rb +72 -0
- data/lib/fastlane/plugin/sapfire/version.rb +5 -0
- data/lib/fastlane/plugin/sapfire.rb +16 -0
- metadata +182 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8e3383a3f917a4dba8d2c43dfdbbf597d1f29e6770d4f6f799b8fc1725a056b5
|
4
|
+
data.tar.gz: 69ab3275172df5edcecc365f8202f40c145d31bb690cf7a8e8a322d9499ee526
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 79f0683b16c2684293d88eaa4a1b4d0327034120e4af61cc7903a28359d6eb217eceb6a5a1f1467b7dab2b38ddb20b7b5c01d1970d32ad3e402cf1a6c16a0275
|
7
|
+
data.tar.gz: f45c506a139c7020e5eac351b8884c46a5258a43c92968436bc36c28832cd570b461dc5d3813d9d0c3816e6999d3548d06917bc45e0e07ecdf1acfd246e36bfb
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2023 Alexander Pluzhnikov
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,135 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<a href="#">
|
3
|
+
<img src="https://raw.githubusercontent.com/CheeryLee/fastlane-plugin-sapfire/master/assets/sapfire_logo.png" height="150" />
|
4
|
+
</a>
|
5
|
+
</p>
|
6
|
+
|
7
|
+
# Sapfire
|
8
|
+
[](https://opensource.org/licenses/MIT)
|
9
|
+

|
10
|
+
|
11
|
+
<br/>
|
12
|
+
<p align="center">An incredibly simple and fast way to automate building and deployment <b>Visual C++</b>, <b>.NET</b> and <b>UWP</b> apps</p>
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
## What is it?
|
16
|
+
_Sapfire_ is a fastlane plugin that provides a bunch of actions to work with MSBuild, NuGet and Microsoft Store app submission.
|
17
|
+
|
18
|
+
**MSBuild** is a set of open-source build tools created by Microsoft. It is included with Visual Studio,
|
19
|
+
but also can be used independently via command-line interface.
|
20
|
+
|
21
|
+
**NuGet** is a package manager, primarily used for packaging and distributing software written using the .NET.
|
22
|
+
|
23
|
+
**Microsoft Store** is a digital distribution platform for Windows.
|
24
|
+
|
25
|
+
## Getting started
|
26
|
+
To get started working with plugin, add it to your `fastlane/Pluginfile`:
|
27
|
+
```ruby
|
28
|
+
gem "fastlane-plugin-sapfire", git: "https://github.com/fastlane/fastlane-plugin-sapfire"
|
29
|
+
```
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
### Platform support note
|
33
|
+
First of all it's important to denote that some of actions or their parameters (such as `msbuild` for UWP) are working
|
34
|
+
on Windows only. Currently _fastlane_ is not officially supported on this platform. Despite this fact it's still possible to run it.
|
35
|
+
|
36
|
+
Actions or parameters with such restriction contain the corresponding mark in documentation.
|
37
|
+
|
38
|
+
If you want to use them, be sure that the platform name of the build lanes is **windows**:
|
39
|
+
```ruby
|
40
|
+
platform :windows do
|
41
|
+
# your lanes
|
42
|
+
end
|
43
|
+
```
|
44
|
+
|
45
|
+
### Help
|
46
|
+
Once installed, the information for an action can be printed out with this command:
|
47
|
+
```shell
|
48
|
+
fastlane action msbuild # or any action included with this plugin
|
49
|
+
```
|
50
|
+
|
51
|
+
### Actions
|
52
|
+
Here is the list of all available actions. Read the documentation on each one by clicking on the action name.
|
53
|
+
|
54
|
+
#### 🔨 Building
|
55
|
+
|
56
|
+
| Argument | Description | Supported platforms |
|
57
|
+
|----------------------------------------------------------------|-------------------------------------------------------------------|--------------------:|
|
58
|
+
| [msbuild_select](docs/actions/msbuild_select.md) | Changes the MSBuild executable to use | all |
|
59
|
+
| [msbuild](docs/actions/msbuild.md) | Wraps all parameters and executes MSBuild | all |
|
60
|
+
| [build_uwp_app](docs/actions/build_uwp_app.md) | Alias for the `msbuild` action with additional parameters for UWP | windows |
|
61
|
+
| [dotnet_select](docs/actions/dotnet_select.md) | Changes the dotnet executable to use | all |
|
62
|
+
| [ensure_dotnet_version](docs/actions/ensure_dotnet_version.md) | Ensures the right version of .NET is installed and can be used | all |
|
63
|
+
| [associate_ms_store](docs/actions/associate_ms_store.md) | Makes a local app manifest needed for Microsoft Store association | windows |
|
64
|
+
| [nuget_pack](docs/actions/nuget_pack.md) | Executes MSBuild to create a NuGet package | all |
|
65
|
+
|
66
|
+
#### 🔑 Signing
|
67
|
+
|
68
|
+
| Argument | Description | Supported platforms |
|
69
|
+
|----------------------------------------------------------------------------|-----------------------------------------|--------------------:|
|
70
|
+
| [update_uwp_signing_settings](docs/actions/update_uwp_signing_settings.md) | Configures UWP package signing settings | windows |
|
71
|
+
|
72
|
+
#### 🔧 Testing
|
73
|
+
|
74
|
+
| Argument | Description | Supported platforms |
|
75
|
+
|--------------------------------------------------------|-----------------------------------------------------------------------------|--------------------:|
|
76
|
+
| [app_certification](docs/actions/app_certification.md) | Runs Windows App Certification Kit to ensure your app is safe and efficient | windows |
|
77
|
+
|
78
|
+
|
79
|
+
#### 📦 Releasing
|
80
|
+
|
81
|
+
| Argument | Description | Supported platforms |
|
82
|
+
|----------------------------------------------------|-------------------------------------------------|--------------------:|
|
83
|
+
| [upload_ms_store](docs/actions/upload_ms_store.md) | Uploads new binary to Microsoft Partner Center | windows |
|
84
|
+
| [upload_nuget](docs/actions/upload_nuget.md) | Pushes a package to the server and publishes it | all |
|
85
|
+
|
86
|
+
#### 🔆 Misc
|
87
|
+
|
88
|
+
| Argument | Description | Supported platforms |
|
89
|
+
|--------------------------------------------------|-----------------------------------------------|--------------------:|
|
90
|
+
| [ms_credentials](docs/actions/ms_credentials.md) | Sets Azure AD credentials for further actions | windows |
|
91
|
+
|
92
|
+
|
93
|
+
## Working with SLN solution
|
94
|
+
In addition this plugin provides a parser module for Microsoft SLN file format.
|
95
|
+
|
96
|
+
To open a solution, run this:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
require "fastlane/plugin/sapfire/sln_project/sln_project"
|
100
|
+
|
101
|
+
root_block = Module.open("/cygdrive/c/Projects/My_Project.sln")
|
102
|
+
puts root_block.projects[0] # print name of the first subproject in solution
|
103
|
+
```
|
104
|
+
|
105
|
+
## Run tests for this plugin
|
106
|
+
|
107
|
+
To run both the tests, and code style validation, run
|
108
|
+
|
109
|
+
```shell
|
110
|
+
rake
|
111
|
+
```
|
112
|
+
|
113
|
+
To automatically fix many of the styling issues, use
|
114
|
+
```shell
|
115
|
+
rubocop -a
|
116
|
+
```
|
117
|
+
|
118
|
+
## Issues and Feedback
|
119
|
+
|
120
|
+
For any other issues and feedback about this plugin, please open a [GitHub issue](https://github.com/CheeryLee/fastlane-plugin-sapfire/issues).
|
121
|
+
|
122
|
+
## Troubleshooting
|
123
|
+
|
124
|
+
If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
|
125
|
+
|
126
|
+
## Using _fastlane_ Plugins
|
127
|
+
|
128
|
+
For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
|
129
|
+
|
130
|
+
## About _fastlane_
|
131
|
+
|
132
|
+
_fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
|
133
|
+
|
134
|
+
## License
|
135
|
+
This project is licensed under [the MIT license](LICENSE).
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require "fastlane/action"
|
2
|
+
require_relative "../helper/sapfire_helper"
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Actions
|
6
|
+
class AppCertificationAction < Action
|
7
|
+
def self.run(params)
|
8
|
+
path = Helper::SapfireHelper.kits_10_location
|
9
|
+
UI.user_error!("Can't locate Windows SDK. Ensure it's installed.") if path.empty?
|
10
|
+
UI.message("Windows SDK path: #{path}")
|
11
|
+
|
12
|
+
appcert_path = File.join(path, "App Certification Kit/appcert.exe")
|
13
|
+
UI.user_error!("Can't find appcert.exe. Check your Windows SDK installation.") unless File.exist?(appcert_path)
|
14
|
+
|
15
|
+
cmd = "\"#{appcert_path}\" reset"
|
16
|
+
UI.command(cmd)
|
17
|
+
wait_thr = run_appcert(cmd)
|
18
|
+
UI.user_error!("Appcert reset failed. See the log above.") unless wait_thr.value.success?
|
19
|
+
|
20
|
+
cmd = "\"#{appcert_path}\" test -appxpackagepath \"#{params[:appx_package_path]}\" -reportoutputpath \"#{params[:output_path]}\""
|
21
|
+
UI.command(cmd)
|
22
|
+
wait_thr = run_appcert(cmd)
|
23
|
+
UI.user_error!("Appcert checking failed. See the log above.") unless wait_thr.value.success?
|
24
|
+
UI.success("App checking has successfully finished. Output result saved at: #{params[:output_path]}") if wait_thr.value.success?
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.description
|
28
|
+
"Runs Windows App Certification Kit to ensure your app is safe and efficient before publishing it to Microsoft Store"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.authors
|
32
|
+
["CheeryLee"]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.is_supported?(platform)
|
36
|
+
[:windows].include?(platform)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.available_options
|
40
|
+
[
|
41
|
+
FastlaneCore::ConfigItem.new(
|
42
|
+
key: :appx_package_path,
|
43
|
+
description: "The full path to a UWP package",
|
44
|
+
optional: false,
|
45
|
+
type: String,
|
46
|
+
verify_block: proc do |value|
|
47
|
+
UI.user_error!("Path to UWP package is invalid") unless value && !value.empty?
|
48
|
+
UI.user_error!("The provided path doesn't point to APPX-file") unless
|
49
|
+
File.exist?(File.expand_path(value)) && value.end_with?(".appx")
|
50
|
+
end
|
51
|
+
),
|
52
|
+
FastlaneCore::ConfigItem.new(
|
53
|
+
key: :output_path,
|
54
|
+
description: "The path where to save report output XML-file",
|
55
|
+
optional: false,
|
56
|
+
type: String
|
57
|
+
)
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.category
|
62
|
+
:testing
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.run_appcert(cmd)
|
66
|
+
Open3.popen2(cmd) do |_, stdout, wait_thr|
|
67
|
+
until stdout.eof?
|
68
|
+
stdout.each do |l|
|
69
|
+
line = l.force_encoding("utf-8").chomp
|
70
|
+
puts line
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
wait_thr
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require "uri"
|
2
|
+
require "net/http"
|
3
|
+
require "json"
|
4
|
+
require "fastlane/action"
|
5
|
+
|
6
|
+
module Fastlane
|
7
|
+
module Actions
|
8
|
+
class AssociateMsStoreAction < Action
|
9
|
+
XML_NAME = "Package.StoreAssociation.xml".freeze
|
10
|
+
|
11
|
+
def self.run(params)
|
12
|
+
FastlaneCore::PrintTable.print_values(config: params, title: "Summary for associate_ms_store")
|
13
|
+
|
14
|
+
begin
|
15
|
+
UI.message("Creating #{XML_NAME}...")
|
16
|
+
|
17
|
+
token = acquire_authorization_token
|
18
|
+
developer_info = get_developer_info(token)
|
19
|
+
app_info = get_app_info(token, params[:app_id])
|
20
|
+
create_xml(params[:manifest], developer_info, app_info)
|
21
|
+
|
22
|
+
UI.message("#{XML_NAME} successfully created")
|
23
|
+
rescue StandardError => ex
|
24
|
+
UI.user_error!("Something went wrong while associating the project: #{ex}")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.create_xml(manifest_path, developer_info, app_info)
|
29
|
+
app_identity = app_info[:identity]
|
30
|
+
app_names = app_info[:names]
|
31
|
+
publisher = developer_info[:publisher]
|
32
|
+
publisher_display_name = developer_info[:display_name]
|
33
|
+
appxmanifest_xml = get_appxmanifest_xml(manifest_path)
|
34
|
+
|
35
|
+
UI.message("Set identity name: #{app_identity}")
|
36
|
+
|
37
|
+
begin
|
38
|
+
identity_entry = appxmanifest_xml.elements["Package"]
|
39
|
+
.elements["Identity"]
|
40
|
+
identity_entry.attributes["Name"] = app_identity
|
41
|
+
identity_entry.attributes["Publisher"] = publisher
|
42
|
+
|
43
|
+
properties_entry = appxmanifest_xml.elements["Package"]
|
44
|
+
.elements["Properties"]
|
45
|
+
properties_entry.elements["DisplayName"].text = app_names[0] unless app_names.empty?
|
46
|
+
properties_entry.elements["PublisherDisplayName"].text = publisher_display_name
|
47
|
+
rescue StandardError => ex
|
48
|
+
UI.user_error!("Can't update app manifest: #{ex}")
|
49
|
+
end
|
50
|
+
|
51
|
+
save_xml(appxmanifest_xml, manifest_path)
|
52
|
+
|
53
|
+
UI.message("Set publisher data: #{publisher}")
|
54
|
+
UI.message("Set publisher display name: #{publisher_display_name}")
|
55
|
+
|
56
|
+
document = REXML::Document.new
|
57
|
+
document.xml_decl.version = "1.0"
|
58
|
+
document.xml_decl.encoding = "utf-8"
|
59
|
+
|
60
|
+
store_association = document.add_element("StoreAssociation", {
|
61
|
+
"xmlns" => "http://schemas.microsoft.com/appx/2010/storeassociation"
|
62
|
+
})
|
63
|
+
store_association.add_element("Publisher").text = publisher
|
64
|
+
store_association.add_element("PublisherDisplayName").text = publisher_display_name
|
65
|
+
store_association.add_element("DeveloperAccountType").text = "WSA"
|
66
|
+
store_association.add_element("GeneratePackageHash").text = "http://www.w3.org/2001/04/xmlenc#sha256"
|
67
|
+
|
68
|
+
product_reserved_info = store_association.add_element("ProductReservedInfo")
|
69
|
+
product_reserved_info.add_element("MainPackageIdentityName").text = app_identity
|
70
|
+
|
71
|
+
reserved_names = product_reserved_info.add_element("ReservedNames")
|
72
|
+
app_names.each do |x|
|
73
|
+
reserved_names.add_element("ReservedName").text = x
|
74
|
+
end
|
75
|
+
|
76
|
+
working_directory = File.dirname(manifest_path)
|
77
|
+
path = File.join(working_directory, XML_NAME)
|
78
|
+
save_xml(document, path)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.get_appxmanifest_xml(manifest_path)
|
82
|
+
file = File.open(manifest_path, "r")
|
83
|
+
|
84
|
+
begin
|
85
|
+
document = REXML::Document.new(file)
|
86
|
+
file.close
|
87
|
+
document
|
88
|
+
rescue REXML::ParseException => ex
|
89
|
+
UI.user_error!("Can't parse Package.appxmanifest: #{ex}")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.save_xml(document, path)
|
94
|
+
file = File.open(path, "w")
|
95
|
+
document.write(file)
|
96
|
+
file.close
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.get_developer_info(token)
|
100
|
+
UI.message("Obtaining developer info ...")
|
101
|
+
|
102
|
+
headers = {
|
103
|
+
"Authorization": "Bearer #{token}",
|
104
|
+
"Accept": "application/json",
|
105
|
+
"MS-Contract-Version": "1"
|
106
|
+
}
|
107
|
+
query = {
|
108
|
+
setvar: "fltaad:1"
|
109
|
+
}
|
110
|
+
|
111
|
+
uri = URI("https://developer.microsoft.com/vsapi/developer")
|
112
|
+
uri.query = URI.encode_www_form(query)
|
113
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
114
|
+
https.use_ssl = true
|
115
|
+
request = Net::HTTP::Get.new(uri, headers)
|
116
|
+
response = https.request(request)
|
117
|
+
|
118
|
+
begin
|
119
|
+
data = JSON.parse(response.body)
|
120
|
+
|
121
|
+
if response.code == "200"
|
122
|
+
UI.message("Developer info was obtained")
|
123
|
+
return {
|
124
|
+
display_name: data["PublisherDisplayName"],
|
125
|
+
publisher: data["Publisher"]
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
UI.user_error!("Request returned the error: #{response.code}")
|
130
|
+
rescue StandardError => ex
|
131
|
+
UI.user_error!("Developer info request failed: #{ex}")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def self.get_app_info(token, app_id)
|
136
|
+
UI.message("Obtaining application info ...")
|
137
|
+
|
138
|
+
headers = {
|
139
|
+
"Authorization": "Bearer #{token}",
|
140
|
+
"Accept": "application/json",
|
141
|
+
"MS-Contract-Version": "1"
|
142
|
+
}
|
143
|
+
query = {
|
144
|
+
setvar: "fltaad:1"
|
145
|
+
}
|
146
|
+
|
147
|
+
uri = URI("https://developer.microsoft.com/vsapi/applications")
|
148
|
+
uri.query = URI.encode_www_form(query)
|
149
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
150
|
+
https.use_ssl = true
|
151
|
+
request = Net::HTTP::Get.new(uri, headers)
|
152
|
+
response = https.request(request)
|
153
|
+
|
154
|
+
begin
|
155
|
+
data = JSON.parse(response.body)
|
156
|
+
|
157
|
+
if response.code == "200"
|
158
|
+
UI.message("Application info was obtained")
|
159
|
+
|
160
|
+
product = data["Products"].find { |x| x["LandingUrl"].include?(app_id) }
|
161
|
+
return {
|
162
|
+
identity: product["MainPackageIdentityName"],
|
163
|
+
names: product["ReservedNames"]
|
164
|
+
}
|
165
|
+
end
|
166
|
+
|
167
|
+
UI.user_error!("Request returned the error: #{response.code}")
|
168
|
+
rescue StandardError => ex
|
169
|
+
UI.user_error!("Application info request failed: #{ex}")
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.acquire_authorization_token
|
174
|
+
UI.message("Acquiring authorization token ...")
|
175
|
+
|
176
|
+
username = Actions.lane_context[SharedValues::SF_MS_USERNAME]
|
177
|
+
password = Actions.lane_context[SharedValues::SF_MS_PASSWORD]
|
178
|
+
tenant_id = Actions.lane_context[SharedValues::SF_MS_TENANT_ID]
|
179
|
+
client_id = Actions.lane_context[SharedValues::SF_MS_CLIENT_ID]
|
180
|
+
client_secret = Actions.lane_context[SharedValues::SF_MS_CLIENT_SECRET]
|
181
|
+
|
182
|
+
body = {
|
183
|
+
client_id: client_id,
|
184
|
+
client_secret: client_secret,
|
185
|
+
client_info: 1,
|
186
|
+
grant_type: "password",
|
187
|
+
scope: "https://management.azure.com/.default offline_access openid profile",
|
188
|
+
username: username,
|
189
|
+
password: password
|
190
|
+
}
|
191
|
+
headers = {
|
192
|
+
"x-anchormailbox": "upn:#{username}",
|
193
|
+
"x-client-sku": "fastlane-sapfire-plugin",
|
194
|
+
"Accept": "application/json"
|
195
|
+
}
|
196
|
+
|
197
|
+
uri = URI("https://login.microsoftonline.com/#{tenant_id}/oauth2/v2.0/token")
|
198
|
+
https = Net::HTTP.new(uri.host, uri.port)
|
199
|
+
https.use_ssl = true
|
200
|
+
request = Net::HTTP::Post.new(uri, headers)
|
201
|
+
request_body = URI.encode_www_form(body)
|
202
|
+
response = https.request(request, request_body)
|
203
|
+
|
204
|
+
begin
|
205
|
+
data = JSON.parse(response.body)
|
206
|
+
|
207
|
+
if response.code == "200"
|
208
|
+
UI.message("Authorization token was obtained")
|
209
|
+
return data["access_token"]
|
210
|
+
end
|
211
|
+
|
212
|
+
error = data["error"]
|
213
|
+
error_description = data["error_description"]
|
214
|
+
|
215
|
+
UI.user_error!("Request returned the error.\nCode: #{error}.\nDescription: #{error_description}")
|
216
|
+
rescue StandardError => ex
|
217
|
+
UI.user_error!("Authorization failed: #{ex}")
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.description
|
222
|
+
"Makes a local app manifest needed for Microsoft Store association"
|
223
|
+
end
|
224
|
+
|
225
|
+
def self.authors
|
226
|
+
["CheeryLee"]
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.is_supported?(platform)
|
230
|
+
[:windows].include?(platform)
|
231
|
+
end
|
232
|
+
|
233
|
+
def self.available_options
|
234
|
+
[
|
235
|
+
FastlaneCore::ConfigItem.new(
|
236
|
+
key: :manifest,
|
237
|
+
description: "Path to the APPX package manifest",
|
238
|
+
optional: false,
|
239
|
+
type: String,
|
240
|
+
verify_block: proc do |value|
|
241
|
+
UI.user_error!("Path to the APPX package manifest is invalid") unless value && !value.empty?
|
242
|
+
UI.user_error!("The provided path doesn't point to AppxManifest-file") unless
|
243
|
+
File.exist?(File.expand_path(value)) && value.end_with?(".appxmanifest")
|
244
|
+
end
|
245
|
+
),
|
246
|
+
FastlaneCore::ConfigItem.new(
|
247
|
+
key: :app_id,
|
248
|
+
description: "The Microsoft Store ID of an application",
|
249
|
+
optional: false,
|
250
|
+
type: String,
|
251
|
+
verify_block: proc do |value|
|
252
|
+
UI.user_error!("The Microsoft Store ID can't be empty") unless value && !value.empty?
|
253
|
+
end
|
254
|
+
)
|
255
|
+
]
|
256
|
+
end
|
257
|
+
|
258
|
+
def self.category
|
259
|
+
:project
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "fastlane/action"
|
2
|
+
require_relative "../actions_base/msbuild_action_base"
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Actions
|
6
|
+
class BuildUwpAppAction < MsbuildActionBase
|
7
|
+
def self.run(params)
|
8
|
+
Msbuild.config.certificate = Actions.lane_context[SharedValues::SF_CERTIFICATE_PATH]
|
9
|
+
Msbuild.config.certificate_password = Actions.lane_context[SharedValues::SF_CERTIFICATE_PASSWORD]
|
10
|
+
Msbuild.config.certificate_thumbprint = Actions.lane_context[SharedValues::SF_CERTIFICATE_THUMBPRINT]
|
11
|
+
Msbuild.config.build_type = Msbuild::BuildType::UWP
|
12
|
+
|
13
|
+
super(params)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.overwritten_msbuild_properties
|
17
|
+
props = {
|
18
|
+
AppxPackageDir: "appx_output_path",
|
19
|
+
AppxBundlePlatforms: "appx_bundle_platforms",
|
20
|
+
UapAppxPackageBuildMode: "build_mode",
|
21
|
+
AppxPackageSigningEnabled: "skip_codesigning"
|
22
|
+
}
|
23
|
+
super.merge(props)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.description
|
27
|
+
"Alias for the `msbuild` action with additional parameters for UWP"
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.details
|
31
|
+
[
|
32
|
+
"Works only on `windows` platform.",
|
33
|
+
"The `:platform` value must contain the same value as `:appx_bundle_platforms` does.",
|
34
|
+
"If `appx_bundle_platforms` is set to be multiplatform, then any of platforms from it's list must be set in the `:platform` option"
|
35
|
+
].join("\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.authors
|
39
|
+
["CheeryLee"]
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.is_supported?(platform)
|
43
|
+
[:windows].include?(platform)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.rejected_options
|
47
|
+
nil
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.category
|
51
|
+
:building
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "fastlane/action"
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Actions
|
5
|
+
module SharedValues
|
6
|
+
SF_DOTNET_PATH = :SF_DOTNET_PATH
|
7
|
+
end
|
8
|
+
|
9
|
+
class DotnetSelectAction < Action
|
10
|
+
def self.run(params)
|
11
|
+
path = (params || []).first.to_s
|
12
|
+
path = File.expand_path(path)
|
13
|
+
|
14
|
+
UI.user_error!("File '#{path}' doesn't exist") unless File.exist?(path)
|
15
|
+
UI.user_error!("Path to dotnet executable required") if
|
16
|
+
path.empty? || (!path.end_with?("dotnet") && !path.end_with?("dotnet.exe"))
|
17
|
+
|
18
|
+
Actions.lane_context[SharedValues::SF_DOTNET_PATH] = path
|
19
|
+
|
20
|
+
UI.message("Setting dotnet executable to '#{path}' for all next build steps")
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.description
|
24
|
+
"Changes the dotnet executable to use"
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.authors
|
28
|
+
["CheeryLee"]
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.is_supported?(platform)
|
32
|
+
true
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.example_code
|
36
|
+
[
|
37
|
+
'dotnet_select("C:/Program\ Files/dotnet/dotnet.exe")'
|
38
|
+
]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.category
|
42
|
+
:building
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|