robopigeon 0.1.0
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 +7 -0
- data/.gitignore +16 -0
- data/.gitlab-ci.yml +27 -0
- data/.rspec +3 -0
- data/.rubocop.yml +65 -0
- data/.ruby-version +1 -0
- data/.version +1 -0
- data/Gemfile +4 -0
- data/README.md +256 -0
- data/Rakefile +11 -0
- data/bin/console +14 -0
- data/bin/rake +29 -0
- data/bin/rspec +29 -0
- data/bin/rubocop +29 -0
- data/bin/setup +8 -0
- data/exe/robopigeon +22 -0
- data/lib/robopigeon/documentarian.rb +39 -0
- data/lib/robopigeon/dsl/helpers.rb +17 -0
- data/lib/robopigeon/dsl/initial_jobs.rb +36 -0
- data/lib/robopigeon/dsl/job.rb +34 -0
- data/lib/robopigeon/dsl.rb +46 -0
- data/lib/robopigeon/git/helper_dsl.rb +60 -0
- data/lib/robopigeon/git.rb +7 -0
- data/lib/robopigeon/gitlab/client.rb +42 -0
- data/lib/robopigeon/gitlab/dsl.rb +174 -0
- data/lib/robopigeon/gitlab/helper_dsl.rb +44 -0
- data/lib/robopigeon/gitlab/jira.rb +0 -0
- data/lib/robopigeon/gitlab/merge_request.rb +78 -0
- data/lib/robopigeon/gitlab.rb +29 -0
- data/lib/robopigeon/jira/client.rb +17 -0
- data/lib/robopigeon/jira/dsl.rb +81 -0
- data/lib/robopigeon/jira/helper_dsl.rb +24 -0
- data/lib/robopigeon/jira/ticket.rb +186 -0
- data/lib/robopigeon/jira/ticket_dsl.rb +155 -0
- data/lib/robopigeon/jira.rb +37 -0
- data/lib/robopigeon/markdown/helper_dsl.rb +73 -0
- data/lib/robopigeon/markdown.rb +11 -0
- data/lib/robopigeon/resources/initial_robopigeon.rb +156 -0
- data/lib/robopigeon/slack/attachments_dsl.rb +63 -0
- data/lib/robopigeon/slack/client.rb +46 -0
- data/lib/robopigeon/slack/dsl.rb +74 -0
- data/lib/robopigeon/slack/helper_dsl.rb +26 -0
- data/lib/robopigeon/slack/message.rb +35 -0
- data/lib/robopigeon/slack.rb +30 -0
- data/lib/robopigeon/version.rb +3 -0
- data/lib/robopigeon.rb +13 -0
- data/robopigeon +0 -0
- data/robopigeon.gemspec +47 -0
- data/robopigeon.rb +156 -0
- metadata +264 -0
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'robopigeon/dsl/helpers'
|
2
|
+
require 'robopigeon/dsl/initial_jobs'
|
3
|
+
require 'robopigeon/dsl/job'
|
4
|
+
|
5
|
+
module RoboPigeon::Dsl
|
6
|
+
class Root
|
7
|
+
include RoboPigeon::Dsl::InitialJobs
|
8
|
+
attr_accessor :jobs, :file
|
9
|
+
|
10
|
+
def initialize(file = RoboPigeon::DEFAULT_FILE)
|
11
|
+
self.file = file
|
12
|
+
self.jobs = {}
|
13
|
+
base
|
14
|
+
init_help
|
15
|
+
if File.exist?(file)
|
16
|
+
instance_exec do
|
17
|
+
eval(File.read(file))
|
18
|
+
end
|
19
|
+
else
|
20
|
+
init_job
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def run(name)
|
25
|
+
jobs[name][:action].call
|
26
|
+
end
|
27
|
+
|
28
|
+
def job?(name)
|
29
|
+
!jobs[name].nil?
|
30
|
+
end
|
31
|
+
|
32
|
+
def usage
|
33
|
+
max_size = jobs.keys.max_by(&:length).size
|
34
|
+
jobs_strings = jobs.keys.reject do |key|
|
35
|
+
jobs[key][:hidden]
|
36
|
+
end.map do |name|
|
37
|
+
padding = ' ' * (max_size - name.length)
|
38
|
+
" '#{name}' #{padding}- #{jobs[name][:desc]}"
|
39
|
+
end.join("\n")
|
40
|
+
puts "Usage: robopigeon 'job name'"
|
41
|
+
puts "Jobs are configured in #{file}"
|
42
|
+
puts 'See https://gitlab.com/robopigeon/robopigeon for configuration'
|
43
|
+
puts "Configured Jobs:\n#{jobs_strings}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module RoboPigeon::Dsl
|
2
|
+
module Helpers
|
3
|
+
module Git
|
4
|
+
RoboPigeon::Documentarian.add_command('git_committer_name', block: ['helpers'], desc: 'name of the last person to make a non-merge commit')
|
5
|
+
def git_committer_name
|
6
|
+
`git log -1 --pretty=format:'%an' --no-merges`
|
7
|
+
end
|
8
|
+
|
9
|
+
RoboPigeon::Documentarian.add_command('git_committer_email', block: ['helpers'], desc: 'email of the last person to make a non-merge commit')
|
10
|
+
def git_committer_email
|
11
|
+
`git log -1 --pretty=format:'%ae' --no-merges`
|
12
|
+
end
|
13
|
+
|
14
|
+
RoboPigeon::Documentarian.add_command('git_merger_name', block: ['helpers'], desc: 'name of the last person to make a merge commit')
|
15
|
+
def git_merger_name
|
16
|
+
`git log -1 --pretty=format:'%an' --merges`
|
17
|
+
end
|
18
|
+
|
19
|
+
RoboPigeon::Documentarian.add_command('git_merger_email', block: ['helpers'], desc: 'email of the last person to make a merge commit')
|
20
|
+
def git_merger_email
|
21
|
+
`git log -1 --pretty=format:'%ae' --merges`
|
22
|
+
end
|
23
|
+
|
24
|
+
RoboPigeon::Documentarian.add_command('git_branch_merged_source', block: ['helpers'], desc: 'source branch in the last merge commit')
|
25
|
+
def git_branch_merged_source
|
26
|
+
get_merge_data[:source]
|
27
|
+
end
|
28
|
+
|
29
|
+
RoboPigeon::Documentarian.add_command('git_branch_merged_target', block: ['helpers'], desc: 'target branch in the last merge commit')
|
30
|
+
def git_branch_merged_target
|
31
|
+
get_merge_data[:target]
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def merge_commit_subject
|
37
|
+
`git log -1 --merges --pretty=format:'%s'`
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_merge_data
|
41
|
+
commit_subject = merge_commit_subject || ''
|
42
|
+
if data = commit_subject.match(/Merge branch '(.*)' into '(.*)'/)
|
43
|
+
return {
|
44
|
+
source: data[1],
|
45
|
+
target: data[2]
|
46
|
+
}
|
47
|
+
elsif data = commit_subject.match(/Merge branch '(.*)' of (.*)/)
|
48
|
+
return {
|
49
|
+
source: "#{data[2]}/#{data[1]}",
|
50
|
+
target: data[1]
|
51
|
+
}
|
52
|
+
end
|
53
|
+
{
|
54
|
+
source: 'unknown',
|
55
|
+
target: 'unknown'
|
56
|
+
}
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RoboPigeon::GitLab
|
2
|
+
class Client
|
3
|
+
@project = ENV['CI_PROJECT_PATH']
|
4
|
+
@pipeline_id = ENV['CI_PIPELINE_ID']
|
5
|
+
@branch = ENV['CI_COMMIT_REF_NAME']
|
6
|
+
@enabled = true
|
7
|
+
|
8
|
+
class << self
|
9
|
+
attr_accessor :project, :branch, :pipeline_id, :enabled
|
10
|
+
def client
|
11
|
+
Gitlab.client
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_deployment(environment, page = 0)
|
15
|
+
deployments = client.deployments(
|
16
|
+
project,
|
17
|
+
order_by: 'created_at',
|
18
|
+
sort: 'desc',
|
19
|
+
per_page: 20,
|
20
|
+
page: page
|
21
|
+
)
|
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?
|
24
|
+
|
25
|
+
deployment
|
26
|
+
end
|
27
|
+
|
28
|
+
def create_tag(ref, tag, message)
|
29
|
+
client.create_tag(project, tag, ref, message)
|
30
|
+
end
|
31
|
+
|
32
|
+
def merge_request_comment(text, source = branch)
|
33
|
+
merge_requests = client.merge_requests(project, source_branch: source)
|
34
|
+
raise "No merge requests exist for branch '#{source}'" if merge_requests.empty?
|
35
|
+
|
36
|
+
merge_requests.each do |merge_request|
|
37
|
+
client.create_merge_request_discussion(project, merge_request.iid, body: text)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,174 @@
|
|
1
|
+
require 'gitlab'
|
2
|
+
module RoboPigeon::Dsl
|
3
|
+
class GitLabRoot
|
4
|
+
def self.run(&block)
|
5
|
+
gitlab = RoboPigeon::Dsl::GitLabRoot.new
|
6
|
+
gitlab.instance_eval(&block)
|
7
|
+
end
|
8
|
+
|
9
|
+
RoboPigeon::Documentarian.add_command(
|
10
|
+
'enabled',
|
11
|
+
block: ['gitlab'],
|
12
|
+
params: [
|
13
|
+
{ name: 'enabled', type: 'boolean', desc: 'should it run gitlab commands', example: 'false', default: 'true' }
|
14
|
+
],
|
15
|
+
desc: 'Set whether or not to run gitlab commands, defaults to true'
|
16
|
+
)
|
17
|
+
def enabled(bool)
|
18
|
+
RoboPigeon::GitLab::Client.enabled = bool
|
19
|
+
end
|
20
|
+
|
21
|
+
RoboPigeon::Documentarian.add_command(
|
22
|
+
'api_key',
|
23
|
+
block: ['gitlab'],
|
24
|
+
params: [
|
25
|
+
{ name: 'api_key', type: 'String', desc: 'your gitlab api key', example: 'aeoiabDasdf-B', default: "ENV['GITLAB_API_KEY']" }
|
26
|
+
],
|
27
|
+
desc: 'Set the gitlab api key for your gitlab account'
|
28
|
+
)
|
29
|
+
def api_key(key)
|
30
|
+
Gitlab.private_token = key
|
31
|
+
end
|
32
|
+
|
33
|
+
RoboPigeon::Documentarian.add_command(
|
34
|
+
'api_url',
|
35
|
+
block: ['gitlab'],
|
36
|
+
params: [
|
37
|
+
{ name: 'url', type: 'String', desc: 'the url to your gitlab instance', example: 'https://gitlab.com/api/v4/', default: "ENV['CI_API_V4_URL']" }
|
38
|
+
],
|
39
|
+
desc: 'Set the gitlab api url for your account'
|
40
|
+
)
|
41
|
+
def api_url(url)
|
42
|
+
Gitlab.endpoint = url
|
43
|
+
end
|
44
|
+
|
45
|
+
RoboPigeon::Documentarian.add_command(
|
46
|
+
'project',
|
47
|
+
block: ['gitlab'],
|
48
|
+
params: [
|
49
|
+
{ name: 'project_path', type: 'String', desc: 'path to your project', example: 'robopigeon/robopigeon', default: "ENV['CI_PROJECT_PATH']" }
|
50
|
+
],
|
51
|
+
desc: 'Override the project path reference'
|
52
|
+
)
|
53
|
+
def project(project_path)
|
54
|
+
RoboPigeon::GitLab::Client.project = project_path
|
55
|
+
end
|
56
|
+
|
57
|
+
RoboPigeon::Documentarian.add_command(
|
58
|
+
'pipeline_id',
|
59
|
+
block: ['gitlab'],
|
60
|
+
params: [
|
61
|
+
{ name: 'pipeline_id', type: 'String', desc: 'id of the current pipeline', example: '1359234', default: "ENV['CI_PIPELINE_ID']" }
|
62
|
+
],
|
63
|
+
desc: 'Override the pipeline id reference'
|
64
|
+
)
|
65
|
+
def pipeline_id(pipeline_id)
|
66
|
+
RoboPigeon::GitLab::Client.pipeline_id = pipeline_id
|
67
|
+
end
|
68
|
+
|
69
|
+
RoboPigeon::Documentarian.add_command(
|
70
|
+
'branch',
|
71
|
+
block: ['gitlab'],
|
72
|
+
params: [
|
73
|
+
{ name: 'branch', type: 'String', desc: 'branch you want to refer to', example: 'master', default: "ENV['CI_COMMIT_REF_NAME']" }
|
74
|
+
],
|
75
|
+
desc: 'Override the branch reference'
|
76
|
+
)
|
77
|
+
def branch(branch)
|
78
|
+
RoboPigeon::GitLab::Client.branch = branch
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
class GitLab < GitLabRoot
|
83
|
+
attr_accessor :merge_request
|
84
|
+
include RoboPigeon::Dsl::Helpers
|
85
|
+
|
86
|
+
def self.run(&block)
|
87
|
+
if RoboPigeon::GitLab::Client.enabled
|
88
|
+
gitlab = RoboPigeon::Dsl::GitLab.new
|
89
|
+
gitlab.instance_eval(&block)
|
90
|
+
else
|
91
|
+
puts 'Gitlab is disabled, please remove `enabled false` from your global gitlab config'
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
RoboPigeon::Documentarian.add_command(
|
96
|
+
'merge_request_comment',
|
97
|
+
block: %w[job gitlab],
|
98
|
+
params: [
|
99
|
+
{ name: 'text', type: 'String', desc: 'text you want to post as a comment', example: 'this branch failed during a deployment' },
|
100
|
+
{ name: 'source_branch', type: 'String', desc: 'branch you want to refer to', example: 'master', default: "current global branch, defaults ENV['CI_COMMIT_REF_NAME']" }
|
101
|
+
],
|
102
|
+
desc: 'post a comment to all merge requests with the branch source'
|
103
|
+
)
|
104
|
+
def merge_request_comment(text, source_branch = RoboPigeon::GitLab::Client.branch)
|
105
|
+
RoboPigeon::GitLab::Client.merge_request_comment(text, source_branch)
|
106
|
+
end
|
107
|
+
|
108
|
+
RoboPigeon::Documentarian.add_command(
|
109
|
+
'create_merge_request',
|
110
|
+
block: %w[job gitlab],
|
111
|
+
params: [
|
112
|
+
{ name: 'source_branch', type: 'String', desc: 'source branch you want to merge from', example: "ENV['CI_COMMIT_REF_NAME']" },
|
113
|
+
{ name: 'target_branch', type: 'String', desc: 'target branch to merge to', example: 'master' },
|
114
|
+
{ name: 'title', type: 'String', desc: 'Optional string to use as the merge request title.', example: 'Merge my_face into master on tuesdays', default: "Automated merge request from \#{source} to \#{target}" }
|
115
|
+
],
|
116
|
+
desc: 'create a merge request between two supplied branches'
|
117
|
+
)
|
118
|
+
def create_merge_request(source, target, arg_title=nil)
|
119
|
+
title = arg_title || "Automated merge request from #{source} to #{target}"
|
120
|
+
self.merge_request = RoboPigeon::GitLab::MergeRequest.create!(source, target, title)
|
121
|
+
end
|
122
|
+
|
123
|
+
RoboPigeon::Documentarian.add_command(
|
124
|
+
'merge_branches',
|
125
|
+
block: %w[job gitlab],
|
126
|
+
params: [
|
127
|
+
{ name: 'source_branch', type: 'String', desc: 'source branch you want to merge from', example: "ENV['CI_COMMIT_REF_NAME']" },
|
128
|
+
{ name: 'target_branch', type: 'String', desc: 'target branch to merge to', example: 'master' },
|
129
|
+
{ name: 'title', type: 'String', desc: 'Optional string to use as the merge request title.', example: 'Merge my_face into master on tuesdays', default: "Automated merge request from \#{source} to \#{target}" }
|
130
|
+
],
|
131
|
+
desc: 'merge two branches together using a merge request that automatically merges'
|
132
|
+
)
|
133
|
+
def merge_branches(source, target, arg_title=nil)
|
134
|
+
title = arg_title || "Automated merge request from #{source} to #{target}"
|
135
|
+
RoboPigeon::GitLab::MergeRequest.create!(source, target, title).merge!
|
136
|
+
end
|
137
|
+
|
138
|
+
RoboPigeon::Documentarian.add_command(
|
139
|
+
'tag',
|
140
|
+
block: %w[job gitlab],
|
141
|
+
params: [
|
142
|
+
{ name: 'tag', type: 'String', desc: 'the tag to create', example: '1.2.3' },
|
143
|
+
{ name: 'ref', type: 'String', desc: 'branch or sha that you want to tag', example: 'master', default: ENV['CI_COMMIT_REF_NAME'] },
|
144
|
+
{ name: 'message', type: 'String', desc: 'message to annotate the tag with', example: 'updating version to 1.2.3', default: "RoboPigeon tagged at \#{Time.now}" }
|
145
|
+
],
|
146
|
+
desc: 'look up a merge request by source and target'
|
147
|
+
)
|
148
|
+
def tag(tag, ref=ENV['CI_COMMIT_REF_NAME'], message="RoboPigeon tagged at #{Time.now}")
|
149
|
+
RoboPigeon::GitLab::Client.create_tag(ref, tag, message)
|
150
|
+
end
|
151
|
+
|
152
|
+
RoboPigeon::Documentarian.add_command(
|
153
|
+
'find_merge_request',
|
154
|
+
block: %w[job gitlab],
|
155
|
+
params: [
|
156
|
+
{ name: 'source_branch', type: 'String', desc: 'source branch you want to merge from', example: "ENV['CI_COMMIT_REF_NAME']" },
|
157
|
+
{ name: 'target_branch', type: 'String', desc: 'target branch to merge to', example: 'master' }
|
158
|
+
],
|
159
|
+
desc: 'look up a merge request by source and target'
|
160
|
+
)
|
161
|
+
def find_merge_request(source, target)
|
162
|
+
RoboPigeon::GitLab::MergeRequest.find(source, target)
|
163
|
+
end
|
164
|
+
|
165
|
+
RoboPigeon::Documentarian.add_command(
|
166
|
+
'merge_merge_request',
|
167
|
+
block: %w[job gitlab],
|
168
|
+
desc: 'merge the recently created merge request'
|
169
|
+
)
|
170
|
+
def merge_merge_request
|
171
|
+
merge_request.merge!
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'gitlab'
|
2
|
+
|
3
|
+
module RoboPigeon::Dsl
|
4
|
+
module Helpers
|
5
|
+
module GitLab
|
6
|
+
RoboPigeon::Documentarian.add_command('deployment_sha', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'get the git sha of the specified deployed environement')
|
7
|
+
def deployment_sha(environment)
|
8
|
+
dep = RoboPigeon::GitLab::Client.get_deployment(environment)
|
9
|
+
dep.sha
|
10
|
+
end
|
11
|
+
|
12
|
+
RoboPigeon::Documentarian.add_command('deployment_ref', block: ['helpers'], params: [{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' }], desc: 'get the git ref (branch or tag) of the specified deployed environement')
|
13
|
+
def deployment_ref(environment)
|
14
|
+
dep = RoboPigeon::GitLab::Client.get_deployment(environment)
|
15
|
+
dep.ref
|
16
|
+
end
|
17
|
+
|
18
|
+
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')
|
19
|
+
def deployment_shortlog(environment)
|
20
|
+
dep = RoboPigeon::GitLab::Client.get_deployment(environment)
|
21
|
+
`git shortlog --no-merges #{dep.sha}..`
|
22
|
+
end
|
23
|
+
|
24
|
+
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')
|
25
|
+
def deployment_time(environment)
|
26
|
+
dep = RoboPigeon::GitLab::Client.get_deployment(environment)
|
27
|
+
dep.deployable.finished_at
|
28
|
+
end
|
29
|
+
|
30
|
+
RoboPigeon::Documentarian.add_command('deployment_git_log_jira_tickets',
|
31
|
+
block: ['helpers'],
|
32
|
+
params: [
|
33
|
+
{ name: 'environment', type: 'String', desc: 'the name of a gitlab operations environment', example: 'production' },
|
34
|
+
{ name: 'project_key', type: 'String', desc: 'the project key to search history for', example: 'TIC' }
|
35
|
+
],
|
36
|
+
desc: 'returns a list of jira tickets for the given project key in history since the deployment')
|
37
|
+
def tickets_in_log_since_deployment_to(environment, _project)
|
38
|
+
dep = RoboPigeon::GitLab::Client.get_deployment(environment)
|
39
|
+
log = `git log #{dep.sha}..`
|
40
|
+
log.scan(/[A-Za-z]+-\d+/)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
File without changes
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module RoboPigeon::GitLab
|
2
|
+
class MergeRequest
|
3
|
+
attr_accessor :merge_request
|
4
|
+
def initialize(merge_request)
|
5
|
+
self.merge_request = merge_request
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.create!(source, target, title)
|
9
|
+
RoboPigeon::GitLab::MergeRequest.new(RoboPigeon::GitLab::Client.client.create_merge_request(
|
10
|
+
RoboPigeon::GitLab::Client.project,
|
11
|
+
title,
|
12
|
+
source_branch: source,
|
13
|
+
target_branch: target
|
14
|
+
))
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.find(source, target)
|
18
|
+
RoboPigeon::GitLab::MergeRequest.new(
|
19
|
+
RoboPigeon::GitLab::Client.client.merge_requests(
|
20
|
+
RoboPigeon::GitLab::Client.project,
|
21
|
+
state: 'opened',
|
22
|
+
source_branch: source,
|
23
|
+
target_branch: target
|
24
|
+
).first
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def gitlab
|
29
|
+
RoboPigeon::GitLab::Client
|
30
|
+
end
|
31
|
+
|
32
|
+
def client
|
33
|
+
gitlab.client
|
34
|
+
end
|
35
|
+
|
36
|
+
def comment!(text)
|
37
|
+
client.create_merge_request_note(RoboPigeon::GitLab::Client.project, merge_request.iid, body: text)
|
38
|
+
end
|
39
|
+
|
40
|
+
def merge!
|
41
|
+
return if already_up_to_date
|
42
|
+
|
43
|
+
return if merge_merge_request!
|
44
|
+
|
45
|
+
close_merge_request!
|
46
|
+
raise 'Merge request could not be merged'
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def already_up_to_date
|
52
|
+
if merge_request.changes_count.nil? || merge_request.changes_count == '0'
|
53
|
+
close_merge_request!
|
54
|
+
puts 'Merge request had no changes, aborting.'
|
55
|
+
return true
|
56
|
+
end
|
57
|
+
false
|
58
|
+
end
|
59
|
+
|
60
|
+
def merge_merge_request!
|
61
|
+
begin
|
62
|
+
merge = client.accept_merge_request(RoboPigeon::GitLab::Client.project, merge_request.iid, merge_when_pipeline_succeeds: true)
|
63
|
+
return merge.merge_status == 'can_be_merged' && (merge.merge_when_pipeline_succeeds || merge.state == 'merged')
|
64
|
+
rescue Gitlab::Error::Error => e
|
65
|
+
puts "Failed to merge branch - #{e}\n#{e.message}"
|
66
|
+
end
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
def close_merge_request!
|
71
|
+
client.update_merge_request(RoboPigeon::GitLab::Client.project, merge_request.iid, state_event: 'close')
|
72
|
+
true
|
73
|
+
rescue Gitlab::Error::Error => e
|
74
|
+
puts "Failed to close merge request - #{e}\n#{e.message}"
|
75
|
+
false
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
RoboPigeon::Documentarian.add_block('gitlab', helpers: true, block: [], desc: 'a configuration block for gitlab')
|
2
|
+
RoboPigeon::Documentarian.add_block('gitlab', helpers: true, block: ['job'], desc: 'interact with gitlab, can have multiple')
|
3
|
+
|
4
|
+
require 'robopigeon/gitlab/dsl'
|
5
|
+
require 'robopigeon/gitlab/client'
|
6
|
+
require 'robopigeon/gitlab/merge_request'
|
7
|
+
require 'robopigeon/gitlab/helper_dsl'
|
8
|
+
|
9
|
+
module RoboPigeon::Dsl
|
10
|
+
module Helpers
|
11
|
+
include RoboPigeon::Dsl::Helpers::GitLab
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module RoboPigeon::Dsl
|
16
|
+
class Root
|
17
|
+
def gitlab(&block)
|
18
|
+
RoboPigeon::Dsl::GitLabRoot.run(&block)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
module RoboPigeon::Dsl
|
24
|
+
class Job
|
25
|
+
def gitlab(&block)
|
26
|
+
RoboPigeon::Dsl::GitLab.run(&block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RoboPigeon::Jira
|
2
|
+
class Client
|
3
|
+
@enabled = true
|
4
|
+
@api_key = ENV['JIRA_TOKEN']
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :api_key, :api_url, :enabled, :last_created_ticket
|
8
|
+
def jira_request
|
9
|
+
Faraday.new(url: RoboPigeon::Jira::Client.api_url) do |faraday|
|
10
|
+
faraday.adapter Faraday.default_adapter
|
11
|
+
faraday.headers['Content-Type'] = 'application/json'
|
12
|
+
faraday.headers['Authorization'] = 'Basic ' + RoboPigeon::Jira::Client.api_key
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module RoboPigeon::Dsl
|
2
|
+
class JiraRoot
|
3
|
+
def self.run(&block)
|
4
|
+
jira = RoboPigeon::Dsl::JiraRoot.new
|
5
|
+
jira.instance_eval(&block)
|
6
|
+
end
|
7
|
+
|
8
|
+
RoboPigeon::Documentarian.add_command(
|
9
|
+
'enabled',
|
10
|
+
block: ['jira'],
|
11
|
+
params: [
|
12
|
+
{ name: 'enabled', type: 'boolean', desc: 'should it run jira commands', example: 'false', default: 'true' }
|
13
|
+
],
|
14
|
+
desc: 'Set whether or not to run jira commands, defaults to true'
|
15
|
+
)
|
16
|
+
def enabled(bool)
|
17
|
+
RoboPigeon::Jira::Client.enabled = bool
|
18
|
+
end
|
19
|
+
|
20
|
+
RoboPigeon::Documentarian.add_command(
|
21
|
+
'api_key',
|
22
|
+
block: ['jira'],
|
23
|
+
params: [
|
24
|
+
{ name: 'api_key', type: 'String', desc: 'the api key for your jira account', example: 'someLongString12ofLettersAndNumber5', default: "ENV['JIRA_TOKEN']" }
|
25
|
+
],
|
26
|
+
desc: 'set your jira api key globally'
|
27
|
+
)
|
28
|
+
def api_key(key)
|
29
|
+
RoboPigeon::Jira::Client.api_key = key
|
30
|
+
end
|
31
|
+
|
32
|
+
RoboPigeon::Documentarian.add_command(
|
33
|
+
'api_url',
|
34
|
+
block: ['jira'],
|
35
|
+
params: [
|
36
|
+
{ name: 'api_url', type: 'String', desc: 'the api url for your jira', example: 'https://jira.example.com/' }
|
37
|
+
],
|
38
|
+
desc: 'set your jira api key globally'
|
39
|
+
)
|
40
|
+
def api_url(key)
|
41
|
+
RoboPigeon::Jira::Client.api_url = key
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
class Jira < JiraRoot
|
46
|
+
include RoboPigeon::Dsl::Helpers
|
47
|
+
|
48
|
+
def self.run(&block)
|
49
|
+
jira = RoboPigeon::Dsl::Jira.new
|
50
|
+
jira.instance_eval(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
RoboPigeon::Documentarian.add_block(
|
54
|
+
'ticket',
|
55
|
+
params: [
|
56
|
+
{ name: 'number', type: 'String', desc: 'Existing ticket number to reference (optional)', example: 'TIC-1234' }
|
57
|
+
],
|
58
|
+
helpers: true,
|
59
|
+
block: %w[job jira],
|
60
|
+
desc: 'Create or update a ticket'
|
61
|
+
)
|
62
|
+
def ticket(number = nil, &block)
|
63
|
+
RoboPigeon::Dsl::JiraTicket.run(number, &block)
|
64
|
+
end
|
65
|
+
|
66
|
+
RoboPigeon::Documentarian.add_block(
|
67
|
+
'comment_on',
|
68
|
+
params: [
|
69
|
+
{ name: 'number', type: 'String', desc: 'Existing ticket number to reference', example: 'TIC-1234' },
|
70
|
+
{ name: 'comment', type: 'String', desc: 'Comment to add to the ticket', example: 'A comment for a ticket' }
|
71
|
+
],
|
72
|
+
helpers: true,
|
73
|
+
block: %w[job jira],
|
74
|
+
desc: 'Add a comment to specified ticket'
|
75
|
+
)
|
76
|
+
def comment_on(number, comment)
|
77
|
+
jira = RoboPigeon::Jira::Ticket.new(number)
|
78
|
+
jira.add_comment(comment)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module RoboPigeon::Dsl
|
2
|
+
module Helpers
|
3
|
+
module Jira
|
4
|
+
RoboPigeon::Documentarian.add_command('jira_last_created_ticket', block: ['helpers'], desc: 'Returns the id of the last created ticket.')
|
5
|
+
def jira_last_created_ticket
|
6
|
+
RoboPigeon::Jira::Client.last_created_ticket
|
7
|
+
end
|
8
|
+
|
9
|
+
RoboPigeon::Documentarian.add_command('jira_last_created_ticket_link', block: ['helpers'], desc: 'Returns a link to the last created ticket.')
|
10
|
+
def jira_last_created_ticket_link
|
11
|
+
issue_id = RoboPigeon::Jira::Client.last_created_ticket
|
12
|
+
jira_url = RoboPigeon::Jira::Client.api_url
|
13
|
+
"#{jira_url}/browse/#{issue_id}"
|
14
|
+
end
|
15
|
+
|
16
|
+
RoboPigeon::Documentarian.add_command('jira_last_created_ticket_slack_link', block: ['helpers'], desc: 'Returns a slack formatted link to the last created ticket.')
|
17
|
+
def jira_last_created_ticket_slack_link
|
18
|
+
issue_id = RoboPigeon::Jira::Client.last_created_ticket
|
19
|
+
jira_url = RoboPigeon::Jira::Client.api_url
|
20
|
+
"<#{issue_id}|#{jira_url}/browse/#{issue_id}>"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|