apadmi_grout 2.0.0 → 2.1.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
  SHA256:
3
- metadata.gz: 8da866b98ba10eeb0dd9a8a664bd926e8c657cb918bf8a73474d1e3aacd941c4
4
- data.tar.gz: '0759b30f1bcbe228e7c1a22eecc52bad02f8174d31584d130936a9d3203d35ef'
3
+ metadata.gz: f1a387b90108f0657af3875457b1eb98440b54d7fdf6d62a9750fe1af10aeca5
4
+ data.tar.gz: 25fe6b6ca1083a991f088d2161f49997f04944dda1225617192c9fcf2494f511
5
5
  SHA512:
6
- metadata.gz: fd158cbb2bda541b4fbb80137200c60793d86d1257705aec7ffe5450f1fd66a6d8dc13f6e1135ca5c2db28a8049a92db4e1d76b678b0aa745314cdd7bdd92fed
7
- data.tar.gz: f0a7a913306577749fcba0a68ce1311e073ce4f21ac0e15d50f87527f7a65a8c27e0f3136e871d7d0b5ab457da99369bc9c99a91007f361f4cb102c435e3751f
6
+ metadata.gz: ca2dee35cca80456ca3ebd01b8ab1e1c89eb6c9bad069b36a1e20f8ae36bb511144fed3de12d8dccc31cc8c9dd364684bbdcee4af69244ff180d6e8af4ac24d2
7
+ data.tar.gz: 49414ee4d8507110fed1bbf50946c16357039aacbc1e6657f32c1c4b4777d0ea013559da5c99fc65c77ea5a55d5d4e61479ed7b433dac81885d532dcab4eeaaa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Core Changelog
2
2
 
3
+ ## [2.1.0] - 22-07-26
4
+ * Added a few bitrise utils to support listing builds, triggering builds and downloading artifacts.
5
+ * Added utilities to the network service to upload files
6
+
3
7
  ## [2.0.0] - 2022-05-25
4
8
  * Almost total refactor to support having different board providers (other than jira)
5
9
  * Implement ADO support for all existing actions
@@ -25,7 +25,7 @@ module Apadmi
25
25
  project,
26
26
  logger = Apadmi::Grout::DefaultLogger.new
27
27
  )
28
- network_service = Apadmi::Grout::NetworkService.new(username, token, base_url)
28
+ network_service = Apadmi::Grout::NetworkService.init_for_basic_auth(username, token, base_url)
29
29
  jira_board_service = Apadmi::Grout::JiraBoardService.new(username, token, base_url, context_path, project, network_service)
30
30
  git_utils = Apadmi::Grout::GitUtils
31
31
  issues_from_changelog_action = Apadmi::Grout::IssuesFromChangelogAction.new(jira_board_service, "#{project}-", logger)
@@ -51,7 +51,7 @@ module Apadmi
51
51
  )
52
52
  )
53
53
  ticket_prefix = "#"
54
- network_service = Apadmi::Grout::NetworkService.new("", personal_access_token, base_url)
54
+ network_service = Apadmi::Grout::NetworkService.init_for_basic_auth("", personal_access_token, base_url)
55
55
  ado_board_service = Apadmi::Grout::AdoBoardService.new(network_service, ado_config, logger)
56
56
  git_utils = Apadmi::Grout::GitUtils
57
57
  issues_from_changelog_action = Apadmi::Grout::IssuesFromChangelogAction.new(ado_board_service, ticket_prefix, logger)
@@ -65,6 +65,11 @@ module Apadmi
65
65
  generate_release_notes_action: Apadmi::Grout::GenerateReleaseNotesAction.new(Apadmi::Grout::AdoIssueClassifier.new)
66
66
  )
67
67
  end
68
+
69
+ def self.bitrise_service(api_token, base_url, app_slug)
70
+ network_service = Apadmi::Grout::NetworkService.new(api_token, base_url)
71
+ Apadmi::Grout::BitriseService.new(app_slug, network_service)
72
+ end
68
73
  end
69
74
  end
70
75
  end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apadmi
