fastlane 2.50.0.beta.20170731010002 → 2.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 609d266f5d04fe6eb726a8c2c2c9e5fd8aa33929
4
- data.tar.gz: c028dc002f5ffa051910db3e69769a2ab7ff4a52
3
+ metadata.gz: 4bcea6a1f68d82ce8f7490a64d9bb4734aba11cc
4
+ data.tar.gz: a6f24ff351403a7d87e9b614b9b0e5546542d18b
5
5
  SHA512:
6
- metadata.gz: 192fe79a86c1dc4a5062800f676df4c6783de16cf852bebcc703558c0ffe0cce7930a26ac880aaa80bb52902e2c7dba06e393e9fba80867a25b46fca9b1b1f0b
7
- data.tar.gz: b30f38600568d36ca896d8080317afaac20121a5a815240c63b8523f79f2078ee94133f47ffad3196ce1b3a2bcea0498a9536ca4d7225b245b511b9373f1a12c
6
+ metadata.gz: a18267f30b1f5335b969f9ebc3687d05dd1a2ddbb4cd22edc8c730d53e77bf36efd99ebeb023fa601a853220c5becc66218983fc3b9ad2a57b9251906417be81
7
+ data.tar.gz: 56aa6d2e0ee98bf8bccf0b0be9e496e68f53b26219ca464ad7b1d79446a7f3b236c7716e2b6bda47ce55a96c98262f2964fa0cd55316e278af57adf998aa3fe6
@@ -22,10 +22,14 @@ For _fastlane_ plugins, check out the [available plugins](https://docs.fastlane.
22
22
  <%- end -%>
23
23
  - [Plugins](https://docs.fastlane.tools/plugins/available-plugins)
24
24
 
25
-
26
25
  <%- @categories.each do |category, actions| %>
27
26
  # <%= category %>
28
- <%- actions.sort.to_h.each do |_number_of_launches, action| -%>
27
+
28
+ <div class='category-actions'>
29
+
30
+ <%- actions.sort.to_h.each do |_number_of_launches, action| -%>
31
+
32
+ <div class='action'>
29
33
 
30
34
  ### <%= action.action_name %>
31
35
 
@@ -51,8 +55,8 @@ Returns | <%= action.return_value %>
51
55
  ```ruby
52
56
  <%= current_sample.gsub(" ", "") %>
53
57
  ```
54
- <% end %>
55
- <% end %>
58
+ <% end %><%# End of action.example_code... %>
59
+ <% end %><%# End of if %>
56
60
  </details>
57
61
 
58
62
  <% if action.available_options && action.available_options.first.kind_of?(FastlaneCore::ConfigItem) %>
@@ -67,9 +71,11 @@ Key | Description
67
71
  `<%= config_item.key %>` | <%= config_item.description %>
68
72
  <%- end %>
69
73
  </details>
70
- <% end %>
74
+ </div>
71
75
 
76
+ <% end %><%# End of action.available_options... %>
72
77
 
78
+ <%- end %><%# End of actions.sort... %>
79
+ </div>
73
80
 
74
- <%- end %>
75
- <%- end %>
81
+ <%- end %><%# End of categories.each %>
@@ -0,0 +1,178 @@
1
+ module Fastlane
2
+ module Actions
3
+ module SharedValues
4
+ COMMIT_GITHUB_FILE_HTML_LINK = :COMMIT_GITHUB_FILE_HTML_LINK
5
+ COMMIT_GITHUB_FILE_SHA = :COMMIT_GITHUB_FILE_SHA
6
+ COMMIT_GITHUB_FILE_JSON = :COMMIT_GITHUB_FILE_JSON
7
+ end
8
+
9
+ class CommitGithubFileAction < Action
10
+ def self.run(params)
11
+ repo_name = params[:repository_name]
12
+ branch = params[:branch] ||= 'master'
13
+ commit_message = params[:message]
14
+
15
+ file_path = params[:path]
16
+ file_name = File.basename(file_path)
17
+ expanded_file_path = File.expand_path(file_path)
18
+
19
+ UI.important("Creating commit on #{repo_name} on branch \"#{branch}\" for file \"#{file_path}\"")
20
+
21
+ api_file_path = file_path
22
+ api_file_path = "/#{api_file_path}" unless api_file_path.start_with? '/'
23
+ api_file_path = api_file_path[0..-2] if api_file_path.end_with? '/'
24
+
25
+ payload = {
26
+ path: api_file_path,
27
+ message: commit_message || "Updated : #{file_name}",
28
+ content: Base64.encode64(File.open(expanded_file_path).read),
29
+ branch: branch
30
+ }
31
+
32
+ UI.message("Committing #{api_file_path}")
33
+ GithubApiAction.run({
34
+ server_url: params[:server_url],
35
+ api_token: params[:api_token],
36
+ secure: params[:secure],
37
+ http_method: "PUT",
38
+ path: File.join("repos", params[:repository_name], "contents", api_file_path),
39
+ body: payload,
40
+ error_handlers: {
41
+ 422 => proc do |result|
42
+ json = result[:json]
43
+ UI.error(json || result[:body])
44
+ error = if json['message'] == "Invalid request.\n\n\"sha\" wasn't supplied."
45
+ "File already exists - please remove from repo before uploading or rename this upload"
46
+ else
47
+ "Uprocessable error"
48
+ end
49
+ UI.user_error!(error)
50
+ end
51
+ }
52
+ }) do |result|
53
+ UI.success("Successfully commited file to GitHub")
54
+ json = result[:json]
55
+ html_url = json['commit']['html_url']
56
+ download_url = json['content']['download_url']
57
+ commit_sha = json['commit']['sha']
58
+
59
+ UI.important("Commit: \"#{html_url}\"")
60
+ UI.important("SHA: \"#{commit_sha}\"")
61
+ UI.important("Download at: \"#{download_url}\"")
62
+
63
+ Actions.lane_context[SharedValues::COMMIT_GITHUB_FILE_HTML_LINK] = html_url
64
+ Actions.lane_context[SharedValues::COMMIT_GITHUB_FILE_SHA] = commit_sha
65
+ Actions.lane_context[SharedValues::COMMIT_GITHUB_FILE_JSON] = json
66
+ end
67
+
68
+ Actions.lane_context[SharedValues::COMMIT_GITHUB_FILE_JSON]
69
+ end
70
+
71
+ #####################################################
72
+ # @!group Documentation
73
+ #####################################################
74
+
75
+ def self.description
76
+ "This will commit a file directly on GitHub via the API"
77
+ end
78
+
79
+ def self.details
80
+ "Commits a file directly to GitHub. You must provide your GitHub Personal token
81
+ (get one from https://github.com/settings/tokens/new), the repository name and the relative file path from the root git project.
82
+ Out parameters provide the commit sha created, which can be used for later usage for examples such as releases, the direct download link and the full response JSON.
83
+ Documentation: https://developer.github.com/v3/repos/contents/#create-a-file"
84
+ end
85
+
86
+ def self.available_options
87
+ [
88
+ FastlaneCore::ConfigItem.new(key: :repository_name,
89
+ env_name: "FL_COMMIT_GITHUB_FILE_REPOSITORY_NAME",
90
+ description: "The path to your repo, e.g. 'fastlane/fastlane'",
91
+ verify_block: proc do |value|
92
+ UI.user_error!("Please only pass the path, e.g. 'fastlane/fastlane'") if value.include? "github.com"
93
+ UI.user_error!("Please only pass the path, e.g. 'fastlane/fastlane'") if value.split('/').count != 2
94
+ end),
95
+ FastlaneCore::ConfigItem.new(key: :server_url,
96
+ env_name: "FL_COMMIT_GITHUB_FILE_SERVER_URL",
97
+ description: "The server url. e.g. 'https://your.internal.github.host/api/v3' (Default: 'https://api.github.com')",
98
+ default_value: "https://api.github.com",
99
+ optional: true,
100
+ verify_block: proc do |value|
101
+ UI.user_error!("Please include the protocol in the server url, e.g. https://your.github.server/api/v3") unless value.include? "//"
102
+ end),
103
+ FastlaneCore::ConfigItem.new(key: :api_token,
104
+ env_name: "FL_COMMIT_GITHUB_FILE_API_TOKEN",
105
+ description: "Personal API Token for GitHub - generate one at https://github.com/settings/tokens",
106
+ sensitive: true,
107
+ is_string: true,
108
+ default_value: ENV["GITHUB_API_TOKEN"],
109
+ optional: false),
110
+ FastlaneCore::ConfigItem.new(key: :branch,
111
+ env_name: "FL_COMMIT_GITHUB_FILE_BRANCH",
112
+ description: "The branch that the file should be committed on (default: master)",
113
+ default_value: 'master',
114
+ optional: true),
115
+ FastlaneCore::ConfigItem.new(key: :path,
116
+ env_name: 'FL_COMMIT_GITHUB_FILE_PATH',
117
+ description: 'The relative path to your file from project root e.g. assets/my_app.xcarchive',
118
+ optional: false,
119
+ is_string: true,
120
+ verify_block: proc do |value|
121
+ value = File.expand_path(value)
122
+ UI.user_error!("File not found at path '#{value}'") unless File.exist?(value)
123
+ end),
124
+ FastlaneCore::ConfigItem.new(key: :message,
125
+ env_name: "FL_COMMIT_GITHUB_FILE_MESSAGE",
126
+ description: "The commit message. Defaults to the file name",
127
+ optional: true),
128
+ FastlaneCore::ConfigItem.new(key: :secure,
129
+ env_name: "FL_COMMIT_GITHUB_FILE_SECURE",
130
+ description: "Optionally disable secure requests (ssl_verify_peer)",
131
+ is_string: false,
132
+ default_value: true,
133
+ optional: true)
134
+ ]
135
+ end
136
+
137
+ def self.output
138
+ [
139
+ ['COMMIT_GITHUB_FILE_HTML_LINK', 'Link to your committed file'],
140
+ ['COMMIT_GITHUB_FILE_SHA', 'Commit SHA generated'],
141
+ ['COMMIT_GITHUB_FILE_JSON', 'The whole commit JSON object response']
142
+ ]
143
+ end
144
+
145
+ def self.return_value
146
+ [
147
+ "A hash containing all relevant information for this commit",
148
+ "Access things like 'html_url', 'sha', 'message'"
149
+ ].join("\n")
150
+ end
151
+
152
+ def self.authors
153
+ ["tommeier"]
154
+ end
155
+
156
+ def self.example_code
157
+ [
158
+ 'response = commit_github_file(
159
+ repository_name: "fastlane/fastlane",
160
+ server_url: "https://api.github.com",
161
+ api_token: ENV["GITHUB_TOKEN"],
162
+ message: "Add my new file",
163
+ branch: "master",
164
+ path: "assets/my_new_file.xcarchive"
165
+ )'
166
+ ]
167
+ end
168
+
169
+ def self.is_supported?(platform)
170
+ true
171
+ end
172
+
173
+ def self.category
174
+ :source_control
175
+ end
176
+ end
177
+ end
178
+ end
@@ -6,34 +6,35 @@ module Fastlane
6
6
 
7
7
  class CreatePullRequestAction < Action
8
8
  def self.run(params)
9
- require 'excon'
10
- require 'base64'
11
-
12
9
  UI.message("Creating new pull request from '#{params[:head]}' to branch '#{params[:base]}' of '#{params[:repo]}'")
13
10
 
14
- url = "#{params[:api_url]}/repos/#{params[:repo]}/pulls"
15
- headers = { 'User-Agent' => 'fastlane-create_pull_request' }
16
- headers['Authorization'] = "Basic #{Base64.strict_encode64(params[:api_token])}" if params[:api_token]
17
-
18
- data = {
11
+ payload = {
19
12
  'title' => params[:title],
20
13
  'head' => params[:head],
21
14
  'base' => params[:base]
22
15
  }
16
+ payload['body'] = params[:body] if params[:body]
23
17
 
24
- data['body'] = params[:body] if params[:body]
25
-
26
- response = Excon.post(url, headers: headers, body: data.to_json)
27
-
28
- if response[:status] == 201
29
- body = JSON.parse(response.body)
30
- number = body['number']
31
- html_url = body['html_url']
18
+ GithubApiAction.run(
19
+ server_url: params[:api_url],
20
+ api_token: params[:api_token],
21
+ http_method: 'POST',
22
+ path: "repos/#{params[:repo]}/pulls",
23
+ body: payload,
24
+ error_handlers: {
25
+ '*' => proc do |result|
26
+ UI.error("GitHub responded with #{result[:status]}: #{result[:body]}")
27
+ return nil
28
+ end
29
+ }
30
+ ) do |result|
31
+ json = result[:json]
32
+ number = json['number']
33
+ html_url = json['html_url']
32
34
  UI.success("Successfully created pull request ##{number}. You can see it at '#{html_url}'")
33
35
 
34
36
  Actions.lane_context[SharedValues::CREATE_PULL_REQUEST_HTML_URL] = html_url
35
- elsif response[:status] != 200
36
- UI.error("GitHub responded with #{response[:status]}: #{response[:body]}")
37
+ return json
37
38
  end
38
39
  end
39
40
 
@@ -91,13 +92,17 @@ module Fastlane
91
92
  end
92
93
 
93
94
  def self.author
94
- ["seei"]
95
+ ["seei", "tommeier"]
95
96
  end
96
97
 
97
98
  def self.is_supported?(platform)
98
99
  return true
99
100
  end
100
101
 
102
+ def self.return_value
103
+ "The parsed JSON when successful"
104
+ end
105
+
101
106
  def self.example_code
102
107
  [
103
108
  'create_pull_request(
@@ -7,43 +7,38 @@ module Fastlane
7
7
  class GetGithubReleaseAction < Action
8
8
  def self.run(params)
9
9
  UI.message("Getting release on GitHub (#{params[:server_url]}/#{params[:url]}: #{params[:version]})")
10
- require 'excon'
11
- require 'base64'
12
10
 
13
- server_url = params[:server_url]
14
- server_url = server_url[0..-2] if server_url.end_with? '/'
15
-
16
- headers = { 'User-Agent' => 'fastlane-get_github_release' }
17
- headers['Authorization'] = "Basic #{Base64.strict_encode64(params[:api_token])}" if params[:api_token]
18
-
19
- # To still get the data when a repo has been moved
20
- middlewares = Excon.defaults[:middlewares] + [Excon::Middleware::RedirectFollower]
21
- response = Excon.get("#{server_url}/repos/#{params[:url]}/releases", headers: headers, middlewares: middlewares)
22
-
23
- case response[:status]
24
- when 404
25
- UI.error("Repository #{params[:url]} cannot be found, please double check its name and that you provided a valid API token (if it's a private repository).")
26
- return nil
27
- when 401
28
- UI.error("You are not authorized to access #{params[:url]}, please make sure you provided a valid API token.")
29
- return nil
30
- else
31
- if response[:status] != 200
32
- UI.error("GitHub responded with #{response[:status]}:#{response[:body]}")
33
- return nil
11
+ GithubApiAction.run(
12
+ server_url: params[:server_url],
13
+ api_token: params[:api_token],
14
+ http_method: 'GET',
15
+ path: "repos/#{params[:url]}/releases",
16
+ error_handlers: {
17
+ 404 => proc do |result|
18
+ UI.error("Repository #{params[:url]} cannot be found, please double check its name and that you provided a valid API token (if it's a private repository).")
19
+ return nil
20
+ end,
21
+ 401 => proc do |result|
22
+ UI.error("You are not authorized to access #{params[:url]}, please make sure you provided a valid API token.")
23
+ return nil
24
+ end,
25
+ '*' => proc do |result|
26
+ UI.error("GitHub responded with #{result[:status]}:#{result[:body]}")
27
+ return nil
28
+ end
29
+ }
30
+ ) do |result|
31
+ json = result[:json]
32
+ json.each do |current|
33
+ next unless current['tag_name'] == params[:version]
34
+
35
+ # Found it
36
+ Actions.lane_context[SharedValues::GET_GITHUB_RELEASE_INFO] = current
37
+ UI.message("Version is already live on GitHub.com 🚁")
38
+ return current
34
39
  end
35
40
  end
36
41
 
37
- result = JSON.parse(response.body)
38
- result.each do |current|
39
- next unless current['tag_name'] == params[:version]
40
-
41
- # Found it
42
- Actions.lane_context[SharedValues::GET_GITHUB_RELEASE_INFO] = current
43
- UI.message("Version is already live on GitHub.com 🚁")
44
- return current
45
- end
46
-
47
42
  UI.important("Couldn't find GitHub release #{params[:version]}")
48
43
  return nil
49
44
  end
@@ -128,15 +123,15 @@ module Fastlane
128
123
  env_name: "FL_GET_GITHUB_RELEASE_VERSION",
129
124
  description: "The version tag of the release to check"),
130
125
  FastlaneCore::ConfigItem.new(key: :api_token,
131
- env_name: "FL_GITHUB_RELEASE_API_TOKEN",
132
- sensitive: true,
133
- description: "GitHub Personal Token (required for private repositories)",
134
- optional: true)
126
+ env_name: "FL_GITHUB_RELEASE_API_TOKEN",
127
+ sensitive: true,
128
+ description: "GitHub Personal Token (required for private repositories)",
129
+ optional: true)
135
130
  ]
136
131
  end
137
132
 
138
133
  def self.authors
139
- ["KrauseFx", "czechboy0", "jaleksynas"]
134
+ ["KrauseFx", "czechboy0", "jaleksynas", "tommeier"]
140
135
  end
141
136
 
142
137
  def self.is_supported?(platform)
@@ -0,0 +1,258 @@
1
+ module Fastlane
2
+ module Actions
3
+ module SharedValues
4
+ GITHUB_API_STATUS_CODE = :GITHUB_API_STATUS_CODE
5
+ GITHUB_API_RESPONSE = :GITHUB_API_RESPONSE
6
+ GITHUB_API_JSON = :GITHUB_API_JSON
7
+ end
8
+
9
+ class GithubApiAction < Action
10
+ class << self
11
+ def run(params)
12
+ require 'json'
13
+
14
+ http_method = (params[:http_method] || 'GET').to_s.upcase
15
+ url = construct_url(params[:server_url], params[:path], params[:url])
16
+ headers = construct_headers(params[:api_token], params[:headers])
17
+ payload = construct_body(params[:body], params[:raw_body])
18
+ error_handlers = params[:error_handlers] || {}
19
+ secure = params[:secure] || true
20
+
21
+ response = call_endpoint(
22
+ url,
23
+ http_method,
24
+ headers,
25
+ payload,
26
+ secure
27
+ )
28
+
29
+ status_code = response[:status]
30
+ result = {
31
+ status: status_code,
32
+ body: response.body || "",
33
+ json: parse_json(response.body) || {}
34
+ }
35
+
36
+ if status_code.between?(200, 299)
37
+ UI.verbose("Response:")
38
+ UI.verbose(response.body)
39
+ UI.verbose("---")
40
+ yield(result) if block_given?
41
+ else
42
+ handled_error = error_handlers[status_code] || error_handlers['*']
43
+ if handled_error
44
+ handled_error.call(result)
45
+ else
46
+ UI.error("---")
47
+ UI.error("Request failed:\n#{http_method}: #{url}")
48
+ UI.error("Headers:\n#{headers}")
49
+ UI.error("---")
50
+ UI.error("Response:")
51
+ UI.error(response.body)
52
+ UI.user_error!("GitHub responded with #{status_code}\n---\n#{response.body}")
53
+ end
54
+ end
55
+
56
+ Actions.lane_context[SharedValues::GITHUB_API_STATUS_CODE] = result[:status]
57
+ Actions.lane_context[SharedValues::GITHUB_API_RESPONSE] = result[:body]
58
+ Actions.lane_context[SharedValues::GITHUB_API_JSON] = result[:json]
59
+
60
+ return result
61
+ end
62
+
63
+ #####################################################
64
+ # @!group Documentation
65
+ #####################################################
66
+
67
+ def description
68
+ "Call a GitHub API endpoint and get the resulting JSON response"
69
+ end
70
+
71
+ def details
72
+ "Calls any GitHub API endpoint. You must provide your GitHub Personal token (get one from https://github.com/settings/tokens/new).
73
+ Out parameters provide the status code and the full response JSON if valid, otherwise the raw response body.
74
+ Documentation: https://developer.github.com/v3"
75
+ end
76
+
77
+ def available_options
78
+ [
79
+ FastlaneCore::ConfigItem.new(key: :server_url,
80
+ env_name: "FL_GITHUB_API_SERVER_URL",
81
+ description: "The server url. e.g. 'https://your.internal.github.host/api/v3' (Default: 'https://api.github.com')",
82
+ default_value: "https://api.github.com",
83
+ optional: true,
84
+ verify_block: proc do |value|
85
+ UI.user_error!("Please include the protocol in the server url, e.g. https://your.github.server/api/v3") unless value.include? "//"
86
+ end),
87
+ FastlaneCore::ConfigItem.new(key: :api_token,
88
+ env_name: "FL_GITHUB_API_TOKEN",
89
+ description: "Personal API Token for GitHub - generate one at https://github.com/settings/tokens",
90
+ sensitive: true,
91
+ is_string: true,
92
+ default_value: ENV["GITHUB_API_TOKEN"],
93
+ optional: false),
94
+ FastlaneCore::ConfigItem.new(key: :http_method,
95
+ env_name: "FL_GITHUB_API_HTTP_METHOD",
96
+ description: "The HTTP method. e.g. GET / POST",
97
+ default_value: "GET",
98
+ optional: true,
99
+ verify_block: proc do |value|
100
+ unless %w(GET POST PUT DELETE HEAD CONNECT).include?(value.to_s.upcase)
101
+ UI.user_error!("Unrecognised HTTP method")
102
+ end
103
+ end),
104
+ FastlaneCore::ConfigItem.new(key: :body,
105
+ env_name: "FL_GITHUB_API_REQUEST_BODY",
106
+ description: "The request body in JSON or hash format",
107
+ is_string: false,
108
+ default_value: {},
109
+ optional: true),
110
+ FastlaneCore::ConfigItem.new(key: :raw_body,
111
+ env_name: "FL_GITHUB_API_REQUEST_RAW_BODY",
112
+ description: "The request body taken vertabim instead of as JSON, useful for file uploads",
113
+ is_string: true,
114
+ optional: true),
115
+ FastlaneCore::ConfigItem.new(key: :path,
116
+ env_name: "FL_GITHUB_API_PATH",
117
+ description: "The endpoint path. e.g. '/repos/:owner/:repo/readme'",
118
+ optional: true),
119
+ FastlaneCore::ConfigItem.new(key: :url,
120
+ env_name: "FL_GITHUB_API_URL",
121
+ description: "The complete full url - used instead of path. e.g. 'https://uploads.github.com/repos/fastlane...'",
122
+ optional: true,
123
+ verify_block: proc do |value|
124
+ UI.user_error!("Please include the protocol in the url, e.g. https://uploads.github.com") unless value.include? "//"
125
+ end),
126
+ FastlaneCore::ConfigItem.new(key: :error_handlers,
127
+ description: "Optional error handling hash based on status code, or pass '*' to handle all errors",
128
+ is_string: false,
129
+ default_value: {},
130
+ optional: true),
131
+ FastlaneCore::ConfigItem.new(key: :headers,
132
+ description: "Optional headers to apply",
133
+ is_string: false,
134
+ default_value: {},
135
+ optional: true),
136
+ FastlaneCore::ConfigItem.new(key: :secure,
137
+ env_name: "FL_GITHUB_API_SECURE",
138
+ description: "Optionally disable secure requests (ssl_verify_peer)",
139
+ is_string: false,
140
+ default_value: true,
141
+ optional: true)
142
+ ]
143
+ end
144
+
145
+ def output
146
+ [
147
+ ['GITHUB_API_STATUS_CODE', 'The status code returned from the request'],
148
+ ['GITHUB_API_RESPONSE', 'The full response body'],
149
+ ['GITHUB_API_JSON', 'The parsed json returned from GitHub']
150
+ ]
151
+ end
152
+
153
+ def return_value
154
+ "A hash including the HTTP status code (:status), the response body (:body), and if valid JSON has been returned the parsed JSON (:json)."
155
+ end
156
+
157
+ def authors
158
+ ["tommeier"]
159
+ end
160
+
161
+ def example_code
162
+ [
163
+ 'result = github_api(
164
+ server_url: "https://api.github.com",
165
+ api_token: ENV["GITHUB_TOKEN"],
166
+ http_method: "GET",
167
+ path: "/repos/:owner/:repo/readme",
168
+ body: { ref: "master" }
169
+ )',
170
+ '# Alternatively call directly with optional error handling or block usage
171
+ GithubApiAction.run(
172
+ server_url: "https://api.github.com",
173
+ api_token: ENV["GITHUB_TOKEN"],
174
+ http_method: "GET",
175
+ path: "/repos/:owner/:repo/readme",
176
+ error_handlers: {
177
+ 404 => proc do |result|
178
+ UI.message("Something went wrong - I couldn\'t find it...")
179
+ end,
180
+ \'*\' => proc do |result|
181
+ UI.message("Handle all error codes other than 404")
182
+ end
183
+ }
184
+ ) do |result|
185
+ UI.message("JSON returned: #{result[:json]}")
186
+ end
187
+ '
188
+ ]
189
+ end
190
+
191
+ def is_supported?(platform)
192
+ true
193
+ end
194
+
195
+ def category
196
+ :source_control
197
+ end
198
+
199
+ private
200
+
201
+ def construct_headers(api_token, overrides)
202
+ require 'base64'
203
+ headers = { 'User-Agent' => 'fastlane-github_api' }
204
+ headers['Authorization'] = "Basic #{Base64.strict_encode64(api_token)}" if api_token
205
+ headers.merge(overrides || {})
206
+ end
207
+
208
+ def construct_url(server_url, path, url)
209
+ UI.user_error!("Please provide server URL, eg: https://api.github.com") unless server_url
210
+
211
+ return_url = path ? File.join(server_url, path) : url
212
+
213
+ UI.user_error!("Please provide either 'path' or full 'url' for GitHub API endpoint") unless return_url
214
+
215
+ return_url
216
+ end
217
+
218
+ def construct_body(body, raw_body)
219
+ body ||= {}
220
+
221
+ if raw_body
222
+ raw_body
223
+ elsif body.kind_of?(Hash)
224
+ body.to_json
225
+ else
226
+ UI.user_error!("Please provide valid JSON, or a hash as request body") unless parse_json(body)
227
+ body
228
+ end
229
+ end
230
+
231
+ def parse_json(value)
232
+ JSON.parse(value)
233
+ rescue JSON::ParserError
234
+ nil
235
+ end
236
+
237
+ def call_endpoint(url, http_method, headers, body, secure)
238
+ require 'excon'
239
+
240
+ Excon.defaults[:ssl_verify_peer] = secure
241
+ middlewares = Excon.defaults[:middlewares] + [Excon::Middleware::RedirectFollower] # allow redirect in case of repo renames
242
+
243
+ UI.verbose("#{http_method} : #{url}")
244
+
245
+ connection = Excon.new(url)
246
+ connection.request(
247
+ method: http_method,
248
+ headers: headers,
249
+ middlewares: middlewares,
250
+ body: body,
251
+ debug_request: FastlaneCore::Globals.verbose?,
252
+ debug_response: FastlaneCore::Globals.verbose?
253
+ )
254
+ end
255
+ end
256
+ end
257
+ end
258
+ end
@@ -4,11 +4,24 @@ module Fastlane
4
4
  def self.run(params)
