robopigeon 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|