robopigeon 0.3.0 → 0.3.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: 25d50f00dc30aa78bd9389cee8da7d93aa04920e4db5c10433f39c2df4d97b0f
4
- data.tar.gz: c0f86cfe9dc63bb753d4ee5e88cfe16512fce547fcdb649ffe4776282c3162dd
3
+ metadata.gz: e79ffa789106a62a231ad2f47d77a0a4f40d6f10f402a5d850854a8d6fc28e6b
4
+ data.tar.gz: 68cf7d61408fae7074e0866a0ed8617206d6298d89d0efd840576dd436eed43c
5
5
  SHA512:
6
- metadata.gz: 9f980108a24e6e081f073e9747efca1fcb4cb14f776aa911cb4a60c769529401abf140b0f09de6c68208f1d78dde56a6ea8f8ae899b8ab3d943676be34bf8a80
7
- data.tar.gz: 94b3b6a2f9631eb610ddfb2bf13fc8f885d3962d65a5dbdcfeb7c56ad44bbdf25d298db7fdf7b08ad9b3cd463cabc65a9c88c3310fd7a0b3a21960be94af7e0e
6
+ metadata.gz: 71ed0f3218d805e49954f88257b29a218c5c1e28983e57e403e8c8576c375074b732eda9b548b8aa408be2fc22b25a9c3fcce9bc46491782d631c9707eb15f28
7
+ data.tar.gz: e1721290eba3a076d1801c4ef14d3806e48a932d7fd7cd0d89dc2317b0cefc5e9adcb2155199d6ae0129678f6be9bc4c286b2e1301d1bcbc170eb828cd34a8cd
data/.version CHANGED
@@ -1 +1 @@
1
- 0.3.0
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
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'robopigeon'
4
4
 
5
+ Bundler.require if defined?(Bundler)
6
+
5
7
  def usage(bot)
6
8
  bot.usage
7
9
  exit 1
@@ -15,9 +15,8 @@ module RoboPigeon::Dsl
15
15
  init_help
16
16
  init_new
17
17
  if File.exist?(file)
18
- instance_exec do
19
- eval(File.read(file))
20
- end
18
+ contents = File.read(file)
19
+ instance_eval(contents, file)
21
20
  else
22
21
  init_job
23
22
  end
@@ -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
- include RoboPigeon::Dsl::Helpers
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
@@ -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[args.shift] = this_job
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, project, page + 1) if deployment.nil? && deployments.has_next_page?
23
+ return get_deployment(environment, page + 1) if deployment.nil? && deployments.has_next_page?
24
24
 
25
25
  deployment
26
26
  end
@@ -1,6 +1,6 @@
1
1
  require 'gitlab'
2
2
  module RoboPigeon::Dsl
3
- class GitLabCommit
3
+ class GitLabCommit < RoboPigeon::Dsl::Base
4
4
  attr_accessor :commit
5
5
  def initialize
6
6
  self.commit = RoboPigeon::GitLab::Commit.new
@@ -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
- "<#{issue_id}|#{jira_url}/browse/#{issue_id}>"
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
- update_from_server
13
+ attempt_update_from_server
14
14
  self.project = ticket.split('-')[0] if ticket
15
15
  end
16
16
 
17
- def update_from_server
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}/transitions?expand=transitions.fields")
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: 'duedate' },
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'
@@ -1,6 +1,5 @@
1
1
  module RoboPigeon::Dsl
2
- class SlackAttachment
3
- include RoboPigeon::Dsl::Helpers
2
+ class SlackAttachment < RoboPigeon::Dsl::Base
4
3
  attr_accessor :attachment
5
4
 
6
5
  def initialize
@@ -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: search.downcase).try(:members)
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
@@ -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
- name = RoboPigeon::Slack::Client.get_user(search).try(:name)
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
- "@#{name}"
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.0
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-08 00:00:00.000000000 Z
11
+ date: 2019-04-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gitlab