apadmi_grout 2.0.0 → 2.2.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: 8da866b98ba10eeb0dd9a8a664bd926e8c657cb918bf8a73474d1e3aacd941c4
4
- data.tar.gz: '0759b30f1bcbe228e7c1a22eecc52bad02f8174d31584d130936a9d3203d35ef'
3
+ metadata.gz: 58507ab047f8ae45fff33f92ac13ae75d57680c0d29abdaaedf39ea0e27e82c2
4
+ data.tar.gz: d598788e30b14c306d107c7522c2e1646f95f54e92cb8f4aa74806326a85b10d
5
5
  SHA512:
6
- metadata.gz: fd158cbb2bda541b4fbb80137200c60793d86d1257705aec7ffe5450f1fd66a6d8dc13f6e1135ca5c2db28a8049a92db4e1d76b678b0aa745314cdd7bdd92fed
7
- data.tar.gz: f0a7a913306577749fcba0a68ce1311e073ce4f21ac0e15d50f87527f7a65a8c27e0f3136e871d7d0b5ab457da99369bc9c99a91007f361f4cb102c435e3751f
6
+ metadata.gz: acc0fa240dde5f43293978694005ff9509dd39fdfeb89ea2db207f0944ab54d8eab598da6f133d9595e12c870b4a1ee7d6307c3060f376544231bff2493572c5
7
+ data.tar.gz: 230e4d0c686736605ac0a2548fc500c398d4e7c41b39d1aff55b93ed567cad887503cfa2684066a06a59f8f77e0f0bc05a5298d5647074235e1ef7ee06968ec7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Core Changelog
2
2
 
3
+ ## [2.2.1] - 2022-08-21
4
+ * Reduce ruby version to match what bitrise has installed
5
+
6
+ ## [2.2.0] - 2022-08-16
7
+ * Bumped min ruby version to 3.0.0 to prevent subtle bugs
8
+ * Removed references to JIRA in default release note templates
9
+ * Fixed issues with git warnings being treated like errors
10
+
11
+ ## [2.1.0] - 2022-07-26
12
+ * Added a few bitrise utils to support listing builds, triggering builds and downloading artifacts.
13
+ * Added utilities to the network service to upload files
14
+
3
15
  ## [2.0.0] - 2022-05-25
4
16
  * Almost total refactor to support having different board providers (other than jira)
5
17
  * 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
@@ -20,9 +20,9 @@ module Apadmi
20
20
  Commit Hash: {{config.commit_hash}}
21
21
  [CI/CD build \#{{config.ci_build_number}}]({{config.ci_build_url}})
22
22
 
23
- ## Jira Tickets Moved By This Build
23
+ ## Tickets Moved By This Build
24
24
  {{ rendered_moved_issues }}
25
- ## Jira Sprint Release notes
25
+ ## Sprint Release notes
26
26
  {{ rendered_release_issues }} }
27
27
  end
28
28
 
@@ -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
@@ -9,8 +9,16 @@ module Apadmi
9
9
  # Gets the root of the Git repo we're in
10
10
  # @return [String] The full path for the root of this Git repo
11
11
  def self.git_root
12
- stdout, stderr, = Open3.capture3("git rev-parse --show-toplevel")
13
- raise "Failed to get git root: #{stderr}" unless stderr.strip.empty?
12
+ stdout, stderr, status = Open3.capture3("git rev-parse --show-toplevel")
13
+ raise "Failed to get git root: #{stderr}" unless status.success?
14
+
15
+ stdout.strip
16
+ end
17
+
18
+ # Gets the commit hash of the current HEAD
19
+ def self.commit_hash
20
+ stdout, stderr, status = Open3.capture3("git rev-parse HEAD")
21
+ raise "Failed to get hash: #{stderr}" unless status.success?
14
22
 
15
23
  stdout.strip
16
24
  end
@@ -19,16 +27,16 @@ module Apadmi
19
27
  # See more details here: https://git-scm.com/docs/git-rev-list
20
28
  # @return [String] The number of commits
21
29
  def self.number_of_commits
22
- stdout, stderr, = Open3.capture3("git rev-list HEAD --count")
23
- raise "Failed to get commit number: #{stderr}" unless stderr.strip.empty?
30
+ stdout, stderr, status = Open3.capture3("git rev-list HEAD --count")
31
+ raise "Failed to get commit number: #{stderr}" unless status.success?
24
32
 
25
33
  stdout.strip
26
34
  end
27
35
 
28
36
  # Runs a git fetch all
29
37
  def self.fetch_all
30
- stdout, stderr, = Open3.capture3("git fetch --all")
31
- raise "Failed to fetch #{stderr}" unless stderr.strip.empty?
38
+ stdout, stderr, status = Open3.capture3("git fetch --all")
39
+ raise "Failed to fetch #{stderr}" unless status.success?
32
40
 
33
41
  stdout.strip
34
42
  end
@@ -37,8 +45,8 @@ module Apadmi
37
45
  # @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
38
46
  def self.merge_changelog(grep_conditions)
39
47
  command = "git log HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
40
- stdout, stderr, = Open3.capture3(command)
41
- raise "Failed to get changelog: #{stderr}" unless stderr.strip.empty?
48
+ stdout, stderr, status = Open3.capture3(command)
49
+ raise "Failed to get changelog: #{stderr}" unless status.success?
42
50
 
43
51
  stdout
44
52
  end
@@ -47,8 +55,8 @@ module Apadmi
47
55
  # @param grep_conditions [Array<String>] values to be passed in as grep cases (https://git-scm.com/docs/git-log)
48
56
  def self.invert_changelog(grep_conditions)
49
57
  command = "git log --all ^HEAD --merges --format=%s#{grep_conditions.map { |c| " --grep #{c}" }.join(" ")}"
50
- stdout, stderr, = Open3.capture3(command)
51
- raise "Failed to get changelog: #{stderr}" unless stderr.strip.empty?
58
+ stdout, stderr, status = Open3.capture3(command)
59
+ raise "Failed to get changelog: #{stderr}" unless status.success?
52
60
 
53
61
  stdout
54
62
  end
@@ -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.2.1"
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.2.1
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-08-21 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
@@ -102,14 +104,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
102
104
  requirements:
103
105
  - - ">="
104
106
  - !ruby/object:Gem::Version
105
- version: 2.7.0
107
+ version: 2.7.6
106
108
  required_rubygems_version: !ruby/object:Gem::Requirement
107
109
  requirements:
108
110
  - - ">="
109
111
  - !ruby/object:Gem::Version
110
112
  version: '0'
111
113
  requirements: []
112
- rubygems_version: 3.1.2
114
+ rubygems_version: 3.2.3
113
115
  signing_key:
114
116
  specification_version: 4
115
117
  summary: Apadmi build tool utils for use through Fastlane on Android and iOS.