Skip to content

Instantly share code, notes, and snippets.

@a-voronov
Last active May 14, 2020 13:09
Show Gist options
  • Save a-voronov/9f97a40b6e03789a2aee9194e9ddc5be to your computer and use it in GitHub Desktop.
Save a-voronov/9f97a40b6e03789a2aee9194e9ddc5be to your computer and use it in GitHub Desktop.
Gitlab Merge Requests Reminder
require 'getoptlong'
require 'gitlab'
opts = GetoptLong.new(
['--help', '-h', GetoptLong::NO_ARGUMENT],
['--endpoint', '-e', GetoptLong::REQUIRED_ARGUMENT],
['--token', '-t', GetoptLong::REQUIRED_ARGUMENT],
['--group', '-g', GetoptLong::REQUIRED_ARGUMENT],
['--webhook', '-w', GetoptLong::REQUIRED_ARGUMENT]
)
$GITLAB_ENDPOINT = nil
$GITLAB_PRIVATE_TOKEN = nil
$GITLAB_GROUP_ID = nil
$SLACK_WEBHOOK = nil
opts.each do |opt, arg|
case opt
when '--help'
puts <<-EOF
-h, --help:
show help
--endpoint 'https://yourcompany.gitlab.com/api/v4', -e 'https://yourcompany.gitlab.com/api/v4':
gitlab API endpoint
--token 'xxxxxxxxxx', -t 'xxxxxxxxxx':
gitlab private token (you may have service user with read-only rights for this purpose)
--group x, -g x:
gitlab group id (supposing your team projects are in one group)
--webhook 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX', -w 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX':
slack webhook url
EOF
exit 0
when '--endpoint'
$GITLAB_ENDPOINT = arg.to_s
when '--token'
$GITLAB_PRIVATE_TOKEN = arg.to_s
when '--group'
$GITLAB_GROUP_ID = arg.to_i
when '--webhook'
$SLACK_WEBHOOK = arg.to_s
end
end
if $GITLAB_ENDPOINT.nil? or $GITLAB_PRIVATE_TOKEN.nil? or $GITLAB_GROUP_ID.nil? or $SLACK_WEBHOOK.nil?
puts 'Missing one of the arguments (try --help)'
exit 0
end
$ANIMALS = ['๐Ÿ™ˆ See-No-Evil Monkey', '๐Ÿ™‰ Hear-No-Evil Monkey', '๐Ÿ™Š Speak-No-Evil Monkey', '๐Ÿต Monkey', '๐Ÿ’ Monkey', '๐Ÿฆ Gorilla', '๐Ÿถ Dog', '๐Ÿ• Dog', '๐Ÿฉ Poodle', '๐Ÿบ Wolf', '๐ŸฆŠ Fox', '๐Ÿฆ Raccoon', '๐Ÿฑ Cat', '๐Ÿˆ Cat', '๐Ÿฆ Lion', '๐Ÿฏ Tiger', '๐Ÿ… Tiger', '๐Ÿ† Leopard', '๐Ÿด Horse', '๐ŸŽ Horse', '๐Ÿฆ„ Unicorn', '๐Ÿฆ“ Zebra', '๐Ÿฎ Cow', '๐Ÿ‚ Ox', '๐Ÿƒ Water Buffalo', '๐Ÿ„ Cow', '๐Ÿท Pig', '๐Ÿ– Pig', '๐Ÿ— Boar', '๐Ÿ Ram', '๐Ÿ‘ Ewe', '๐Ÿ Goat', '๐Ÿช Camel', '๐Ÿซ Camel', '๐Ÿฆ™ Llama', '๐Ÿฆ’ Giraffe', '๐Ÿ˜ Elephant', '๐Ÿฆ Rhinoceros', '๐Ÿฆ› Hippopotamus', '๐Ÿญ Mouse', '๐Ÿ Mouse', '๐Ÿ€ Rat', '๐Ÿน Hamster', '๐Ÿฐ Rabbit', '๐Ÿ‡ Rabbit', '๐Ÿฟ Chipmunk', '๐Ÿฆ” Hedgehog', '๐Ÿฆ‡ Bat', '๐Ÿป Bear', '๐Ÿจ Koala', '๐Ÿผ Panda', '๐Ÿฆ˜ Kangaroo', '๐Ÿฆก Badger', '๐Ÿฆƒ Turkey', '๐Ÿ” Chicken', '๐Ÿ“ Rooster', '๐Ÿฃ Chick', '๐Ÿค Baby Chick', '๐Ÿฅ Baby Chick', '๐Ÿฆ Bird', '๐Ÿง Penguin', '๐Ÿ•Š Dove', '๐Ÿฆ… Eagle', '๐Ÿฆ† Duck', '๐Ÿฆข Swan', '๐Ÿฆ‰ Owl', '๐Ÿฆš Peacock', '๐Ÿฆœ Parrot', '๐Ÿธ Frog', '๐ŸŠ Crocodile', '๐Ÿข Turtle', '๐ŸฆŽ Lizard', '๐Ÿ Snake', '๐Ÿฒ Dragon', '๐Ÿ‰ Dragon', '๐Ÿฆ• Sauropod', '๐Ÿฆ– T-Rex', '๐Ÿณ Spouting Whale', '๐Ÿ‹ Whale', '๐Ÿฌ Dolphin', '๐ŸŸ Fish', '๐Ÿ  Tropical Fish', '๐Ÿก Blowfish', '๐Ÿฆˆ Shark', '๐Ÿ™ Octopus', '๐Ÿš Spiral Shell', '๐Ÿฆ€ Crab', '๐Ÿฆž Lobster', '๐Ÿฆ Shrimp', '๐Ÿฆ‘ Squid', '๐ŸŒ Snail', '๐Ÿฆ‹ Butterfly', '๐Ÿ› Bug', '๐Ÿœ Ant', '๐Ÿ Honeybee', '๐Ÿž Lady Beetle', '๐Ÿฆ— Cricket', '๐Ÿ•ท Spider', '๐Ÿฆ‚ Scorpion', '๐ŸฆŸ Mosquito', '๐Ÿฆ  Microbe']
def run
client = Gitlab.client(endpoint: $GITLAB_ENDPOINT, private_token: $GITLAB_PRIVATE_TOKEN)
mrs = group_mrs(client)
projects = group_projects(client)
messages_per_project = mrs.map { |project_id, project_mrs|
project = projects.find { |p| p['id'] == project_id }
"โ€ข *#{project_name(project)}*:\n" + project_mrs.map { |mr|
" #{mr_age(mr)} <#{mr['web_url']}|#{mr['title']}> " + mr_status(mr)
}.join("\n")
}
br = "\n\n"
message_start = "*Good Morning! โ˜•๏ธ๐Ÿ˜Š *"
mrs_message = "Seems like there're some Merge Requests waiting for the review. Now is the best time to do it! ๐Ÿ˜‰"
alt_message = "Seems like we don't have any Merge Requests waiting for the review! Good job! ๐Ÿ’ช๐Ÿ˜Ž"
message_end = "\n*#{$ANIMALS.sample} wishes you a great day! ๐Ÿค™ *"
message_body = unless messages_per_project.empty? then mrs_message + br + messages_per_project.join(br) else alt_message end
slack([message_start, message_body, message_end].join(br))
end
def group_mrs(client)
client.
get("/groups/#{url_encode($GITLAB_GROUP_ID)}/merge_requests", query: { state: 'opened', order_by: 'created_at', per_page: 100 }).
map(&:to_hash).
reject { |mr| mr['work_in_progress'] }.
group_by { |mr| mr['project_id'] }
end
def group_projects(client)
client.
group_projects($GITLAB_GROUP_ID, per_page: 100).
map(&:to_hash)
end
def project_name(project)
if project
project['name'].upcase
else
'unknown project ๐Ÿคทโ€โ™‚๏ธ'
end
end
def mr_age(mr)
age = DateTime.now.mjd - Date.parse(mr['created_at']).mjd
case age - 1
when 0
'๐Ÿฃ'
when 1..3
['๐Ÿฅบ', '๐Ÿ™', '๐Ÿ™‹โ€โ™‚๏ธ', '๐Ÿ™‹', '๐Ÿ‘€', '๐Ÿค—', '๐Ÿ‘‹', 'โœŒ๏ธ'].sample
when 3..10
['๐ŸงŸโ€โ™‚๏ธ', '๐ŸงŸโ€โ™€๏ธ'].sample
else
'โ˜ ๏ธ'
end
end
def mr_status(mr)
if mr['merge_status'] == 'can_be_merged' then 'โœ”๏ธŽ' else 'โœ˜' end
end
def url_encode(url)
URI.encode(url.to_s, /\W/)
end
def slack(message)
puts message
begin
require 'net/http'
uri = URI($SLACK_WEBHOOK)
Net::HTTP.start(uri.host, uri.port, :use_ssl => true) do |http|
request = Net::HTTP::Post.new(uri, { 'Content-Type' => 'application/json', 'Accept' => 'application/json' })
request.body = { "text" => "#{message}" }.to_json
response = http.request(request)
puts "response #{response.body}"
end
rescue => e
puts "failed #{e}"
end
end
# --------------- RUN --------------- #
run
@a-voronov
Copy link
Author

Requirements

Usage

run ruby script by providing necessary arguments:

  • gitlab endpoint: 'https://yourcompany.gitlab.com/api/v4'
  • gitlab private token (you may have service user with read-only rights for this purpose): 'xxxxxxxxxxxxxxxxxxxxxxxx'
  • gitlab group id (supposing your team projects are in one group): 42
  • slack webhook url: 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'
$ ruby mr-reminder.rb \
       --endpoint 'https://yourcompany.gitlab.com/api/v4' \
       --token 'xxxxxxxxxxxxxxxxxxxxxxxx' \
       --group 42 \
       --webhook 'https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX'

use help for more info:

$ ruby mr-reminder.rb --help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment