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 +4 -4
- data/CHANGELOG.md +12 -0
- data/lib/apadmi/grout/di.rb +7 -2
- data/lib/apadmi/grout/models/bitrise.rb +38 -0
- data/lib/apadmi/grout/models/release_notes_templates.rb +2 -2
- data/lib/apadmi/grout/service/bitrise_service/bitrise_service.rb +103 -0
- data/lib/apadmi/grout/utils/git_utils.rb +18 -10
- data/lib/apadmi/grout/utils/network_service.rb +40 -5
- data/lib/apadmi/grout/version.rb +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 58507ab047f8ae45fff33f92ac13ae75d57680c0d29abdaaedf39ea0e27e82c2
|
4
|
+
data.tar.gz: d598788e30b14c306d107c7522c2e1646f95f54e92cb8f4aa74806326a85b10d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/apadmi/grout/di.rb
CHANGED
@@ -25,7 +25,7 @@ module Apadmi
|
|
25
25
|
project,
|
26
26
|
logger = Apadmi::Grout::DefaultLogger.new
|
27
27
|
)
|
28
|
-
network_service = Apadmi::Grout::NetworkService.
|
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.
|
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
|
-
##
|
23
|
+
## Tickets Moved By This Build
|
24
24
|
{{ rendered_moved_issues }}
|
25
|
-
##
|
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
|
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
|
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
|
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
|
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
|
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
|
19
|
-
|
20
|
-
|
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"] =
|
112
|
+
conn.headers["Authorization"] = @auth_header
|
113
|
+
conn.options.timeout = @timeout
|
79
114
|
conn
|
80
115
|
end
|
81
116
|
|
data/lib/apadmi/grout/version.rb
CHANGED
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.
|
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-
|
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.
|
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.
|
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.
|