5
5
  require 'fileutils'
6
6
 
7
- unless params[:github].nil?
8
- github_api_url = params[:github].sub('https://github.com', 'https://api.github.com/repos')
9
- release = self.fetch_json(github_api_url + '/releases/latest')
10
- return if release.nil?
11
- params[:url] = release['assets'][0]['browser_download_url']
7
+ if params[:github]
8
+ base_api_url = params[:github].sub('https://github.com', 'https://api.github.com/repos')
9
+
10
+ GithubApiAction.run(
11
+ url: File.join(base_api_url, 'releases/latest'),
12
+ http_method: 'GET',
13
+ error_handlers: {
14
+ 404 => proc do |result|
15
+ UI.error("No latest release found for the specified GitHub repository")
16
+ end,
17
+ '*' => proc do |result|
18
+ UI.error("GitHub responded with #{response[:status]}:#{response[:body]}")
19
+ end
20
+ }
21
+ ) do |result|
22
+ return nil if result[:json].nil?
23
+ params[:url] = result[:json]['assets'][0]['browser_download_url']
24
+ end
12
25
  end
13
26
 
14
27
  zip_path = File.join(Dir.tmpdir, 'plugin.zip')
@@ -21,24 +34,6 @@ module Fastlane
21
34
  UI.message("Please restart Xcode to use the newly installed plugin")
22
35
  end
23
36
 
24
- def self.fetch_json(url)
25
- require 'excon'
26
- require 'json'
27
-
28
- response = Excon.get(url)
29
-
30
- if response[:status] != 200
31
- if response[:status] == 404
32
- UI.error("No latest release found for the specified GitHub repository")
33
- else
34
- UI.error("GitHub responded with #{response[:status]}:#{response[:body]}")
35
- end
36
- return nil
37
- end
38
-
39
- JSON.parse(response.body)
40
- end
41
-
42
37
  #####################################################
43
38
  # @!group Documentation
44
39
  #####################################################
@@ -74,7 +69,7 @@ module Fastlane
74
69
  end
75
70
 
76
71
  def self.authors
77
- ["NeoNachoSoto"]
72
+ ["NeoNachoSoto", "tommeier"]
78
73
  end
79
74
 
80
75
  def self.is_supported?(platform)
@@ -11,70 +11,83 @@ module Fastlane
11
11
  UI.important("Creating release of #{params[:repository_name]} on tag \"#{params[:tag_name]}\" with name \"#{params[:name]}\".")
12
12
  UI.important("Will also upload assets #{params[:upload_assets]}.") if params[:upload_assets]
13
13
 
14
- require 'json'
15
- body_obj = {
14
+ repo_name = params[:repository_name]
15
+ api_token = params[:api_token]
16
+ server_url = params[:server_url]
17
+ tag_name = params[:tag_name]
18
+
19
+ payload = {
16
20
  'tag_name' => params[:tag_name],
17
21
  'name' => params[:name],
18
22
  'body' => params[:description],
19
23
  'draft' => !!params[:is_draft],
20
24
  'prerelease' => !!params[:is_prerelease]
21
25
  }
22
- body_obj['target_commitish'] = params[:commitish] if params[:commitish]
23
- body = body_obj.to_json
24
-
25
- repo_name = params[:repository_name]
26
- api_token = params[:api_token]
27
- server_url = params[:server_url]
28
- server_url = server_url[0..-2] if server_url.end_with? '/'
26
+ payload['target_commitish'] = params[:commitish] if params[:commitish]
29
27
 
30
- # create the release
31
- response = call_releases_endpoint("post", server_url, repo_name, "/releases", api_token, body)
28
+ GithubApiAction.run(
29
+ server_url: server_url,
30
+ api_token: api_token,
31
+ http_method: 'POST',
32
+ path: "repos/#{repo_name}/releases",
33
+ body: payload,
34
+ error_handlers: {
35
+ 422 => proc do |result|
36
+ UI.error(result[:body])
37
+ UI.error("Release on tag #{tag_name} already exists!")
38
+ return nil
39
+ end,
40
+ 404 => proc do |result|
41
+ UI.error(result[:body])
42
+ UI.user_error!("Repository #{repo_name} cannot be found, please double check its name and that you provided a valid API token (GITHUB_API_TOKEN)")
43
+ end,
44
+ 401 => proc do |result|
45
+ UI.error(result[:body])
46
+ UI.user_error!("You are not authorized to access #{repo_name}, please make sure you provided a valid API token (GITHUB_API_TOKEN)")
47
+ end,
48
+ '*' => proc do |result|
49
+ UI.error("GitHub responded with #{result[:status]}:#{result[:body]}")
50
+ return nil
51
+ end
52
+ }
53
+ ) do |result|
54
+ json = result[:json]
55
+ html_url = json['html_url']
56
+ release_id = json['id']
32
57
 
33
- case response[:status]
34
- when 201
35
- UI.success("Successfully created release at tag \"#{params[:tag_name]}\" on GitHub")
36
- body = JSON.parse(response.body)
37
- html_url = body['html_url']
38
- release_id = body['id']
58
+ UI.success("Successfully created release at tag \"#{tag_name}\" on GitHub")
39
59
  UI.important("See release at \"#{html_url}\"")
60
+
40
61
  Actions.lane_context[SharedValues::SET_GITHUB_RELEASE_HTML_LINK] = html_url
41
62
  Actions.lane_context[SharedValues::SET_GITHUB_RELEASE_RELEASE_ID] = release_id
42
- Actions.lane_context[SharedValues::SET_GITHUB_RELEASE_JSON] = body
63
+ Actions.lane_context[SharedValues::SET_GITHUB_RELEASE_JSON] = json
43
64
 
44
65
  assets = params[:upload_assets]
45
66
  if assets && assets.count > 0
46
67
  # upload assets
47
- self.upload_assets(assets, body['upload_url'], api_token)
68
+ self.upload_assets(assets, json['upload_url'], api_token)
48
69
 
49
70
  # fetch the release again, so that it contains the uploaded assets
50
- get_response = self.call_releases_endpoint("get", server_url, repo_name, "/releases/#{release_id}", api_token, nil)
51
- if get_response[:status] != 200
52
- UI.error("GitHub responded with #{response[:status]}:#{response[:body]}")
53
- UI.user_error!("Failed to fetch the newly created release, but it *has been created* successfully.")
71
+ GithubApiAction.run(
72
+ server_url: server_url,
73
+ api_token: api_token,
74
+ http_method: 'GET',
75
+ path: "repos/#{repo_name}/releases/#{release_id}",
76
+ error_handlers: {
77
+ '*' => proc do |get_result|
78
+ UI.error("GitHub responded with #{get_result[:status]}:#{get_result[:body]}")
79
+ UI.user_error!("Failed to fetch the newly created release, but it *has been created* successfully.")
80
+ end
81
+ }
82
+ ) do |get_result|
83
+ Actions.lane_context[SharedValues::SET_GITHUB_RELEASE_JSON] = get_result[:json]
84
+ UI.success("Successfully uploaded assets #{assets} to release \"#{html_url}\"")
85
+ return get_result[:json]
54
86
  end
55
-
56
- get_body = JSON.parse(get_response.body)
57
- Actions.lane_context[SharedValues::SET_GITHUB_RELEASE_JSON] = get_body
58
- UI.success("Successfully uploaded assets #{assets} to release \"#{html_url}\"")
59
- return get_body
60
87
  else
61
- return body
62
- end
63
- when 422
64
- UI.error(response.body)
65
- UI.error("Release on tag #{params[:tag_name]} already exists!")
66
- when 404
67
- UI.error(response.body)
68
- UI.user_error!("Repository #{params[:repository_name]} cannot be found, please double check its name and that you provided a valid API token (GITHUB_API_TOKEN)")
69
- when 401
70
- UI.error(response.body)
71
- UI.user_error!("You are not authorized to access #{params[:repository_name]}, please make sure you provided a valid API token (GITHUB_API_TOKEN)")
72
- else
73
- if response[:status] != 200
74
- UI.error("GitHub responded with #{response[:status]}:#{response[:body]}")
88
+ return json || result[:body]
75
89
  end
76
90
  end
77
- return nil
78
91
  end
79
92
 
80
93
  def self.upload_assets(assets, upload_url_template, api_token)
@@ -90,65 +103,41 @@ module Fastlane
90
103
  # check that the asset even exists
91
104
  UI.user_error!("Asset #{absolute_path} doesn't exist") unless File.exist?(absolute_path)
92
105
 
93
- name = File.basename(absolute_path)
94
- response = nil
95
106
  if File.directory?(absolute_path)
96
107
  Dir.mktmpdir do |dir|
97
108
  tmpzip = File.join(dir, File.basename(absolute_path) + '.zip')
98
- name = File.basename(tmpzip)
99
109
  sh "cd \"#{File.dirname(absolute_path)}\"; zip -r --symlinks \"#{tmpzip}\" \"#{File.basename(absolute_path)}\" 2>&1 >/dev/null"
100
- response = self.upload_file(tmpzip, upload_url_template, api_token)
110
+ self.upload_file(tmpzip, upload_url_template, api_token)
101
111
  end
102
112
  else
103
- response = self.upload_file(absolute_path, upload_url_template, api_token)
113
+ self.upload_file(absolute_path, upload_url_template, api_token)
104
114
  end
105
- return response
106
115
  end
107
116
 
108
117
  def self.upload_file(file, url_template, api_token)
109
118
  require 'addressable/template'
110
- name = File.basename(file)
111
- expanded_url = Addressable::Template.new(url_template).expand(name: name).to_s
112
- headers = self.headers(api_token)
113
- headers['Content-Type'] = 'application/zip' # how do we detect other types e.g. other binary files? file extensions?
114
-
115
- UI.important("Uploading #{name}")
116
- response = self.call_endpoint(expanded_url, "post", headers, File.read(file))
117
-
118
- # inspect the response
119
- case response.status
120
- when 201
121
- # all good in the hood
122
- UI.success("Successfully uploaded #{name}.")
123
- else
124
- UI.error("GitHub responded with #{response[:status]}:#{response[:body]}")
125
- UI.user_error!("Failed to upload asset #{name} to GitHub.")
119
+ file_name = File.basename(file)
120
+ expanded_url = Addressable::Template.new(url_template).expand(name: file_name).to_s
121
+ headers = {}
122
+ if File.extname(file_name).to_s.casecmp('.zip').zero?
123
+ headers['Content-Type'] = 'application/zip'
126
124
  end
127
- end
128
-
129
- def self.call_endpoint(url, method, headers, body)
130
- require 'excon'
131
- case method
132
- when "post"
133
- response = Excon.post(url, headers: headers, body: body)
134
- when "get"
135
- response = Excon.get(url, headers: headers, body: body)
136
- else
137
- UI.user_error!("Unsupported method #{method}")
125
+ UI.important("Uploading #{file_name}")
126
+ GithubApiAction.run(
127
+ api_token: api_token,
128
+ http_method: 'POST',
129
+ headers: headers,
130
+ url: expanded_url,
131
+ raw_body: File.read(file),
132
+ error_handlers: {
133
+ '*' => proc do |result|
134
+ UI.error("GitHub responded with #{result[:status]}:#{result[:body]}")
135
+ UI.user_error!("Failed to upload asset #{file_name} to GitHub.")
136
+ end
137
+ }
138
+ ) do |result|
139
+ UI.success("Successfully uploaded #{file_name}.")
138
140
  end
139
- return response
140
- end
141
-
142
- def self.call_releases_endpoint(method, server, repo, endpoint, api_token, body)
143
- url = "#{server}/repos/#{repo}#{endpoint}"
144
- self.call_endpoint(url, method, self.headers(api_token), body)
145
- end
146
-
147
- def self.headers(api_token)
148
- require 'base64'
149
- headers = { 'User-Agent' => 'fastlane-set_github_release' }
150
- headers['Authorization'] = "Basic #{Base64.strict_encode64(api_token)}" if api_token
151
- headers
152
141
  end
153
142
 
154
143
  #####################################################
@@ -251,7 +240,7 @@ module Fastlane
251
240
  end
252
241
 
253
242
  def self.authors
254
- ["czechboy0"]
243
+ ["czechboy0", "tommeier"]
255
244
  end
256
245
 
257
246
  def self.is_supported?(platform)
@@ -273,7 +262,7 @@ module Fastlane
273
262
  end
274
263
 
275
264
  def self.category
276
- :misc
265
+ :source_control
277
266
  end
278
267
  end
279
268
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.50.0.beta.20170731010002'.freeze
2
+ VERSION = '2.50.0'.freeze
3
3
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
4
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
5
  end
data/gym/README.md CHANGED
@@ -157,7 +157,7 @@ output_name "MyApp" # the name of the ipa file
157
157
 
158
158
  ## Export options
159
159
 
160
- Since Xcode 7, `gym` is using new Xcode API which allows us to specify export options using `plist` file. By default `gym` creates this file for you and you are able to modify some parameters by using `export_method`, `export_team_id`, `include_symbols` or `include_bitcode`. If you want to have more options, like creating manifest file or app thinning, you can provide your own `plist` file:
160
+ Since Xcode 7, `gym` is using new Xcode API which allows us to specify export options using `plist` file. By default `gym` creates this file for you and you are able to modify some parameters by using `export_method`, `export_team_id`, `include_symbols` or `include_bitcode`. If you want to have more options, like creating manifest file for app thinning, you can provide your own `plist` file:
161
161
 
162
162
  ```ruby
163
163
  export_options "./ExportOptions.plist"
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.50.0.beta.20170731010002
4
+ version: 2.50.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
@@ -863,6 +863,7 @@ files:
863
863
  - fastlane/lib/fastlane/actions/clipboard.rb
864
864
  - fastlane/lib/fastlane/actions/cloc.rb
865
865
  - fastlane/lib/fastlane/actions/cocoapods.rb
866
+ - fastlane/lib/fastlane/actions/commit_github_file.rb
866
867
  - fastlane/lib/fastlane/actions/commit_version_bump.rb
867
868
  - fastlane/lib/fastlane/actions/copy_artifacts.rb
868
869
  - fastlane/lib/fastlane/actions/crashlytics.rb
@@ -899,6 +900,7 @@ files:
899
900
  - fastlane/lib/fastlane/actions/git_commit.rb
900
901
  - fastlane/lib/fastlane/actions/git_pull.rb
901
902
  - fastlane/lib/fastlane/actions/git_tag_exists.rb
903
+ - fastlane/lib/fastlane/actions/github_api.rb
902
904
  - fastlane/lib/fastlane/actions/google_play_track_version_codes.rb
903
905
  - fastlane/lib/fastlane/actions/gradle.rb
904
906
  - fastlane/lib/fastlane/actions/gym.rb
@@ -1091,6 +1093,7 @@ files:
1091
1093
  - fastlane_core/README.md
1092
1094
  - fastlane_core/lib/assets/XMLTemplate.xml.erb
1093
1095
  - fastlane_core/lib/fastlane_core.rb
1096
+ - fastlane_core/lib/fastlane_core/.DS_Store
1094
1097
  - fastlane_core/lib/fastlane_core/build_watcher.rb
1095
1098
  - fastlane_core/lib/fastlane_core/cert_checker.rb
1096
1099
  - fastlane_core/lib/fastlane_core/command_executor.rb
@@ -1382,6 +1385,7 @@ files:
1382
1385
  - spaceship/lib/spaceship/two_step_client.rb
1383
1386
  - spaceship/lib/spaceship/ui.rb
1384
1387
  - supply/README.md
1388
+ - supply/lib/.DS_Store
1385
1389
  - supply/lib/supply.rb
1386
1390
  - supply/lib/supply/apk_listing.rb
1387
1391
  - supply/lib/supply/client.rb
@@ -1399,24 +1403,24 @@ metadata:
1399
1403
  post_install_message:
1400
1404
  rdoc_options: []
1401
1405
  require_paths:
1402
- - spaceship/lib
1403
- - scan/lib
1404
- - sigh/lib
1405
- - snapshot/lib
1406
- - screengrab/lib
1407
- - fastlane/lib
1408
1406
  - cert/lib
1409
- - pem/lib
1410
- - gym/lib
1411
- - produce/lib
1407
+ - credentials_manager/lib
1412
1408
  - deliver/lib
1413
- - supply/lib
1414
- - match/lib
1409
+ - fastlane/lib
1410
+ - fastlane_core/lib
1415
1411
  - frameit/lib
1416
- - credentials_manager/lib
1412
+ - gym/lib
1413
+ - match/lib
1414
+ - pem/lib
1417
1415
  - pilot/lib
1418
1416
  - precheck/lib
1419
- - fastlane_core/lib
1417
+ - produce/lib
1418
+ - scan/lib
1419
+ - screengrab/lib
1420
+ - sigh/lib
1421
+ - snapshot/lib
1422
+ - spaceship/lib
1423
+ - supply/lib
1420
1424
  required_ruby_version: !ruby/object:Gem::Requirement
1421
1425
  requirements:
1422
1426
  - - ">="
@@ -1424,14 +1428,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
1424
1428
  version: 2.0.0
1425
1429
  required_rubygems_version: !ruby/object:Gem::Requirement
1426
1430
  requirements:
1427
- - - ">"
1431
+ - - ">="
1428
1432
  - !ruby/object:Gem::Version
1429
- version: 1.3.1
1433
+ version: '0'
1430
1434
  requirements: []
1431
1435
  rubyforge_project:
1432
- rubygems_version: 2.4.5.1
1436
+ rubygems_version: 2.5.2
1433
1437
  signing_key:
1434
1438
  specification_version: 4
1435
1439
  summary: The easiest way to automate beta deployments and releases for your iOS and
1436
1440
  Android apps
1437
1441
  test_files: []
1442
+ has_rdoc: