fastlane-plugin-bitrise_automation 0.1.0 → 0.3.1

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
  SHA256:
3
- metadata.gz: '0241689ccd66d05a0836120f501ef00feffdfa51348545c49b66b32eaa01dd82'
4
- data.tar.gz: 8e60ba4980310e128b1d8f2027ba957a93edef5da559f3a50176d22e40a3256d
3
+ metadata.gz: 995f0a752fe79b180ba1fbd4d9f74b8dba9b61946dfc4ae8f0234d5eb9dd1e87
4
+ data.tar.gz: 7637f6ad20acb0880c3f0c9e3455c86fa058a24788266b56a3c8b7c5b6cac9bc
5
5
  SHA512:
6
- metadata.gz: 6495f2a4420b45222c9c9d0a876fbb22895da86aa10c7d844f2067ebbd67be5f79c4a5001b800345e9955c9f6f6b97c01547c35013927a90c04e4526e08b4b46
7
- data.tar.gz: a38360cbfa1de1e1cd476fa4afd768456dd443571f02e00aaa3bf489e45dc2724a431a5991333e9647e71388d4dac02b97cc8ab59d6d842661eecbbb66629dbe
6
+ metadata.gz: 06054d6a913718bc2ae33e4705d3238b573fc7a1f6fb0da068c8a41f653d7a53d07ecb4133f67bb20c3c06c4b0abfa2d22aa27a8f67b3617c30c811efdf55505
7
+ data.tar.gz: 6b68a62d4ed134d5619bdc9021c9cf516aac6d4b3079f9b767a36e3896a2e8e29273b0cec9872b7f4b4b601b897dc2ad3e15bb640e215cca703bd3757a222628
data/README.md CHANGED
@@ -12,7 +12,7 @@ fastlane add_plugin bitrise_automation
12
12
 
13
13
  ## About bitrise_automation
14
14
 
