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 +4 -4
- data/README.md +67 -2
- data/lib/fastlane/plugin/bitrise_automation/actions/bitrise_build_artifacts_action.rb +13 -9
- data/lib/fastlane/plugin/bitrise_automation/actions/bitrise_build_status_action.rb +5 -1
- data/lib/fastlane/plugin/bitrise_automation/actions/interrupt_action.rb +38 -0
- data/lib/fastlane/plugin/bitrise_automation/actions/trigger_bitrise_workflow_action.rb +42 -14
- data/lib/fastlane/plugin/bitrise_automation/helper/bitrise_automation_helper.rb +25 -1
- data/lib/fastlane/plugin/bitrise_automation/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 995f0a752fe79b180ba1fbd4d9f74b8dba9b61946dfc4ae8f0234d5eb9dd1e87
|
4
|
+
data.tar.gz: 7637f6ad20acb0880c3f0c9e3455c86fa058a24788266b56a3c8b7c5b6cac9bc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
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
|
-
|
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 #{
|
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[:
|
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/#{
|
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: :
|
98
|
-
env_name: "
|
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.
|
8
|
+
UI.message("Requesting new Bitrise.io build for workflow '#{params[:workflow]}'...")
|
9
9
|
|
10
|
-
|
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
|
-
}
|
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
|
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
|
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
|
100
|
-
optional:
|
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:
|
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
|
-
|
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
|
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
|
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-
|
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
|