4
+ module Grout
5
+ STATUS_RUNNING = 0
6
+ STATUS_SUCCESS = 1
7
+ STATUS_FAILED = 2
8
+ STATUS_ABORTED_FAIL = 3
9
+ STATUS_ABORTED_SUCCESS = 4
10
+
11
+ BitriseBuild = Struct.new(:triggered_at, :slug, :status, :commit_hash) do
12
+ def finished_with_success
13
+ STATUS_SUCCESS == status
14
+ end
15
+ end
16
+
17
+ Artifact = Struct.new(:title, :download_url)
18
+
19
+ TriggeredBitriseBuild = Struct.new(:build_number, :build_slug, :build_url, :message, :service, :slug, :status, :triggered_workflow) do
20
+ def finished_with_success
21
+ STATUS_SUCCESS == status
22
+ end
23
+
24
+ def self.from_json(json)
25
+ TriggeredBitriseBuild.new(
26
+ json["build_number"],
27
+ json["build_slug"],
28
+ json["build_url"],
29
+ json["message"],
30
+ json["service"],
31
+ json["slug"],
32
+ json["status"],
33
+ json["triggered_workflow"]
34
+ )
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "open-uri"
4
+ require "fileutils"
5
+
6
+ module Apadmi
7
+ module Grout
8
+ # Utility class for abstracting a some of the bitrise APIs
9
+ class BitriseService
10
+ # @param [String] app_slug
11
+ # @param [Apadmi::Grout::NetworkService] network_service
12
+ def initialize(app_slug, network_service)
13
+ @app_slug = app_slug
14
+ @network_service = network_service
15
+ end
16
+
17
+ # @param [Integer] pull_request_id
18
+ # @param [String] workflow
19
+ # @return [Array<BitriseBuild>]
20
+ def list_builds(pull_request_id, workflow)
21
+ res = @network_service.do_get("/#{@app_slug}/builds?pull_request_id=#{pull_request_id}&workflow=#{workflow}")
22
+ parsed = JSON.parse(res.body)
23
+ items = parsed["data"]
24
+
25
+ return [] if items.nil? || items.empty?
26
+
27
+ items.map do |item|
28
+ BitriseBuild.new(
29
+ item["triggered_at"],
30
+ item["slug"],
31
+ item["status"],
32
+ item["commit_hash"]
33
+ )
34
+ end
35
+ end
36
+
37
+ # @param [String] build_slug
38
+ # @param [String] artifact_slug
39
+ # @return [Artifact]
40
+ def retrieve_artifact_metadata(build_slug, artifact_slug)
41
+ res = @network_service.do_get("/#{@app_slug}/builds/#{build_slug}/artifacts/#{artifact_slug}")
42
+ parsed = JSON.parse(res.body)
43
+
44
+ Artifact.new(parsed["data"]["title"], parsed["data"]["expiring_download_url"])
45
+ end
46
+
47
+ # @param [String] build_slug
48
+ # @param [String] output_dir
49
+ # Download all artifacts from a given build to a specified directory
50
+ def download_artifacts(build_slug, output_dir)
51
+ res = @network_service.do_get("/#{@app_slug}/builds/#{build_slug}/artifacts")
52
+ parsed = JSON.parse(res.body)
53
+ items = parsed["data"]
54
+
55
+ artifacts = items.map do |item|
56
+ retrieve_artifact_metadata(build_slug, item["slug"])
57
+ end
58
+
59
+ FileUtils.mkdir_p output_dir
60
+
61
+ artifacts.each do |item|
62
+ File.open("#{output_dir}/#{item.title}", "wb") do |file|
63
+ # rubocop:disable Security/Open
64
+ file.write URI.open(item.download_url).read
65
+ # rubocop:enable Security/Open
66
+ end
67
+ end
68
+ artifacts
69
+ end
70
+
71
+ # @param [String] workflow
72
+ # @param [String] branch
73
+ # @param [String] dest the destination branch of the pr
74
+ # @param [String] pull_request_id
75
+ # @param [String] pull_request_repo_url
76
+ # @param [String] commit_hash
77
+ def trigger_build(workflow, branch, dest, pull_request_id, pull_request_repo_url, commit_hash)
78
+ params = {
79
+ workflow_id: workflow,
80
+ branch: branch,
81
+ commit_hash: commit_hash
82
+ }
83
+
84
+ params[:branch_dest] = dest unless dest.strip.blank?
85
+ params[:pull_request_id] = pull_request_id unless pull_request_id.strip.blank?
86
+ params[:pull_request_repository_url] = pull_request_repo_url unless pull_request_repo_url.strip.blank?
87
+
88
+ payload = {
89
+ hook_info: {
90
+ type: "bitrise"
91
+ },
92
+ build_params: params,
93
+ triggered_by: "curl"
94
+ }
95
+
96
+ res = @network_service.do_post("/#{@app_slug}/builds", payload.to_json)
97
+ parsed = JSON.parse(res.body)
98
+
99
+ TriggeredBitriseBuild.from_json(parsed)
100
+ end
101
+ end
102
+ end
103
+ end
@@ -15,6 +15,14 @@ module Apadmi
15
15
  stdout.strip
16
16
  end
17
17
 
18
+ # Gets the commit hash of the current HEAD
19
+ def self.commit_hash
20
+ stdout, stderr, = Open3.capture3("git rev-parse HEAD")
21
+ raise "Failed to get hash: #{stderr}" unless stderr.strip.empty?
22
+
23
+ stdout.strip
24
+ end
25
+
18
26
  # Gets the number of commits accessible from HEAD treating the history as a graph.
