fastlane-plugin-nico 0.10.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](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: []
|