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