robopigeon 0.3.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/.version +1 -1
- data/CHANGELOG.md +15 -0
- data/exe/robopigeon +2 -0
- data/lib/robopigeon/dsl.rb +2 -3
- data/lib/robopigeon/dsl/base.rb +14 -1
- data/lib/robopigeon/dsl/job.rb +2 -1
- data/lib/robopigeon/gitlab/client.rb +1 -1
- data/lib/robopigeon/gitlab/commit_dsl.rb +1 -1
- data/lib/robopigeon/gitlab/helper_dsl.rb +7 -1
- data/lib/robopigeon/jenkins/dsl.rb +2 -2
- data/lib/robopigeon/jira/helper_dsl.rb +1 -1
- data/lib/robopigeon/jira/ticket.rb +10 -7
- data/lib/robopigeon/jira/ticket_dsl.rb +2 -2
- data/lib/robopigeon/slack/attachments_dsl.rb +1 -2
- data/lib/robopigeon/slack/client.rb +5 -2
- data/lib/robopigeon/slack/dsl.rb +1 -1
- data/lib/robopigeon/slack/helper_dsl.rb +5 -4
- data/lib/robopigeon/slack/message.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e79ffa789106a62a231ad2f47d77a0a4f40d6f10f402a5d850854a8d6fc28e6b
|
4
|
+
data.tar.gz: 68cf7d61408fae7074e0866a0ed8617206d6298d89d0efd840576dd436eed43c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 71ed0f3218d805e49954f88257b29a218c5c1e28983e57e403e8c8576c375074b732eda9b548b8aa408be2fc22b25a9c3fcce9bc46491782d631c9707eb15f28
|
7
|
+
data.tar.gz: e1721290eba3a076d1801c4ef14d3806e48a932d7fd7cd0d89dc2317b0cefc5e9adcb2155199d6ae0129678f6be9bc4c286b2e1301d1bcbc170eb828cd34a8cd
|
data/.version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.1
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
## 0.3.1 (2019-04-8)
|
2
|
+
|
3
|
+
### Added
|
4
|
+
|
5
|
+
- Allow slack user methods to take an email and name
|
6
|
+
- Add helper for code change stats since deployment
|
7
|
+
|
8
|
+
### Fixed
|
9
|
+
|
10
|
+
- Show line numbers and file name in robopigeon.rb correctly
|
11
|
+
- Helpers are included even if defined after the main gem
|
12
|
+
- All dsls should extend base
|
13
|
+
- Fix jira ticket slack formatter issue
|
14
|
+
- Remove trailing slash from some lookups that Jira seems to dislike
|
15
|
+
|
1
16
|
## 0.3.0 (2019-04-8)
|
2
17
|
|
3
18
|
### Added
|
data/exe/robopigeon
CHANGED
data/lib/robopigeon/dsl.rb
CHANGED
data/lib/robopigeon/dsl/base.rb
CHANGED
@@ -3,6 +3,19 @@ module RoboPigeon::Dsl
|
|
3
3
|
# extensions. That's very helpful if you're trying to write an
|
4
4
|
# extension that interfaces with another extension or built in.
|
5
5
|
class Base < RoboPigeon::Dsl::Job
|
6
|
-
|
6
|
+
def respond_to_missing?(method, include_private)
|
7
|
+
RoboPigeon::Dsl::Helpers.instance_methods(include_private).include?(method)
|
8
|
+
end
|
9
|
+
|
10
|
+
def method_missing(method, *args)
|
11
|
+
self.class.class_exec do
|
12
|
+
include RoboPigeon::Dsl::Helpers
|
13
|
+
end
|
14
|
+
if respond_to?(method)
|
15
|
+
send(method, *args)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
7
20
|
end
|
8
21
|
end
|
data/lib/robopigeon/dsl/job.rb
CHANGED
@@ -28,6 +28,7 @@ module RoboPigeon::Dsl
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def job(*args, &block)
|
31
|
+
initial_name = args.shift
|
31
32
|
this_job = {
|
32
33
|
desc: args.pop,
|
33
34
|
action: proc do
|
@@ -35,7 +36,7 @@ module RoboPigeon::Dsl
|
|
35
36
|
job.instance_eval(&block)
|
36
37
|
end
|
37
38
|
}
|
38
|
-
jobs[
|
39
|
+
jobs[initial_name] = this_job
|
39
40
|
args.each do |arg|
|
40
41
|
jobs[arg] = this_job.merge(hidden: true)
|
41
42
|
end
|
@@ -20,7 +20,7 @@ module RoboPigeon::GitLab
|
|
20
20
|
page: page
|
21
21
|
)
|
22
22
|
deployment = deployments.select { |dep| dep.environment.name == environment }.first
|
23
|
-
return get_deployment(environment,
|
23
|
+
return get_deployment(environment, page + 1) if deployment.nil? && deployments.has_next_page?
|
24
24
|
|
25
25
|
deployment
|
26
26
|
end
|
@@ -24,7 +24,7 @@ module RoboPigeon::Dsl
|
|
24
24
|
RoboPigeon::Documentarian.add_command('deployment_shortlog', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'get a shortlog of changes between head and the specified environment')
|
25
25
|
def deployment_shortlog(environment)
|
26
26
|
dep = RoboPigeon::GitLab::Client.get_deployment(environment)
|
27
|
-
`git shortlog --no-merges #{dep.sha}
|
27
|
+
`git shortlog --no-merges #{dep.sha}..`.strip
|
28
28
|
end
|
29
29
|
|
30
30
|
RoboPigeon::Documentarian.add_command('deployment_time', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'get the time the last deployment for the given environment happened')
|
@@ -39,6 +39,12 @@ module RoboPigeon::Dsl
|
|
39
39
|
"#{ENV['CI_PROJECT_URL']}/environments/#{dep.environment.id}"
|
40
40
|
end
|
41
41
|
|
42
|
+
RoboPigeon::Documentarian.add_command('deployment_code_change_stats', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'Get code change stats since the latest deployment')
|
43
|
+
def deployment_code_change_stats(environment)
|
44
|
+
dep = RoboPigeon::GitLab::Client.get_deployment(environment)
|
45
|
+
`git diff --shortstat #{dep.sha}`.strip
|
46
|
+
end
|
47
|
+
|
42
48
|
RoboPigeon::Documentarian.add_command(
|
43
49
|
'deployment_git_log_jira_tickets',
|
44
50
|
block: ['helpers'],
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RoboPigeon::Dsl
|
2
|
-
class JenkinsRoot
|
2
|
+
class JenkinsRoot < RoboPigeon::Dsl::Base
|
3
3
|
def self.run(&block)
|
4
4
|
instance = new
|
5
5
|
instance.instance_eval(&block)
|
@@ -53,7 +53,7 @@ module RoboPigeon::Dsl
|
|
53
53
|
RoboPigeon::Jenkins::Client.token = token
|
54
54
|
end
|
55
55
|
end
|
56
|
-
class Jenkins
|
56
|
+
class Jenkins < JenkinsRoot
|
57
57
|
attr_accessor :job
|
58
58
|
def initialize
|
59
59
|
self.job = RoboPigeon::Jenkins::Job.new
|
@@ -17,7 +17,7 @@ module RoboPigeon::Dsl
|
|
17
17
|
def jira_last_created_ticket_slack_link
|
18
18
|
issue_id = RoboPigeon::Jira::Client.last_created_ticket
|
19
19
|
jira_url = RoboPigeon::Jira::Client.api_url
|
20
|
-
"<#{
|
20
|
+
"<#{jira_url}/browse/#{issue_id}|#{issue_id}>"
|
21
21
|
end
|
22
22
|
|
23
23
|
RoboPigeon::Documentarian.add_command(
|
@@ -5,19 +5,19 @@ module RoboPigeon::Jira
|
|
5
5
|
MAX_TRANSITIONS = 10
|
6
6
|
ISSUE_PATH = '/rest/api/2/issue'.freeze
|
7
7
|
attr_accessor :ticket, :project, :issue_type, :summary, :fields,
|
8
|
-
:assignee, :reporter, :description
|
8
|
+
:assignee, :duedate, :reporter, :description
|
9
9
|
|
10
10
|
def initialize(ticket = nil)
|
11
11
|
self.ticket = ticket
|
12
12
|
self.fields = {}
|
13
|
-
|
13
|
+
attempt_update_from_server
|
14
14
|
self.project = ticket.split('-')[0] if ticket
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def attempt_update_from_server
|
18
18
|
return unless ticket
|
19
19
|
|
20
|
-
get = jira_request.get("#{ISSUE_PATH}/#{ticket}
|
20
|
+
get = jira_request.get("#{ISSUE_PATH}/#{ticket}")
|
21
21
|
raise "Failed to look up issue #{ticket}" unless get.status < 400
|
22
22
|
|
23
23
|
raw = JSON.parse(get.body)
|
@@ -40,6 +40,7 @@ module RoboPigeon::Jira
|
|
40
40
|
project: { key: project },
|
41
41
|
issuetype: { name: issue_type },
|
42
42
|
summary: summary,
|
43
|
+
duedate: duedate,
|
43
44
|
description: description,
|
44
45
|
assignee: { name: reporter }
|
45
46
|
}.merge(fields)
|
@@ -97,13 +98,15 @@ module RoboPigeon::Jira
|
|
97
98
|
|
98
99
|
self.fields[field] = if fields[field]['allowedValues'].nil?
|
99
100
|
value
|
101
|
+
elsif fields[field]['schema']['type'] == 'array'
|
102
|
+
[{ name: value }]
|
100
103
|
else
|
101
104
|
{ value: value }
|
102
105
|
end
|
103
106
|
|
104
107
|
if ticket
|
105
108
|
post = jira_request.put do |req|
|
106
|
-
req.url "#{ISSUE_PATH}/#{ticket}
|
109
|
+
req.url "#{ISSUE_PATH}/#{ticket}"
|
107
110
|
req.body = { fields: self.fields }.to_json
|
108
111
|
end
|
109
112
|
end
|
@@ -124,7 +127,7 @@ module RoboPigeon::Jira
|
|
124
127
|
|
125
128
|
def perform_transition(transition)
|
126
129
|
require_ticket
|
127
|
-
get_fields = jira_request.get("#{ISSUE_PATH}/#{ticket}
|
130
|
+
get_fields = jira_request.get("#{ISSUE_PATH}/#{ticket}?expand=transitions.fields")
|
128
131
|
transition_details = JSON.parse(get_fields.body)['transitions'].find do |trans|
|
129
132
|
trans['name'].casecmp(transition).zero?
|
130
133
|
end
|
@@ -139,7 +142,7 @@ module RoboPigeon::Jira
|
|
139
142
|
def current_state
|
140
143
|
require_ticket
|
141
144
|
get = jira_request.get do |req|
|
142
|
-
req.url "#{ISSUE_PATH}/#{ticket}
|
145
|
+
req.url "#{ISSUE_PATH}/#{ticket}"
|
143
146
|
end
|
144
147
|
JSON.parse(get.body)['fields']['status']['name']
|
145
148
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module RoboPigeon::Dsl
|
2
|
-
class JiraTicket
|
2
|
+
class JiraTicket < RoboPigeon::Dsl::Base
|
3
3
|
include RoboPigeon::Dsl::Helpers
|
4
4
|
attr_accessor :ticket
|
5
5
|
|
@@ -110,7 +110,7 @@ module RoboPigeon::Dsl
|
|
110
110
|
'field',
|
111
111
|
block: %w[job jira ticket],
|
112
112
|
params: [
|
113
|
-
{ name: 'field_name', type: 'String', desc: 'the name of the field you want to set', example: '
|
113
|
+
{ name: 'field_name', type: 'String', desc: 'the name of the field you want to set', example: 'Regression Test Release Date' },
|
114
114
|
{ name: 'field_value', type: 'String', desc: 'what to set that field to', example: '2/10/2030' }
|
115
115
|
],
|
116
116
|
desc: 'set or update a field to a value'
|
@@ -28,15 +28,18 @@ module RoboPigeon::Slack
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def get_user(search)
|
31
|
+
lookup = search.shift
|
31
32
|
begin
|
32
|
-
users = client.users_search(user:
|
33
|
+
users = client.users_search(user: lookup.downcase).try(:members) unless lookup.nil?
|
33
34
|
rescue ::Faraday::Error => e
|
34
35
|
puts "Giving up on slack user lookup because the slack client raised a #{e.class}:\n#{e.message}"
|
35
36
|
users = nil
|
36
37
|
end
|
37
38
|
|
38
39
|
if users.nil? || users.empty? || users.length != 1
|
39
|
-
nil
|
40
|
+
return nil if search.empty?
|
41
|
+
|
42
|
+
get_user(search)
|
40
43
|
else
|
41
44
|
users.try(:first)
|
42
45
|
end
|
data/lib/robopigeon/slack/dsl.rb
CHANGED
@@ -46,7 +46,7 @@ module RoboPigeon::Dsl
|
|
46
46
|
end
|
47
47
|
|
48
48
|
RoboPigeon::Documentarian.add_command('user', block: %w[job slack], params: [{ name: 'search', type: 'String', desc: 'the name, email, or slack handle of a user to search for', example: 'robopigeon@ives.dev' }], desc: 'add a single user recipient to your message, can be used multiple times')
|
49
|
-
def user(user)
|
49
|
+
def user(*user)
|
50
50
|
message.users.push(RoboPigeon::Slack::Client.get_user(user).try(:id))
|
51
51
|
end
|
52
52
|
|
@@ -2,7 +2,7 @@ module RoboPigeon::Dsl
|
|
2
2
|
module Helpers
|
3
3
|
module Slack
|
4
4
|
RoboPigeon::Documentarian.add_command('slack_user_for', block: ['helpers'], params: [{ name: 'search', type: 'String', desc: 'the name, email, or slack handle of a user to search for', example: 'robopigeon@ives.dev' }], desc: 'Searches for a given user and returns a formatted slack message mention')
|
5
|
-
def slack_user_for(search)
|
5
|
+
def slack_user_for(*search)
|
6
6
|
uid = RoboPigeon::Slack::Client.get_user(search).try(:id)
|
7
7
|
return '' if uid.nil?
|
8
8
|
|
@@ -10,11 +10,12 @@ module RoboPigeon::Dsl
|
|
10
10
|
end
|
11
11
|
|
12
12
|
RoboPigeon::Documentarian.add_command('slack_name_for', block: ['helpers'], params: [{ name: 'search', type: 'String', desc: 'the name, email, or slack handle of a user to search for', example: 'robopigeon@ives.dev' }], desc: 'Searches for a given user and returns their slack handle with an @')
|
13
|
-
def slack_name_for(search)
|
14
|
-
|
13
|
+
def slack_name_for(*search)
|
14
|
+
uid = RoboPigeon::Slack::Client.get_user(search).try(:name)
|
15
|
+
|
15
16
|
return '' if uid.nil?
|
16
17
|
|
17
|
-
"@#{
|
18
|
+
"@#{uid}"
|
18
19
|
end
|
19
20
|
|
20
21
|
RoboPigeon::Documentarian.add_command('slack_user_group', block: ['helpers'], params: [{ name: 'id', type: 'String', desc: 'the usergroup id to mention', example: 'robopigeon@ives.dev' }], desc: 'a message formatted mention of the given slack group id')
|
@@ -24,10 +24,10 @@ module RoboPigeon::Slack
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def send!
|
27
|
-
users.each do |user|
|
27
|
+
users.reject(&:nil?).each do |user|
|
28
28
|
send_message(user)
|
29
29
|
end
|
30
|
-
channels.each do |channel|
|
30
|
+
channels.reject(&:nil?).each do |channel|
|
31
31
|
send_message(channel)
|
32
32
|
end
|
33
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: robopigeon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Ives
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-04-
|
11
|
+
date: 2019-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: gitlab
|