19
27
  # See more details here: https://git-scm.com/docs/git-rev-list
20
28
  # @return [String] The number of commits
@@ -6,8 +6,11 @@ module Apadmi
6
6
  module Grout
7
7
  # Utility class for running REST network calls
8
8
  class NetworkService
9
+ attr_reader :base_url
10
+
9
11
  APPLICATION_JSON = "application/json"
10
12
  PATCH_CONTENT_TYPE = "application/json-patch+json"
13
+ FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"
11
14
  CONTENT_TYPE = "Content-Type"
12
15
  private_constant :CONTENT_TYPE, :APPLICATION_JSON
13
16
 
@@ -15,10 +18,18 @@ module Apadmi
15
18
  # @param password [String]
16
19
  # @param base_url [String]
17
20
  # Params are encoded for use in Basic Auth https://datatracker.ietf.org/doc/html/rfc7617
18
- def initialize(username, password, base_url)
19
- @username = username
20
- @password = password
21
+ def self.init_for_basic_auth(username, password, base_url, timeout = 30)
22
+ auth_str = "#{username}:#{password}"
23
+ auth_header = "Basic #{Base64.strict_encode64(auth_str)}"
24
+ NetworkService.new(auth_header, base_url, timeout)
25
+ end
26
+
27
+ # @param auth_header [String]
28
+ # @param base_url [String]
29
+ def initialize(auth_header, base_url, timeout = 30)
21
30
  @base_url = base_url
31
+ @auth_header = auth_header
32
+ @timeout = timeout
22
33
  end
23
34
 
24
35
  # @param [String] path
@@ -50,6 +61,30 @@ module Apadmi
50
61
  response
51
62
  end
52
63
 
64
+ def do_form_encoded_post(path, payload)
65
+ conn = setup_con
66
+ response = conn.post("#{@base_url}#{path}") do |req|
67
+ req.headers[CONTENT_TYPE] = FORM_CONTENT_TYPE
68
+ req.body = URI.encode_www_form(payload)
69
+ end
70
+ throw_if_error(response)
71
+ response
72
+ end
73
+
74
+ def do_file_post(path, file_path, type)
75
+ conn = Faraday.new do |f|
76
+ f.request :multipart
77
+ f.adapter :net_http
78
+ end
79
+ conn.options.timeout = @timeout
80
+ conn.headers["Authorization"] = @auth_header
81
+
82
+ payload = { file: Faraday::UploadIO.new(file_path, type) }
83
+ response = conn.post("#{@base_url}#{path}", payload)
84
+ throw_if_error(response)
85
+ response
86
+ end
87
+
53
88
  # @param [String] path
54
89
  # @param [String] payload
55
90
  # @return [Faraday::Response]
@@ -73,9 +108,9 @@ module Apadmi
73
108
 
74
109
  # @return [Faraday::Connection]
75
110
  def setup_con
76
- auth_str = "#{@username}:#{@password}"
77
111
  conn = Faraday.new # create a new Connection with base URL
78
- conn.headers["Authorization"] = "Basic #{Base64.strict_encode64(auth_str)}"
112
+ conn.headers["Authorization"] = @auth_header
113
+ conn.options.timeout = @timeout
79
114
  conn
80
115
  end
81
116
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Apadmi
4
4
  module Grout
5
- VERSION = "2.0.0"
5
+ VERSION = "2.1.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: apadmi_grout
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Apadmi
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-05-25 00:00:00.000000000 Z
11
+ date: 2022-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -72,12 +72,14 @@ files:
72
72
  - lib/apadmi/grout/actions/move_tickets_action.rb
73
73
  - lib/apadmi/grout/di.rb
74
74
  - lib/apadmi/grout/models/ado_config.rb
75
+ - lib/apadmi/grout/models/bitrise.rb
75
76
  - lib/apadmi/grout/models/find_tickets_options.rb
76
77
  - lib/apadmi/grout/models/flag_messages.rb
77
78
  - lib/apadmi/grout/models/issue.rb
78
79
  - lib/apadmi/grout/models/pull_request.rb
79
80
  - lib/apadmi/grout/models/release_notes_config.rb
80
81
  - lib/apadmi/grout/models/release_notes_templates.rb
82
+ - lib/apadmi/grout/service/bitrise_service/bitrise_service.rb
81
83
  - lib/apadmi/grout/service/board_service/ado_board_service.rb
82
84
  - lib/apadmi/grout/service/board_service/board_service.rb
83
85
  - lib/apadmi/grout/service/board_service/jira_board_service.rb