apadmi_grout 2.0.0 → 2.2.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: 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.