fastlane-plugin-bitrise_automation 0.1.0 → 0.3.1

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
  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