fastlane-plugin-nico 0.10.6
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 +100 -0
- data/lib/fastlane/plugin/emerge/actions/emerge_action.rb +227 -0
- data/lib/fastlane/plugin/emerge/actions/emerge_comment_action.rb +86 -0
- data/lib/fastlane/plugin/emerge/actions/emerge_order_file_action.rb +77 -0
- data/lib/fastlane/plugin/emerge/actions/emerge_snapshot_action.rb +162 -0
- data/lib/fastlane/plugin/emerge/helper/emerge_helper.rb +140 -0
- data/lib/fastlane/plugin/emerge/helper/git.rb +106 -0
- data/lib/fastlane/plugin/emerge/helper/github.rb +88 -0
- data/lib/fastlane/plugin/emerge/version.rb +5 -0
- data/lib/fastlane/plugin/emerge.rb +16 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 259c370e91a20c3cd611d0c7c177e77e8513d5e1d9e3475cdb95b5f3371549e6
|
4
|
+
data.tar.gz: 243639ffeb90a983f58a92d3e8662bfaf8878af2217cb0077f2fc9349994ed9e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: aee24183a3debfd3c4b99612737426f8047df98bdb9bf9111aabf9dae35f2a5862d7a9aea1a516fc19a1a1074196b29056063ab8f6beb06965cf99db4a434645
|
7
|
+
data.tar.gz: 7b5cad5c552acde4ff08d1415be04540337f74224117c4bd6ee30e5d12dedc97a6d48a2d6a274f56d4bc718d0df580422f1cf02c8de86581544a7d15e1f71b13
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2020 Noah Martin <noahm444@gmail.com>
|
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,100 @@
|
|
1
|
+
# Emerge `fastlane` plugin
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/fastlane-plugin-emerge)
|
4
|
+
|
5
|
+
## Getting Started
|
6
|
+
|
7
|
+
This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `fastlane-plugin-emerge`, add it to your project by running:
|
8
|
+
|
9
|
+
```bash
|
10
|
+
fastlane add_plugin emerge
|
11
|
+
```
|
12
|
+
|
13
|
+
## About Emerge
|
14
|
+
|
15
|
+
[Emerge](https://emergetools.com) offers a suite of products to help optimize app size, performance and quality. This plugin provides a set of actions to interact with the Emerge API.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
To get started, first obtain an [API token](https://docs.emergetools.com/docs/uploading-basics#obtain-an-api-key) for your organization. The API Token is used to authenticate with the Emerge API in each call. Our actions will automatically pick up the API key if configured as an `EMERGE_API_TOKEN` environment variable.
|
20
|
+
|
21
|
+
### Size Analysis
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
platform :ios do
|
25
|
+
lane :emerge_upload do
|
26
|
+
# Tip: group builds in our dashboard via the `tag` parameter
|
27
|
+
emerge(tag: 'pr_build')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
1. Produce a build using `gym()`, `run_tests()`, or other Fastlane actions
|
33
|
+
2. When you are ready to upload to Emerge, simply call the `emerge()` action
|
34
|
+
- a. We will automatically detect the most recently built app to upload, or you can manually pass in a `file_path` parameter
|
35
|
+
|
36
|
+
For a full list of available parameters run `fastlane action emerge`.
|
37
|
+
|
38
|
+
### Snapshot Testing
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
platform :ios do
|
42
|
+
lane :snapshot_testing do
|
43
|
+
# Call our `emerge_snapshot()` action with the respective scheme for
|
44
|
+
# us to build. We will generate a build with the recommended settings
|
45
|
+
# and upload to our API.
|
46
|
+
emerge_snapshot(scheme: 'Hacker News')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
For a full list of available parameters run `fastlane action emerge_snapshot`.
|
52
|
+
|
53
|
+
## Git Configuration
|
54
|
+
|
55
|
+
For build comparisons to work, Emerge needs the appropriate Git `sha` and `base_sha` values set on each build. Emerge will automatically compare a build at `sha` against the build we find matching the `base_sha` for a given application id. We also recommend setting `pr_number`, `branch`, `repo_name`, and `previous_sha` for the best experience.
|
56
|
+
|
57
|
+
For example:
|
58
|
+
|
59
|
+
- `sha`: `pr-branch-commit-2`
|
60
|
+
- `base_sha`: `main-branch-commit-1`
|
61
|
+
- `previous_sha`: `pr-branch-commit-1`
|
62
|
+
- `pr_number`: `42`
|
63
|
+
- `branch`: `my-awesome-feature`
|
64
|
+
- `repo_name`: `EmergeTools/hackernews`
|
65
|
+
|
66
|
+
Will compare the size difference of your pull request changes.
|
67
|
+
|
68
|
+
This plugin will automatically configure Git values for you assuming certain Github workflow triggers:
|
69
|
+
|
70
|
+
```yaml
|
71
|
+
on:
|
72
|
+
# Produce base builds with a 'sha' when commits are pushed to the main branch
|
73
|
+
push:
|
74
|
+
branches: [main]
|
75
|
+
|
76
|
+
# Produce branch comparison builds with `sha` and `base_sha` when commits are pushed
|
77
|
+
# to open pull requests
|
78
|
+
pull_request:
|
79
|
+
branches: [main]
|
80
|
+
|
81
|
+
...
|
82
|
+
```
|
83
|
+
|
84
|
+
If this doesn't cover your use-case, manually set the `sha` and `base_sha` values when calling the Emerge plugin.
|
85
|
+
|
86
|
+
## Issues and Feedback
|
87
|
+
|
88
|
+
For any other issues and feedback about this plugin, please open a [GitHub issue](https://github.com/EmergeTools/fastlane-plugin-emerge/issues).
|
89
|
+
|
90
|
+
## Troubleshooting
|
91
|
+
|
92
|
+
If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
|
93
|
+
|
94
|
+
## Using _fastlane_ Plugins
|
95
|
+
|
96
|
+
For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
|
97
|
+
|
98
|
+
## About _fastlane_
|
99
|
+
|
100
|
+
_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).
|
@@ -0,0 +1,227 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fastlane_core/print_table'
|
3
|
+
require_relative '../helper/emerge_helper'
|
4
|
+
require_relative '../helper/git'
|
5
|
+
require_relative '../helper/github'
|
6
|
+
require 'pathname'
|
7
|
+
require 'tmpdir'
|
8
|
+
require 'json'
|
9
|
+
require 'fileutils'
|
10
|
+
|
11
|
+
module Fastlane
|
12
|
+
module Actions
|
13
|
+
class EmergeAction < Action
|
14
|
+
def self.run(params)
|
15
|
+
api_token = params[:api_token]
|
16
|
+
|
17
|
+
file_path = if params[:file_path]
|
18
|
+
UI.message("Using input file_path: #{file_path}")
|
19
|
+
params[:file_path]
|
20
|
+
elsif lane_context[SharedValues::XCODEBUILD_ARCHIVE]
|
21
|
+
UI.message("Using XCODEBUILD_ARCHIVE path")
|
22
|
+
lane_context[SharedValues::XCODEBUILD_ARCHIVE]
|
23
|
+
else
|
24
|
+
UI.message("Falling back to searching SCAN_DERIVED_DATA_PATH")
|
25
|
+
Dir.glob("#{lane_context[SharedValues::SCAN_DERIVED_DATA_PATH]}/Build/Products/Debug-iphonesimulator/*.app").first
|
26
|
+
end
|
27
|
+
|
28
|
+
git_params = Helper::EmergeHelper.make_git_params
|
29
|
+
pr_number = params[:pr_number] || git_params.pr_number
|
30
|
+
branch = params[:branch] || git_params.branch
|
31
|
+
sha = params[:sha] || params[:build_id] || git_params.sha
|
32
|
+
base_sha = params[:base_sha] || params[:base_build_id] || git_params.base_sha
|
33
|
+
previous_sha = params[:previous_sha] || git_params.previous_sha
|
34
|
+
repo_name = params[:repo_name] || git_params.repo_name
|
35
|
+
gitlab_project_id = params[:gitlab_project_id]
|
36
|
+
tag = params[:tag]
|
37
|
+
order_file_version = params[:order_file_version]
|
38
|
+
config_path = params[:config_path]
|
39
|
+
|
40
|
+
if file_path.nil? || !File.exist?(file_path)
|
41
|
+
UI.error("Invalid input file")
|
42
|
+
return false
|
43
|
+
else
|
44
|
+
UI.message("Using file_path: #{file_path}")
|
45
|
+
end
|
46
|
+
extension = File.extname(file_path)
|
47
|
+
|
48
|
+
# If the user provided a .app we will look for dsyms and package it into a zipped xcarchive
|
49
|
+
if extension == '.app'
|
50
|
+
absolute_path = Pathname.new(File.expand_path(file_path))
|
51
|
+
UI.message("A .app was provided, dSYMs will be looked for in #{absolute_path.dirname}")
|
52
|
+
Dir.mktmpdir do |d|
|
53
|
+
application_folder = "#{d}/archive.xcarchive/Products/Applications/"
|
54
|
+
dsym_folder = "#{d}/archive.xcarchive/dSYMs/"
|
55
|
+
FileUtils.mkdir_p(application_folder)
|
56
|
+
FileUtils.mkdir_p(dsym_folder)
|
57
|
+
if params[:linkmaps] && params[:linkmaps].length > 0
|
58
|
+
linkmap_folder = "#{d}/archive.xcarchive/Linkmaps/"
|
59
|
+
FileUtils.mkdir_p(linkmap_folder)
|
60
|
+
params[:linkmaps].each do |l|
|
61
|
+
FileUtils.cp(l, linkmap_folder)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
Helper::EmergeHelper.copy_config(config_path, "#{d}/archive.xcarchive")
|
65
|
+
FileUtils.cp_r(file_path, application_folder)
|
66
|
+
copy_dsyms("#{absolute_path.dirname}/*.dsym", dsym_folder)
|
67
|
+
copy_dsyms("#{absolute_path.dirname}/*/*.dsym", dsym_folder)
|
68
|
+
Xcodeproj::Plist.write_to_path({ "NAME" => "Emerge Upload" }, "#{d}/archive.xcarchive/Info.plist")
|
69
|
+
file_path = "#{absolute_path.dirname}/archive.xcarchive.zip"
|
70
|
+
ZipAction.run(
|
71
|
+
path: "#{d}/archive.xcarchive",
|
72
|
+
symlinks: true,
|
73
|
+
output_path: file_path,
|
74
|
+
exclude: [],
|
75
|
+
include: []
|
76
|
+
)
|
77
|
+
UI.message("Archive generated at #{file_path}")
|
78
|
+
end
|
79
|
+
elsif extension == '.xcarchive'
|
80
|
+
zip_path = file_path + ".zip"
|
81
|
+
if params[:linkmaps] && params[:linkmaps].length > 0
|
82
|
+
linkmap_folder = "#{file_path}/Linkmaps/"
|
83
|
+
FileUtils.mkdir_p(linkmap_folder)
|
84
|
+
params[:linkmaps].each do |l|
|
85
|
+
FileUtils.cp(l, linkmap_folder)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
Helper::EmergeHelper.copy_config(config_path, file_path)
|
89
|
+
Actions::ZipAction.run(
|
90
|
+
path: file_path,
|
91
|
+
symlinks: true,
|
92
|
+
output_path: zip_path,
|
93
|
+
exclude: [],
|
94
|
+
include: []
|
95
|
+
)
|
96
|
+
file_path = zip_path
|
97
|
+
elsif (extension == '.zip' || extension == '.ipa') && params[:linkmaps] && params[:linkmaps].length > 0
|
98
|
+
UI.error("Provided #{extension == '.zip' ? 'zipped archive' : 'ipa'} and linkmaps, linkmaps will not be added to upload.")
|
99
|
+
elsif extension != '.zip' && extension != '.ipa'
|
100
|
+
UI.error("Invalid input file")
|
101
|
+
return false
|
102
|
+
end
|
103
|
+
|
104
|
+
params = {
|
105
|
+
prNumber: pr_number,
|
106
|
+
branch: branch,
|
107
|
+
sha: sha,
|
108
|
+
baseSha: base_sha,
|
109
|
+
previousSha: previous_sha,
|
110
|
+
repoName: repo_name,
|
111
|
+
gitlabProjectId: gitlab_project_id,
|
112
|
+
orderFileVersion: order_file_version,
|
113
|
+
appIdSuffix: params[:app_id_suffix],
|
114
|
+
releaseNotes: params[:release_notes],
|
115
|
+
tag: tag || "default"
|
116
|
+
}
|
117
|
+
upload_id = Helper::EmergeHelper.perform_upload(api_token, params, file_path)
|
118
|
+
UI.success("🎉 Your app is processing, you can find the results at https://emergetools.com/build/#{upload_id}")
|
119
|
+
upload_id
|
120
|
+
end
|
121
|
+
|
122
|
+
def self.copy_dsyms(from, to)
|
123
|
+
Dir.glob(from) do |filename|
|
124
|
+
UI.message("Found dSYM: #{Pathname.new(filename).basename}")
|
125
|
+
FileUtils.cp_r(filename, to)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.description
|
130
|
+
"Fastlane plugin for Emerge"
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.authors
|
134
|
+
["Emerge Tools"]
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.return_value
|
138
|
+
"If successful, returns the upload id of the generated build"
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.details
|
142
|
+
""
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.available_options
|
146
|
+
[
|
147
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
148
|
+
env_name: "EMERGE_API_TOKEN",
|
149
|
+
description: "An API token for Emerge",
|
150
|
+
optional: false,
|
151
|
+
type: String),
|
152
|
+
FastlaneCore::ConfigItem.new(key: :file_path,
|
153
|
+
env_name: "EMERGE_FILE_PATH",
|
154
|
+
description: "Path to the zipped xcarchive or app to upload",
|
155
|
+
optional: true,
|
156
|
+
type: String),
|
157
|
+
FastlaneCore::ConfigItem.new(key: :linkmaps,
|
158
|
+
description: "List of paths to linkmaps",
|
159
|
+
optional: true,
|
160
|
+
type: Array),
|
161
|
+
FastlaneCore::ConfigItem.new(key: :pr_number,
|
162
|
+
description: "The PR number that triggered this upload",
|
163
|
+
optional: true,
|
164
|
+
type: String),
|
165
|
+
FastlaneCore::ConfigItem.new(key: :branch,
|
166
|
+
description: "The current git branch",
|
167
|
+
optional: true,
|
168
|
+
type: String),
|
169
|
+
FastlaneCore::ConfigItem.new(key: :sha,
|
170
|
+
description: "The git SHA that triggered this build",
|
171
|
+
optional: true,
|
172
|
+
type: String),
|
173
|
+
FastlaneCore::ConfigItem.new(key: :base_sha,
|
174
|
+
description: "The git SHA of the base build",
|
175
|
+
optional: true,
|
176
|
+
type: String),
|
177
|
+
FastlaneCore::ConfigItem.new(key: :previous_sha,
|
178
|
+
description: "The git SHA of the commit right before this build's commit",
|
179
|
+
optional: true,
|
180
|
+
type: String),
|
181
|
+
FastlaneCore::ConfigItem.new(key: :build_id,
|
182
|
+
description: "A string to identify this build",
|
183
|
+
deprecated: "Replaced by `sha`",
|
184
|
+
optional: true,
|
185
|
+
type: String),
|
186
|
+
FastlaneCore::ConfigItem.new(key: :base_build_id,
|
187
|
+
description: "Id of the build to compare with this upload",
|
188
|
+
deprecated: "Replaced by `base_sha`",
|
189
|
+
optional: true,
|
190
|
+
type: String),
|
191
|
+
FastlaneCore::ConfigItem.new(key: :repo_name,
|
192
|
+
description: "Full name of the respository this upload was triggered from. For example: EmergeTools/Emerge",
|
193
|
+
optional: true,
|
194
|
+
type: String),
|
195
|
+
FastlaneCore::ConfigItem.new(key: :gitlab_project_id,
|
196
|
+
description: "Id of the gitlab project this upload was triggered from",
|
197
|
+
optional: true,
|
198
|
+
type: Integer),
|
199
|
+
FastlaneCore::ConfigItem.new(key: :tag,
|
200
|
+
description: "String to label the build. Useful for grouping builds together in our dashboard, like development, default, or pull-request",
|
201
|
+
optional: true,
|
202
|
+
type: String),
|
203
|
+
FastlaneCore::ConfigItem.new(key: :order_file_version,
|
204
|
+
description: "Version of the order file to download",
|
205
|
+
optional: true,
|
206
|
+
type: String),
|
207
|
+
FastlaneCore::ConfigItem.new(key: :config_path,
|
208
|
+
description: "Path to Emerge config path",
|
209
|
+
optional: true,
|
210
|
+
type: String),
|
211
|
+
FastlaneCore::ConfigItem.new(key: :app_id_suffix,
|
212
|
+
description: "A suffix to append to the application ID to differentiate between different builds of the same app",
|
213
|
+
optional: true,
|
214
|
+
type: String),
|
215
|
+
FastlaneCore::ConfigItem.new(key: :release_notes,
|
216
|
+
description: "A markdown string with release notes for the upload",
|
217
|
+
optional: true,
|
218
|
+
type: String)
|
219
|
+
]
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.is_supported?(platform)
|
223
|
+
platform == :ios
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fastlane_core/print_table'
|
3
|
+
require_relative '../helper/emerge_helper'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Actions
|
7
|
+
class EmergeComment < Action
|
8
|
+
def self.run(params)
|
9
|
+
url = 'https://api.emergetools.com/getComment'
|
10
|
+
api_token = params[:api_token]
|
11
|
+
gitlab_url = params[:gitlab_url]
|
12
|
+
project_id = params[:gitlab_project_id]
|
13
|
+
pr_number = params[:pr_number]
|
14
|
+
gitlab_access_token = params[:gitlab_access_token]
|
15
|
+
|
16
|
+
request_params = {
|
17
|
+
buildId: params[:build_id],
|
18
|
+
baseBuildId: params[:base_build_id]
|
19
|
+
}
|
20
|
+
resp = Faraday.get(url, request_params, 'x-api-token' => api_token)
|
21
|
+
case resp.status
|
22
|
+
when 200
|
23
|
+
UI.message("Received comment from Emerge")
|
24
|
+
baseURL = gitlab_url ? gitlab_url : "https://gitlab.com"
|
25
|
+
url = "#{baseURL}/api/v4/projects/#{project_id}/merge_requests/#{pr_number}/notes"
|
26
|
+
gitlab_response = Faraday.post(url, { "body" => resp.body }, 'Authorization' => "Bearer #{gitlab_access_token}")
|
27
|
+
case gitlab_response.status
|
28
|
+
when 200...299
|
29
|
+
UI.message("Successfully posted comment")
|
30
|
+
else
|
31
|
+
UI.error("Received error #{gitlab_response.status} from Gitlab")
|
32
|
+
end
|
33
|
+
else
|
34
|
+
UI.error("Received error #{resp.status} from Emerge")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.description
|
39
|
+
"Post an Emerge PR comment, currently supports Gitlab only."
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.authors
|
43
|
+
["Emerge Tools"]
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.available_options
|
47
|
+
[
|
48
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
49
|
+
env_name: "EMERGE_API_TOKEN",
|
50
|
+
description: "An API token for Emerge",
|
51
|
+
optional: false,
|
52
|
+
type: String),
|
53
|
+
FastlaneCore::ConfigItem.new(key: :gitlab_acces_token,
|
54
|
+
env_name: "GITLAB_ACCESS_TOKEN",
|
55
|
+
description: "An access token for Gitlab",
|
56
|
+
optional: false,
|
57
|
+
type: String),
|
58
|
+
FastlaneCore::ConfigItem.new(key: :pr_number,
|
59
|
+
description: "The PR number that triggered this upload",
|
60
|
+
optional: false,
|
61
|
+
type: String),
|
62
|
+
FastlaneCore::ConfigItem.new(key: :build_id,
|
63
|
+
description: "A string to identify this build",
|
64
|
+
optional: false,
|
65
|
+
type: String),
|
66
|
+
FastlaneCore::ConfigItem.new(key: :base_build_id,
|
67
|
+
description: "Id of the build to compare with this upload",
|
68
|
+
optional: false,
|
69
|
+
type: String),
|
70
|
+
FastlaneCore::ConfigItem.new(key: :gitlab_url,
|
71
|
+
description: "URL of the self hosted gitlab instance",
|
72
|
+
optional: true,
|
73
|
+
type: String),
|
74
|
+
FastlaneCore::ConfigItem.new(key: :gitlab_project_id,
|
75
|
+
description: "Id of the gitlab project this upload was triggered from",
|
76
|
+
optional: false,
|
77
|
+
type: Integer)
|
78
|
+
]
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.is_supported?(platform)
|
82
|
+
platform == :ios
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
module Fastlane
|
7
|
+
module Actions
|
8
|
+
class EmergeOrderFileAction < Action
|
9
|
+
def self.run(params)
|
10
|
+
puts "https://order-files-prod.emergetools.com/#{params[:app_id]}/#{params[:order_file_version]}"
|
11
|
+
resp = Faraday.get("https://order-files-prod.emergetools.com/#{params[:app_id]}/#{params[:order_file_version]}", nil, {'X-API-Token' => params[:api_token]})
|
12
|
+
case resp.status
|
13
|
+
when 200
|
14
|
+
Tempfile.create do |f|
|
15
|
+
f.write(resp.body)
|
16
|
+
decompressed = IO.popen(['gunzip', '-c', f.path]).read
|
17
|
+
IO.write(params[:output_path], decompressed)
|
18
|
+
end
|
19
|
+
return 200
|
20
|
+
when 401
|
21
|
+
UI.error("Unauthorized")
|
22
|
+
when 403
|
23
|
+
UI.message("No order file found, this is expected for the first build of an app_id/version.")
|
24
|
+
# The API will return a 403 when no order file is found, but we change that to a 200 for the
|
25
|
+
# fastlane plugin because this is an expected state for a CI integraion.
|
26
|
+
return 200
|
27
|
+
else
|
28
|
+
UI.error("Failed to download order file code: #{resp.status}")
|
29
|
+
end
|
30
|
+
resp.status
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.description
|
34
|
+
"Fastlane plugin to download order files"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.authors
|
38
|
+
["Emerge Tools"]
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.return_value
|
42
|
+
# If your method provides a return value, you can describe here what it does
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.details
|
46
|
+
# Optional:
|
47
|
+
""
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.available_options
|
51
|
+
[
|
52
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
53
|
+
env_name: "EMERGE_API_TOKEN",
|
54
|
+
description: "An API token for Emerge",
|
55
|
+
optional: false,
|
56
|
+
type: String),
|
57
|
+
FastlaneCore::ConfigItem.new(key: :app_id,
|
58
|
+
description: "Id of the app being built with the order file",
|
59
|
+
optional: false,
|
60
|
+
type: String),
|
61
|
+
FastlaneCore::ConfigItem.new(key: :output_path,
|
62
|
+
description: "Path to the order file",
|
63
|
+
optional: false,
|
64
|
+
type: String),
|
65
|
+
FastlaneCore::ConfigItem.new(key: :order_file_version,
|
66
|
+
description: "Version of the order file to download",
|
67
|
+
optional: false,
|
68
|
+
type: String),
|
69
|
+
]
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.is_supported?(platform)
|
73
|
+
platform == :ios
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fastlane_core/print_table'
|
3
|
+
require_relative '../helper/emerge_helper'
|
4
|
+
require_relative '../helper/git'
|
5
|
+
require_relative '../helper/github'
|
6
|
+
require 'pathname'
|
7
|
+
require 'tmpdir'
|
8
|
+
require 'json'
|
9
|
+
require 'fileutils'
|
10
|
+
|
11
|
+
module Fastlane
|
12
|
+
module Actions
|
13
|
+
class EmergeSnapshotAction < Action
|
14
|
+
def self.run(params)
|
15
|
+
api_token = params[:api_token]
|
16
|
+
|
17
|
+
git_params = Helper::EmergeHelper.make_git_params
|
18
|
+
pr_number = params[:pr_number] || git_params.pr_number
|
19
|
+
branch = params[:branch] || git_params.branch
|
20
|
+
sha = params[:sha] || git_params.sha
|
21
|
+
base_sha = params[:base_sha] || git_params.base_sha
|
22
|
+
previous_sha = params[:previous_sha] || git_params.previous_sha
|
23
|
+
repo_name = params[:repo_name] || git_params.repo_name
|
24
|
+
gitlab_project_id = params[:gitlab_project_id]
|
25
|
+
tag = params[:tag]
|
26
|
+
config_path = params[:config_path]
|
27
|
+
scheme = params[:scheme]
|
28
|
+
configuration = params[:configuration]
|
29
|
+
team_id = params[:team_id] || CredentialsManager::AppfileConfig.try_fetch_value(:team_id)
|
30
|
+
|
31
|
+
Dir.mktmpdir do |temp_dir|
|
32
|
+
archive_name = "#{scheme}-Emerge-Snapshots"
|
33
|
+
archive_path = "#{temp_dir}/build/#{archive_name}.xcarchive"
|
34
|
+
make_debug_build(
|
35
|
+
scheme: scheme,
|
36
|
+
configuration: configuration,
|
37
|
+
team_id: team_id,
|
38
|
+
archive_path: archive_path
|
39
|
+
)
|
40
|
+
Helper::EmergeHelper.copy_config(config_path, archive_path)
|
41
|
+
Xcodeproj::Plist.write_to_path({ "NAME" => "Emerge Upload" }, "#{archive_path}/Info.plist")
|
42
|
+
|
43
|
+
zip_file_path = "#{temp_dir}/build/#{archive_name}.xcarchive.zip"
|
44
|
+
ZipAction.run(
|
45
|
+
path: archive_path,
|
46
|
+
symlinks: true,
|
47
|
+
output_path: zip_file_path,
|
48
|
+
exclude: [],
|
49
|
+
include: []
|
50
|
+
)
|
51
|
+
|
52
|
+
params = {
|
53
|
+
appIdSuffix: 'snapshots',
|
54
|
+
prNumber: pr_number,
|
55
|
+
branch: branch,
|
56
|
+
sha: sha,
|
57
|
+
baseSha: base_sha,
|
58
|
+
previousSha: previous_sha,
|
59
|
+
repoName: repo_name,
|
60
|
+
gitlabProjectId: gitlab_project_id,
|
61
|
+
tag: tag || "default"
|
62
|
+
}
|
63
|
+
upload_id = Helper::EmergeHelper.perform_upload(api_token, params, zip_file_path)
|
64
|
+
UI.success("🎉 Your app is processing, you can find the results at https://emergetools.com/snapshot/#{upload_id}")
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.make_debug_build(scheme:, configuration:, team_id:, archive_path:)
|
69
|
+
other_action.gym(
|
70
|
+
scheme: scheme,
|
71
|
+
configuration: configuration,
|
72
|
+
skip_codesigning: true,
|
73
|
+
clean: true,
|
74
|
+
export_method: "development",
|
75
|
+
export_team_id: team_id,
|
76
|
+
skip_package_ipa: true,
|
77
|
+
archive_path: archive_path
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.description
|
82
|
+
"Fastlane plugin for Emerge to generate iOS snapshots"
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.authors
|
86
|
+
["Emerge Tools"]
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.return_value
|
90
|
+
"If successful, returns the upload id of the generated snapshot build"
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.details
|
94
|
+
""
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.available_options
|
98
|
+
[
|
99
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
100
|
+
env_name: "EMERGE_API_TOKEN",
|
101
|
+
description: "An API token for Emerge",
|
102
|
+
optional: false,
|
103
|
+
type: String),
|
104
|
+
FastlaneCore::ConfigItem.new(key: :scheme,
|
105
|
+
description: "The scheme of your app to build",
|
106
|
+
optional: false,
|
107
|
+
type: String),
|
108
|
+
FastlaneCore::ConfigItem.new(key: :configuration,
|
109
|
+
description: "The configuration of your app to use",
|
110
|
+
optional: false,
|
111
|
+
default_value: "Debug",
|
112
|
+
type: String),
|
113
|
+
FastlaneCore::ConfigItem.new(key: :team_id,
|
114
|
+
env_name: "EXPORT_TEAM_ID",
|
115
|
+
description: "The Apple Team ID to use for exporting the archive. If not provided, we will try to use the team_id from the Appfile",
|
116
|
+
optional: true,
|
117
|
+
type: String),
|
118
|
+
FastlaneCore::ConfigItem.new(key: :config_path,
|
119
|
+
description: "Path to Emerge YAML config path",
|
120
|
+
optional: true,
|
121
|
+
type: String),
|
122
|
+
FastlaneCore::ConfigItem.new(key: :pr_number,
|
123
|
+
description: "The PR number that triggered this upload",
|
124
|
+
optional: true,
|
125
|
+
type: String),
|
126
|
+
FastlaneCore::ConfigItem.new(key: :branch,
|
127
|
+
description: "The current git branch",
|
128
|
+
optional: true,
|
129
|
+
type: String),
|
130
|
+
FastlaneCore::ConfigItem.new(key: :sha,
|
131
|
+
description: "The git SHA that triggered this build",
|
132
|
+
optional: true,
|
133
|
+
type: String),
|
134
|
+
FastlaneCore::ConfigItem.new(key: :base_sha,
|
135
|
+
description: "The git SHA of the base build",
|
136
|
+
optional: true,
|
137
|
+
type: String),
|
138
|
+
FastlaneCore::ConfigItem.new(key: :previous_sha,
|
139
|
+
description: "The git SHA of the commit right before this build's commit",
|
140
|
+
optional: true,
|
141
|
+
type: String),
|
142
|
+
FastlaneCore::ConfigItem.new(key: :repo_name,
|
143
|
+
description: "Full name of the respository this upload was triggered from. For example: EmergeTools/Emerge",
|
144
|
+
optional: true,
|
145
|
+
type: String),
|
146
|
+
FastlaneCore::ConfigItem.new(key: :gitlab_project_id,
|
147
|
+
description: "Id of the gitlab project this upload was triggered from",
|
148
|
+
optional: true,
|
149
|
+
type: Integer),
|
150
|
+
FastlaneCore::ConfigItem.new(key: :tag,
|
151
|
+
description: "String to label the build. Useful for grouping builds together in our dashboard, like development, default, or pull-request",
|
152
|
+
optional: true,
|
153
|
+
type: String)
|
154
|
+
]
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.is_supported?(platform)
|
158
|
+
platform == :ios
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'fastlane_core/ui/ui'
|
2
|
+
require 'faraday'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
|
6
|
+
|
7
|
+
class GitResult
|
8
|
+
attr_accessor :sha, :base_sha, :previous_sha, :branch, :pr_number, :repo_name
|
9
|
+
|
10
|
+
def initialize(sha:, base_sha:, previous_sha:, branch:, pr_number: nil, repo_name: nil)
|
11
|
+
@pr_number = pr_number
|
12
|
+
@sha = sha
|
13
|
+
@base_sha = base_sha
|
14
|
+
@previous_sha = previous_sha
|
15
|
+
@branch = branch
|
16
|
+
@repo_name = repo_name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module Helper
|
21
|
+
class EmergeHelper
|
22
|
+
API_URL = 'https://api.emergetools.com/upload'.freeze
|
23
|
+
|
24
|
+
def self.perform_upload(api_token, params, file_path)
|
25
|
+
cleaned_params = clean_params(params)
|
26
|
+
print_summary(cleaned_params)
|
27
|
+
|
28
|
+
upload_response = create_upload(api_token, cleaned_params)
|
29
|
+
handle_upload_response(api_token, upload_response, file_path)
|
30
|
+
rescue StandardError => e
|
31
|
+
UI.user_error!(e.message)
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.make_git_params
|
35
|
+
git_result = if Helper::Github.is_supported_github_event?
|
36
|
+
UI.message("Fetching Git info from Github event. This is what we get")
|
37
|
+
UI.message("Github previous_sha: #{Helper::Github.previous_sha}")
|
38
|
+
UI.message("Git previous_sha: #{Helper::Git.previous_sha}")
|
39
|
+
UI.message("Ok for real going to fetch")
|
40
|
+
GitResult.new(
|
41
|
+
sha: Helper::Github.sha,
|
42
|
+
base_sha: Helper::Github.base_sha,
|
43
|
+
previous_sha: Helper::Github.previous_sha,
|
44
|
+
branch: Helper::Github.branch,
|
45
|
+
pr_number: Helper::Github.pr_number,
|
46
|
+
repo_name: Helper::Github.repo_name
|
47
|
+
)
|
48
|
+
else
|
49
|
+
UI.message("Fetching Git info from system Git")
|
50
|
+
GitResult.new(
|
51
|
+
sha: Helper::Git.sha,
|
52
|
+
base_sha: Helper::Git.base_sha,
|
53
|
+
previous_sha: Helper::Git.previous_sha,
|
54
|
+
branch: Helper::Git.branch
|
55
|
+
)
|
56
|
+
end
|
57
|
+
UI.message("Got git result #{git_result.inspect}")
|
58
|
+
git_result
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.copy_config(config_path, tmp_dir)
|
62
|
+
return if config_path.nil?
|
63
|
+
|
64
|
+
expanded_path = File.expand_path(config_path)
|
65
|
+
unless File.exist?(expanded_path)
|
66
|
+
UI.error("No config file found at path '#{expanded_path}'.\nUploading without config file")
|
67
|
+
return
|
68
|
+
end
|
69
|
+
|
70
|
+
emerge_config_path = "#{tmp_dir}/emerge_config.yaml"
|
71
|
+
FileUtils.cp(expanded_path, emerge_config_path)
|
72
|
+
end
|
73
|
+
|
74
|
+
private_class_method
|
75
|
+
|
76
|
+
def self.clean_params(params)
|
77
|
+
params.reject { |_, v| v.nil? }
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.print_summary(params)
|
81
|
+
FastlaneCore::PrintTable.print_values(
|
82
|
+
config: params,
|
83
|
+
hide_keys: [],
|
84
|
+
title: "Summary for Emerge Upload #{Fastlane::Emerge::VERSION}"
|
85
|
+
)
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.create_upload(api_token, params)
|
89
|
+
response = Faraday.post(API_URL, params.to_json, headers(api_token, params, 'application/json'))
|
90
|
+
parse_response(response)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.headers(api_token, params, content_type)
|
94
|
+
{
|
95
|
+
'Content-Type' => content_type,
|
96
|
+
'X-API-Token' => api_token,
|
97
|
+
'User-Agent' => "fastlane-plugin-nico/#{Fastlane::Emerge::VERSION}"
|
98
|
+
}
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.parse_response(response)
|
102
|
+
case response.status
|
103
|
+
when 200
|
104
|
+
JSON.parse(response.body)
|
105
|
+
when 400
|
106
|
+
error_message = JSON.parse(response.body)['errorMessage']
|
107
|
+
raise "Invalid parameters: #{error_message}"
|
108
|
+
when 401, 403
|
109
|
+
raise 'Invalid API token'
|
110
|
+
else
|
111
|
+
raise "Creating upload failed with status #{response.status}"
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.handle_upload_response(api_token, response, file_path)
|
116
|
+
upload_url = response.fetch('uploadURL')
|
117
|
+
upload_id = response.fetch('upload_id')
|
118
|
+
|
119
|
+
warning = response.dig('warning')
|
120
|
+
if warning
|
121
|
+
UI.important(warning)
|
122
|
+
end
|
123
|
+
|
124
|
+
UI.message('Starting zip file upload')
|
125
|
+
upload_file(api_token, upload_url, file_path)
|
126
|
+
upload_id
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.upload_file(api_token, upload_url, file_path)
|
130
|
+
response = Faraday.put(upload_url) do |req|
|
131
|
+
req.headers = headers(api_token, nil, 'application/zip')
|
132
|
+
req.headers['Content-Length'] = File.size(file_path).to_s
|
133
|
+
req.body = Faraday::UploadIO.new(file_path, 'application/zip')
|
134
|
+
end
|
135
|
+
|
136
|
+
raise "Uploading zip file failed #{response.status}" unless response.status == 200
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'fastlane_core/print_table'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Helper
|
6
|
+
module Git
|
7
|
+
def self.branch
|
8
|
+
shell_command = "git rev-parse --abbrev-ref HEAD"
|
9
|
+
UI.command(shell_command)
|
10
|
+
stdout, _, status = Open3.capture3(shell_command)
|
11
|
+
unless status.success?
|
12
|
+
UI.error("Failed to get the current branch name")
|
13
|
+
return nil
|
14
|
+
end
|
15
|
+
|
16
|
+
branch_name = stdout.strip
|
17
|
+
if branch_name == "HEAD"
|
18
|
+
# We're in a detached HEAD state
|
19
|
+
# Find all branches that contains the current HEAD commit
|
20
|
+
#
|
21
|
+
# Example output:
|
22
|
+
# * (HEAD detached at dec13a5)
|
23
|
+
# telkins/detached-test
|
24
|
+
# remotes/origin/telkins/detached-test
|
25
|
+
#
|
26
|
+
# So far I've seen this output be fairly stable
|
27
|
+
# If the input is invalid for whatever reason, sed/awk will return an empty string
|
28
|
+
shell_command = "git branch -a --contains HEAD | sed -n 2p | awk '{ printf $1 }'"
|
29
|
+
UI.command(shell_command)
|
30
|
+
head_stdout, _, head_status = Open3.capture3(shell_command)
|
31
|
+
|
32
|
+
unless head_status.success?
|
33
|
+
UI.error("Failed to get the current branch name for detached HEAD")
|
34
|
+
return nil
|
35
|
+
end
|
36
|
+
|
37
|
+
branch_name = head_stdout.strip
|
38
|
+
end
|
39
|
+
|
40
|
+
branch_name == "HEAD" ? nil : branch_name
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.sha
|
44
|
+
shell_command = "git rev-parse HEAD"
|
45
|
+
UI.command(shell_command)
|
46
|
+
stdout, _, status = Open3.capture3(shell_command)
|
47
|
+
stdout.strip if status.success?
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.base_sha
|
51
|
+
current_branch = branch
|
52
|
+
remote_head = remote_head_branch
|
53
|
+
return nil if current_branch.nil? || remote_head.nil?
|
54
|
+
|
55
|
+
shell_command = "git merge-base #{remote_head} #{current_branch}"
|
56
|
+
UI.command(shell_command)
|
57
|
+
stdout, _, status = Open3.capture3(shell_command)
|
58
|
+
return nil if stdout.strip.empty? || !status.success?
|
59
|
+
current_sha = sha
|
60
|
+
stdout.strip == current_sha ? nil : stdout.strip
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.previous_sha
|
64
|
+
shell_command = "git rev-parse HEAD^"
|
65
|
+
UI.command(shell_command)
|
66
|
+
stdout, _, status = Open3.capture3(shell_command)
|
67
|
+
stdout.strip if status.success?
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.primary_remote
|
71
|
+
remote = remote()
|
72
|
+
return nil if remote.nil?
|
73
|
+
remote.include?("origin") ? "origin" : remote.first
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.remote_head_branch(remote = primary_remote)
|
77
|
+
return nil if remote.nil?
|
78
|
+
shell_command = "git remote show #{remote}"
|
79
|
+
UI.command(shell_command)
|
80
|
+
stdout, _, status = Open3.capture3(shell_command)
|
81
|
+
return nil if stdout.nil? || !status.success?
|
82
|
+
stdout
|
83
|
+
.split("\n")
|
84
|
+
.map(&:strip)
|
85
|
+
.find { |line| line.start_with?("HEAD branch: ") }
|
86
|
+
&.split(' ')
|
87
|
+
&.last
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.remote_url(remote = primary_remote)
|
91
|
+
return nil if remote.nil?
|
92
|
+
shell_command = "git config --get remote.#{remote}.url"
|
93
|
+
UI.command(shell_command)
|
94
|
+
stdout, _, status = Open3.capture3(shell_command)
|
95
|
+
stdout if status.success?
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.remote
|
99
|
+
shell_command = "git remote"
|
100
|
+
UI.command(shell_command)
|
101
|
+
stdout, _, status = Open3.capture3(shell_command)
|
102
|
+
stdout.split("\n") if status.success?
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'fastlane_core/print_table'
|
3
|
+
require_relative 'git'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Helper
|
7
|
+
module Github
|
8
|
+
GITHUB_EVENT_PR = "pull_request".freeze
|
9
|
+
GITHUB_EVENT_PUSH = "push".freeze
|
10
|
+
|
11
|
+
def self.event_name
|
12
|
+
ENV['GITHUB_EVENT_NAME']
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.is_supported_github_event?
|
16
|
+
UI.message("GitHub event name: #{event_name}")
|
17
|
+
is_pull_request? || is_push?
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.is_pull_request?
|
21
|
+
event_name == GITHUB_EVENT_PR
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.is_push?
|
25
|
+
event_name == GITHUB_EVENT_PUSH
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.sha
|
29
|
+
if is_push?
|
30
|
+
ENV['GITHUB_SHA']
|
31
|
+
elsif is_pull_request?
|
32
|
+
github_event_data.dig(:pull_request, :head, :sha)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.base_sha
|
37
|
+
if is_pull_request?
|
38
|
+
github_event_data.dig(:pull_request, :base, :sha)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.previous_sha
|
43
|
+
if is_push?
|
44
|
+
github_event_data.dig(:before)
|
45
|
+
else
|
46
|
+
shell_command = "git rev-parse HEAD^"
|
47
|
+
UI.command(shell_command)
|
48
|
+
stdout, _, status = Open3.capture3(shell_command)
|
49
|
+
stdout.strip if status.success?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def self.pr_number
|
54
|
+
is_pull_request? ? github_event_data.dig(:number) : nil
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.branch
|
58
|
+
is_pull_request? ? github_event_data.dig(:pull_request, :head, :ref) : Git.branch
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.repo_owner
|
62
|
+
github_event_data.dig(:repository, :owner, :login)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.repo_name
|
66
|
+
github_event_data.dig(:repository, :full_name)
|
67
|
+
end
|
68
|
+
|
69
|
+
private_class_method
|
70
|
+
|
71
|
+
def self.github_event_data
|
72
|
+
github_event_path = ENV['GITHUB_EVENT_PATH']
|
73
|
+
UI.error!("GITHUB_EVENT_PATH is not set") if github_event_path.nil?
|
74
|
+
|
75
|
+
unless File.exist?(github_event_path)
|
76
|
+
UI.error!("File #{github_event_path} doesn't exist")
|
77
|
+
end
|
78
|
+
|
79
|
+
file_content = File.read(github_event_path)
|
80
|
+
file_json = JSON.parse(file_content, symbolize_names: true)
|
81
|
+
if ENV['DEBUG']
|
82
|
+
UI.message("Parsed GitHub event data: #{file_json.inspect}")
|
83
|
+
end
|
84
|
+
file_json
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'fastlane/plugin/emerge/version'
|
2
|
+
|
3
|
+
module Fastlane
|
4
|
+
module Emerge
|
5
|
+
# Return all .rb files inside the "actions" and "helper" directory
|
6
|
+
def self.all_classes
|
7
|
+
Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# By default we want to import all available actions and helpers
|
13
|
+
# A plugin can contain any number of actions and plugins
|
14
|
+
Fastlane::Emerge.all_classes.each do |current|
|
15
|
+
require current
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,193 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-nico
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.10.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nico Testing
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-10-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec_junit_formatter
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - '='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.49.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - '='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.49.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop-require_tools
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: simplecov
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: fastlane
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 2.170.0
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 2.170.0
|
153
|
+
description:
|
154
|
+
email:
|
155
|
+
executables: []
|
156
|
+
extensions: []
|
157
|
+
extra_rdoc_files: []
|
158
|
+
files:
|
159
|
+
- LICENSE
|
160
|
+
- README.md
|
161
|
+
- lib/fastlane/plugin/emerge.rb
|
162
|
+
- lib/fastlane/plugin/emerge/actions/emerge_action.rb
|
163
|
+
- lib/fastlane/plugin/emerge/actions/emerge_comment_action.rb
|
164
|
+
- lib/fastlane/plugin/emerge/actions/emerge_order_file_action.rb
|
165
|
+
- lib/fastlane/plugin/emerge/actions/emerge_snapshot_action.rb
|
166
|
+
- lib/fastlane/plugin/emerge/helper/emerge_helper.rb
|
167
|
+
- lib/fastlane/plugin/emerge/helper/git.rb
|
168
|
+
- lib/fastlane/plugin/emerge/helper/github.rb
|
169
|
+
- lib/fastlane/plugin/emerge/version.rb
|
170
|
+
homepage: https://github.com/EmergeTools/fastlane-plugin-emerge
|
171
|
+
licenses:
|
172
|
+
- MIT
|
173
|
+
metadata: {}
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: '0'
|
183
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
requirements: []
|
189
|
+
rubygems_version: 3.5.21
|
190
|
+
signing_key:
|
191
|
+
specification_version: 4
|
192
|
+
summary: Fastlane plugin for Emerge
|
193
|
+
test_files: []
|