15
- Interact with [Bitrise](https://bitrise.io/) projects from fastlane.
15
+ Interact with [Bitrise](https://bitrise.io/) projects from fastlane. This allows you to trigger a Bitrise workflow and its related information using the [Bitrise API](https://devcenter.bitrise.io/api/api-index/).
16
16
 
17
17
  This is useful if you want to interact with Bitrise from your terminal using Fastlane or if you are encapsulating Bitrise builds from another CI (such as Jenkins).
18
18
 
@@ -25,14 +25,79 @@ This plugin assumes you already have an app configured on Bitrise and uses a Per
25
25
  - Check build success/failure (exiting with success or failure according to the status on Bitrise)
26
26
  - Retrieve the list of artifacts from a build
27
27
  - Download the artifacts produced by a build
28
+ - Automatic retry of requests when the connection to the Bitrise API fails or returns a 5xx error
28
29
 
29
30
  ### Known issues
30
31
 
31
- - For now the only option is to trigger a build via a commit hash. It should be more flexible as Bitrise allows triggering by branch, tag, commit or default strategy.
32
+ - Triggering a build with a tag is not yet implemented
32
33
  - The author option to trigger the build is not implemented
33
34
  - The environments option to trigger the build is not implemented
34
35
  - Pagination on API responses is not implemented
35
36
 
37
+ ## Usage
38
+
39
+ It is recommended to set the `BITRISE_APP_SLUG` and `BITRISE_ACCESS_TOKEN` environment variables to avoid committing those values into your repository.
40
+
41
+ ### trigger_bitrise_workflow
42
+ Use this action to trigger a workflow on Bitrise and query its status.
43
+
44
+ | Key | Description | Environment variable | Default value |
45
+ | --- | --- | --- | --- |
46
+ | `app_slug` | The app slug of the project on Bitrise | BITRISE_APP_SLUG | |
47
+ | `access_token` | The [personal access token](https://devcenter.bitrise.io/api/authentication/) used to call Bitrise API | BITRISE_ACCESS_TOKEN | |
48
+ | `workflow` | The name of the workflow to trigger | BITRISE_WORKFLOW | |
49
+ | `branch` | The name of branch that will be checked out | BITRISE_BUILD_BRANCH | |
50
+ | `commit_hash` | The hash of the commit that will be checked out (overrides branch parameter) | BITRISE_BUILD_COMMIT_HASH | |
51
+ | `build_message` | A custom message that will be used to identify the build | BITRISE_BUILD_MESSAGE | |
52
+ | `triggered_by` | A custom message that will be used to identify where the build was triggered from (optional) | BITRISE_BUILD_TRIGGERED_BY | |
53
+ | `wait_for_build` | Whether the action should wait until the build finishes or return immediately after requesting the build | BITRISE_WAIT_FOR_BUILD | false |
54
+ | `download_artifacts` | Whether to download or not the produced artifacts | BITRISE_DOWNLOAD_ARTIFACTS | false |
55
+
56
+ The returned value is a hash containing the information about the build.
57
+
58
+ | Hash key | Description |
59
+ | --- | --- |
60
+ | `status` | The status of the build |
61
+ | `build_slug` | The build slug that can be used to identify the build on other actions |
62
+ | `build_number` | The build number |
63
+ | `build_url` | The URL to the build page on Bitrise |
64
+
65
+ ### bitrise_build_status
66
+ Use this action to query the status of a build on Bitrise.
67
+
68
+ | Key | Description | Environment variable | Default value |
69
+ | --- | --- | --- | --- |
70
+ | `app_slug` | The app slug of the project on Bitrise | BITRISE_APP_SLUG | |
71
+ | `access_token` | The [personal access token](https://devcenter.bitrise.io/api/authentication/) used to call Bitrise API | BITRISE_ACCESS_TOKEN | |
72
+ | `build_slug` | The slug that identifies the build on Bitrise | BITRISE_BUILD_SLUG | |
73
+
74
+ The returned value is a hash containing the information about the build status.
75
+
76
+ | Hash key | Description |
77
+ | --- | --- |
78
+ | `status` | The status of the build: not finished (0), successful (1), failed (2), aborted with failure (3), aborted with success (4) |
79
+ | `status_text` | The status text |
80
+ | `is_on_hold` | Indicates whether the build has started yet (true: the build hasn't started) |
81
+ | `abort_reason` | If the build has been aborted, indicates the reason why |
82
+
83
+ ### bitrise_build_artifacts
84
+ Use this action to retrieve information about the artifacts of a build or to automatically download them from Bitrise.
85
+
86
+ | Key | Description | Environment variable | Default value |
87
+ | --- | --- | --- | --- |
88
+ | `app_slug` | The app slug of the project on Bitrise | BITRISE_APP_SLUG | |
89
+ | `access_token` | The [personal access token](https://devcenter.bitrise.io/api/authentication/) used to call Bitrise API | BITRISE_ACCESS_TOKEN | |
90
+ | `build_slug` | The slug that identifies the build on Bitrise | BITRISE_BUILD_SLUG | |
91
+ | `download_artifacts` | Whether to download or not the produced artifacts | BITRISE_DOWNLOAD_ARTIFACTS | false |
92
+
93
+ The returned value is an list of hashes containing the information about the artifacts. If there are no artifacts, it returns an empty list.
94
+
95
+ | Hash key | Description |
96
+ | --- | --- |
97
+ | `artifact_type` | The type of the artifact as detected by Bitrise |
98
+ | `file_size_bytes` | The size of the artifact in bytes |
99
+ | `slug` | The slug that identifies the artifact |
100
+ | `title` | The name of artifact |
36
101
 
37
102
  ## Example
38
103
 
@@ -5,7 +5,11 @@ module Fastlane
5
5
  module Actions
6
6
  class BitriseBuildArtifactsAction < Action
7
7
  def self.run(params)
8
- response = Helper::BitriseRequestHelper.get(params, "builds/#{params[:build_slug]}/artifacts")
8
+ get_artifacts(params, params[:build_slug])
9
+ end
10
+
11
+ def self.get_artifacts(params, build_slug)
12
+ response = Helper::BitriseRequestHelper.get(params, "builds/#{build_slug}/artifacts")
9
13
 
10
14
  if response.code == "200"
11
15
  json_response = JSON.parse(response.body)['data']
@@ -13,7 +17,7 @@ module Fastlane
13
17
  UI.crash!("Error fetching build artifacts list on Bitrise.io. Status code: #{response.code}. #{response}")
14
18
  end
15
19
 
16
- UI.message("Found #{json_response.size} artifacts on Bitrise for build #{params[:build_slug]}.")
20
+ UI.message("Found #{json_response.size} artifacts on Bitrise for build #{build_slug}.")
17
21
 
18
22
  artifacts = json_response.map do |artifact|
19
23
  {
@@ -29,14 +33,14 @@ module Fastlane
29
33
  title: artifact['title'])
30
34
  end
31
35
 
32
- if params[:download]
36
+ if params[:download_artifacts] && !artifacts.empty?
33
37
  artifacts_dir = 'artifacts'
34
- UI.message("Download option is on. Will start download of #{artifacts.size} artifacts to #{artifacts_dir}.")
38
+ UI.message("Download option is on. Will start download of #{artifacts.size} artifacts to '#{artifacts_dir}'.")
35
39
  Dir.mkdir(artifacts_dir) unless Dir.exist?(artifacts_dir)
36
40
 
37
41
  artifacts.each do |artifact|
38
42
  UI.message("Fetching artifact '#{artifact['title']}' of type '#{artifact['artifact_type']}' (#{artifact['file_size_bytes']} bytes)...")
39
- artifact_details = get_artifact_details(params, artifact['slug'])
43
+ artifact_details = get_artifact_details(params, build_slug, artifact['slug'])
40
44
 
41
45
  download_artifact(artifact_details, artifacts_dir)
42
46
  UI.message("Finished downloading artifact '#{artifact['title']}'.")
@@ -46,8 +50,8 @@ module Fastlane
46
50
  artifacts
47
51
  end
48
52
 
49
- def self.get_artifact_details(params, artifact_slug)
50
- response = Helper::BitriseRequestHelper.get(params, "builds/#{params[:build_slug]}/artifacts/#{artifact_slug}")
53
+ def self.get_artifact_details(params, build_slug, artifact_slug)
54
+ response = Helper::BitriseRequestHelper.get(params, "builds/#{build_slug}/artifacts/#{artifact_slug}")
51
55
 
52
56
  if response.code == "200"
53
57
  json_response = JSON.parse(response.body)['data']
@@ -94,8 +98,8 @@ module Fastlane
94
98
  description: "The slug that identifies the build on Bitrise",
95
99
  optional: false,
96
100
  type: String),
97
- FastlaneCore::ConfigItem.new(key: :download,
98
- env_name: "BITRISE_ARTIFACTS_DOWNLOAD",
101
+ FastlaneCore::ConfigItem.new(key: :download_artifacts,
102
+ env_name: "BITRISE_DOWNLOAD_ARTIFACTS",
99
103
  description: "Whether to download or not the produced artifacts",
100
104
  optional: true,
101
105
  default_value: false,
@@ -5,7 +5,10 @@ module Fastlane
5
5
  module Actions
6
6
  class BitriseBuildStatusAction < Action
7
7
  def self.run(params)
8
- get_status(params, params[:build_slug])
8
+ status = get_status(params, params[:build_slug])
9
+ FastlaneCore::PrintTable.print_values(config: status,
10
+ title: "Bitrise build '#{params[:build_slug]}' status")
11
+ status
9
12
  end
10
13
 
11
14
  def self.get_status(params, build_slug)
@@ -21,6 +24,7 @@ module Fastlane
21
24
  build_infos["is_on_hold"] = json_response["is_on_hold"]
22
25
  build_infos["status"] = json_response["status"]
23
26
  build_infos["status_text"] = json_response["status_text"]
27
+ build_infos["abort_reason"] = json_response["abort_reason"]
24
28
  build_infos
25
29
  end
26
30
 
@@ -0,0 +1,38 @@
1
+ require 'fastlane/action'
2
+ require_relative '../helper/bitrise_automation_helper'
3
+
4
+ module Fastlane
5
+ module Actions
6
+ class InterruptAction < Action
7
+ def self.run(params)
8
+ begin
9
+ UI.message("Test interrupt - sleeping")
10
+ sleep(60)
11
+ rescue Interrupt => e
12
+ UI.message("interrupted")
13
+ end
14
+ end
15
+
16
+ def self.description
17
+ "Trigger a Bitrise workflow with the specified parameters, synchronously or asynchronously"
18
+ end
19
+
20
+ def self.authors
21
+ ["Mario Cecchi", "Henrique Alves"]
22
+ end
23
+
24
+ def self.return_value
25
+ "Returns the information of the Bitrise build"
26
+ end
27
+
28
+ def self.available_options
29
+ [
30
+ ]
31
+ end
32
+
33
+ def self.is_supported?(platform)
34
+ true
35
+ end
36
+ end
37
+ end
38
+ end
@@ -5,26 +5,30 @@ module Fastlane
5
5
  module Actions
6
6
  class TriggerBitriseWorkflowAction < Action
7
7
  def self.run(params)
8
- UI.verbose("Requesting new Bitrise.io build...")
8
+ UI.message("Requesting new Bitrise.io build for workflow '#{params[:workflow]}'...")
9
9
 
10
- response = Helper::BitriseRequestHelper.post(params, 'builds', {
10
+ trigger_payload = {
11
11
  hook_info: {
12
12
  type: "bitrise"
13
13
  },
14
14
  build_params: {
15
- workflow_id: params[:workflow],
16
- commit_hash: params[:commit_hash],
17
- commit_message: params[:build_message]
15
+ workflow_id: params[:workflow]
18
16
  }
19
- }.to_json)
17
+ }
18
+ trigger_payload[:build_params][:branch] = params[:branch] unless params[:branch].nil? || params[:branch].empty?
19
+ trigger_payload[:build_params][:commit_hash] = params[:commit_hash] unless params[:commit_hash].nil? || params[:commit_hash].empty?
20
+ trigger_payload[:build_params][:commit_message] = params[:build_message] unless params[:build_message].nil? || params[:build_message].empty?
21
+ trigger_payload[:triggered_by] = params[:triggered_by] unless params[:triggered_by].nil? || params[:triggered_by].empty?
22
+
23
+ response = Helper::BitriseRequestHelper.post(params, 'builds', trigger_payload.to_json)
20
24
 
21
25
  if response.code == "201"
22
26
  json_response = JSON.parse(response.body)
23
- UI.success("Build triggered successfully 🚀 URL: #{json_response['build_url']}")
27
+ UI.success("Build #{json_response['build_number']} triggered successfully on Bitrise 🚀 URL: #{json_response['build_url']}")
24
28
  FastlaneCore::PrintTable.print_values(config: json_response,
25
29
  title: "Bitrise API response")
26
30
  else
27
- UI.crash!("Error requesting new build on Bitrise.io. Status code: #{response.code}. #{response}")
31
+ UI.crash!("Error requesting new build on Bitrise.io. Status code: #{response.code}. #{response.body}")
28
32
  end
29
33
 
30
34
  build_infos = {}
@@ -36,11 +40,19 @@ module Fastlane
36
40
  if params[:wait_for_build]
37
41
  build_status = wait_until_build_completion(params, build_infos["build_slug"])
38
42
 
43
+ if params[:download_artifacts]
44
+ BitriseBuildArtifactsAction.get_artifacts(params, build_infos["build_slug"])
45
+ end
46
+
47
+ build_infos["status"] = build_status["status_text"]
39
48
  if build_status["status"] == 1
40
49
  UI.success("Build has finished successfully on Bitrise!")
41
- build_infos["status"] = build_status["status_text"]
42
50
  elsif build_status["status"] == 2
43
- UI.build_failure!("Build has FAILED. Check Bitrise for details.")
51
+ UI.build_failure!("Build has FAILED on Bitrise. Check more details at #{build_infos['build_url']}.")
52
+ elsif build_status["status"] == 3 || build_status["status"] == 4
53
+ UI.build_failure!("Build has been ABORTED on Bitrise. Abort reason: '#{build_status['abort_reason']}'. Check more details at #{build_infos['build_url']}.")
54
+ else
55
+ UI.build_failure!("Build has ended with unknown status on Bitrise: #{build_status}. Check more details at #{build_infos['build_url']}.")
44
56
  end
45
57
  end
46
58
 
@@ -91,23 +103,39 @@ module Fastlane
91
103
  type: String),
92
104
  FastlaneCore::ConfigItem.new(key: :workflow,
93
105
  env_name: "BITRISE_WORKFLOW",
94
- description: "The name of the workflow on Bitrise",
106
+ description: "The name of the workflow to trigger",
95
107
  optional: false,
96
108
  type: String),
109
+ FastlaneCore::ConfigItem.new(key: :branch,
110
+ env_name: "BITRISE_BUILD_BRANCH",
111
+ description: "The name of branch that will be checked out",
112
+ optional: true,
113
+ type: String),
97
114
  FastlaneCore::ConfigItem.new(key: :commit_hash,
98
115
  env_name: "BITRISE_BUILD_COMMIT_HASH",
99
- description: "The commit hash to be used on the build",
100
- optional: false,
116
+ description: "The hash of the commit that will be checked out",
117
+ optional: true,
101
118
  type: String),
102
119
  FastlaneCore::ConfigItem.new(key: :build_message,
103
120
  env_name: "BITRISE_BUILD_MESSAGE",
104
121
  description: "A custom message that will be used to identify the build",
105
- optional: false,
122
+ optional: true,
123
+ type: String),
124
+ FastlaneCore::ConfigItem.new(key: :triggered_by,
125
+ env_name: "BITRISE_BUILD_TRIGGERED_BY",
126
+ description: "A custom message that will be used to identify where the build was triggered from",
127
+ optional: true,
106
128
  type: String),
107
129
  FastlaneCore::ConfigItem.new(key: :wait_for_build,
108
130
  env_name: "BITRISE_WAIT_FOR_BUILD",
109
131
  description: "Whether the action should wait until the build finishes or return immediately after requesting the build",
110
132
  optional: true,
133
+ default_value: false,
134
+ is_string: false),
135
+ FastlaneCore::ConfigItem.new(key: :download_artifacts,
136
+ env_name: "BITRISE_DOWNLOAD_ARTIFACTS",
137
+ description: "Whether to download or not the produced artifacts",
138
+ optional: true,
111
139
  default_value: false,
112
140
  is_string: false)
113
141
  ]
@@ -5,6 +5,7 @@ module Fastlane
5
5
 
6
6
  module Helper
7
7
  class BitriseRequestHelper
8
+ MAX_RETRY_ATTEMPTS = 2
8
9
  class << self
9
10
  def get(params, path)
10
11
  request = Net::HTTP::Get.new("/v0.1/apps/#{params[:app_slug]}/#{path}", bitrise_headers(params[:access_token]))
@@ -14,7 +15,7 @@ module Fastlane
14
15
  def post(params, path, body)
15
16
  request = Net::HTTP::Post.new("/v0.1/apps/#{params[:app_slug]}/#{path}", bitrise_headers(params[:access_token]))
16
17
  request.body = body
17
- bitrise_client.request(request)
18
+ request_with_retries(request)
18
19
  end
19
20
 
20
21
  private
@@ -29,6 +30,29 @@ module Fastlane
29
30
  def bitrise_headers(access_token)
30
31
  { 'Content-Type' => 'application/json', 'Authorization' => access_token }
31
32
  end
33
+
34
+ def request_with_retries(request)
35
+ retries = 0
36
+ begin
37
+ response = bitrise_client.request(request)
38
+ if response.code.start_with?("5")
39
+ UI.error("Bitrise returned a server-side error. Status code: #{response.code}. #{response}")
40
+ raise "Bitrise API error: #{response.code}"
41
+ end
42
+ rescue StandardError => e
43
+ UI.error("There was an error making the request to Bitrise (retries: #{retries}). #{e}")
44
+ if retries < MAX_RETRY_ATTEMPTS
45
+ retries += 1
46
+ sleep(15)
47
+ UI.error("Retrying request (attempt #{retries})")
48
+ retry
49
+ else
50
+ UI.error("All retry attempts failed.")
51
+ raise e
52
+ end
53
+ end
54
+ response
55
+ end
32
56
  end
33
57
  end
34
58
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module BitriseAutomation
3
- VERSION = "0.1.0"
3
+ VERSION = "0.3.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-bitrise_automation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mario Cecchi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-09 00:00:00.000000000 Z
11
+ date: 2020-09-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pry
@@ -147,6 +147,7 @@ files:
147
147
  - lib/fastlane/plugin/bitrise_automation.rb
148
148
  - lib/fastlane/plugin/bitrise_automation/actions/bitrise_build_artifacts_action.rb
149
149
  - lib/fastlane/plugin/bitrise_automation/actions/bitrise_build_status_action.rb
150
+ - lib/fastlane/plugin/bitrise_automation/actions/interrupt_action.rb
150
151
  - lib/fastlane/plugin/bitrise_automation/actions/trigger_bitrise_workflow_action.rb
151
152
  - lib/fastlane/plugin/bitrise_automation/helper/bitrise_automation_helper.rb
152
153
  - lib/fastlane/plugin/bitrise_automation/version.rb