fastlane 2.50.0.beta.20170731010002 → 2.50.0

Sign up to get free protection for your applications and to get access to all the features.
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: