Carlos Contreiras
I'm not the droid you're looking for. Move along, move along.
by Carlos Contreras
Dinosaur.JS
production => happy-branch
staging4 => rc99.4.0
uct => ui4
fixture => upgrade-webpack
saintbox => mistery-branch
Tired of keeping a track on what's deployed on all test environments?
Sick of searching trough all PR/MR to prepare release notes?
Can't memorize the meeting url?
Text
* Translations is a different story
secret-server
Meet the tribute bot!
Messages that begin with a slash (/) are commands and will behave differently from regular messages.
When a slash command is invoked, Slack sends your server a HTTP POST of data describing the user's invocation.
https://tribute-bot.com/slack/slash_commands/whats_in
token=gIkuvaNzQIHg97ATvDxqgjtO
team_id=T0001
team_domain=example
enterprise_id=E0001
enterprise_name=Globular%20Construct%20Inc
channel_id=C2147483705
channel_name=test
user_id=U2147483697
user_name=Steve
command=/whats_in
text=saintbox
response_url=https://hooks.slack.com/commands/1234/5678
For example, imagine that there's an app command installed called /whats_in. If someone on the tribute-bot.slack.com team types /weather stainbox in the #test channel and hits enter, this data would be posted to the external URL:
🌟 /release_notes branch repo
Gets RC release notes 📝
/release_notes ui4 gitlab
/release_notes rc43 github
Examples
🌟 /whats_in environment
Show me what's deployed! 🚀
/whats_in saintbox
Example
/whats_in fixture
🌟 /whats_running
Tell me what's deployed in all environments? 👁
/whats_running
Example
🌟 Daily Reminders
Did you forget you had that meeting today? 😱
Example
class Slack::SlashCommandsController < Slack::BaseCommandsController
include Slack::CustomMessage
def release_notes
render status: 200, :json => message('Aye aye! please hold your seat, this can take a while 🕐')
HardWorker.perform_async(release_notes_params.to_h)
end
def whats_running_where
whats_running_where_command = DeployedBranch::BranchNames.call
if whats_running_where_command.success?
branches_data = whats_running_where_command.deployed_branches
render status: 200, :json => message_attachments(deployed_branch_messages(branches_data))
else
render status: 200, :json => message(whats_running_where_command.error)
end
end
def whats_in
branch_name_command = DeployedBranch::BranchName.call(environment: params['text'])
if branch_name_command.success?
branch_data = branch_name_command.deployed_branch
render status: 200, :json => message_attachments(deployed_branch_messages(branch_data))
else
render status: 200, :json => message(branch_name_command.error)
end
end
end
class DeployedBranch::BranchName
include HTTParty
include AyeCommander::Command
requires :environment
returns :deployed_branch, :error
basic_auth Rails.application.secrets.basic_auth['username'], Rails.application.secrets.basic_auth['password']
before do
@url = generate_url
end
def call
get_revision
parse_revision
end
def get_revision
response = HTTParty.get(@url)
@revision = response.body.strip!
rescue SocketError => e
Rails.logger.error(e.message)
@error = "That enviroment doesn't exits, are you sure you typed it correctly? 🤔"
fail!(:invalid_environment_name) && abort!
end
def parse_revision
response = @revision.split(' ')
@deployed_branch = {}.tap do |h|
h[:environment] = environment.capitalize
h[:branch] = response[1]
h[:version] = response[3].strip[0..7]
h[:timestamp] = response[7].to_time.to_formatted_s(:long)
h[:author] = response[9]
end
end
def generate_url
base_url = Rails.application.secrets.base_uri
if environment.to_sym == :production
"https://#{base_url}/REVISION.txt"
else
"https://#{environment}.#{base_url}/REVISION.txt"
end
end
end
class ReleaseNotes::GenericRepo
include AyeCommander::Command
requires :repository_name, :target_branch
returns :release_notes, :error
before do
@adapter = initialize_git
end
def call
prepare_branch
get_release_notes
end
def initialize_git
ReleaseNotes::RepoAdapter.get(repository_name)
rescue => e
Rails.logger.error e.message
@error = "Beep Bop Boop, I couldn't find repository *#{repository_name}*, are you sure it exists? 👁"
fail!(:invalid_repository_name) && abort!
end
def prepare_branch
@adapter.prepare_branch(target_branch)
rescue => e
Rails.logger.error e.message
@error = "Error fetching branch: #{target_branch}, are you sure it exists in remote? 😱"
fail!(:invalid_branch_name) && abort!
end
def get_release_notes
begin
@release_notes = @adapter.release_notes(@branch)
rescue => e
Rails.logger.error e.message
@error = "Erro: Something is burning 🔥🚒!"
fail!(:something_went_wrong) && abort!
end
end
end
class ReleaseNotes::GithubRepo
def initialize
@git = Git.open(Rails.application.secrets.github_repository)
end
def prepare_branch(branch)
@git.checkout(:master)
@git.pull
@git.checkout(branch)
@git.pull(:origin, branch)
end
def release_notes(branch)
release_notes = []
@git.log(MAX_LOG_NUM).between(:master, branch).each do |commit|
commit_array = @git.object(commit).contents.split("\n").reject!(&:empty?)
commit_array.each do |message|
if message =~ /Merge pull request #/
release_notes << "#{message.scan(/#\d+/).first} #{commit_array.last}"
end
end
end
release_notes
end
end
✅ Conversational Responses
✅ Assign Pull requests (?)
✅ Deploy to test environments (?)
https://github.com/DarthCharles/tribute-bot
By Carlos Contreiras