Last active
August 29, 2015 14:02
-
-
Save cpruitt/5fdaec6de5aa12cc6080 to your computer and use it in GitHub Desktop.
Inspyre Git post-commit to send email notifications to specific people for specific branches (2.0)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env ruby | |
| require "action_mailer" | |
| options = { | |
| # The name of this project / repository | |
| # to be used in the emailed notifications | |
| project_name: "My Development Project", | |
| # Hash of branch specific notification settings. | |
| # Hash keys are individual symbols or Regexp objects (or arrays | |
| # thereof) specifying the branches to send notifications to. The | |
| # special key :default specifies notification settings for all | |
| # defined branches unless a specific branch overrides it. The key | |
| # can also be an array of mixed symbols / regexs. | |
| # | |
| # Each entry in the :branches hash is, itself, a hash with | |
| # two possible keys: | |
| # :subject - String to be used in the subject | |
| # The subject string which can have placeholders for: {branch} and {project} | |
| # If left out a reasonable subject line is used by default. | |
| # :mail_to - Array of recipient email addresses | |
| branches: { | |
| default: { | |
| mail_to: [ '[email protected]', '[email protected]', '[email protected]' ] | |
| }, | |
| [:master, :develop] => {} | |
| }, | |
| # SMTP mailer settings. Used by ActionMailer | |
| mailer: { | |
| address: "smtp.example.com", | |
| port: 587, | |
| domain: "example.com", | |
| user_name: "[email protected]", | |
| password: "p@$$w0rd", | |
| authentication: :login, | |
| enable_starttls_auto: true | |
| }, | |
| # Displays feedback about the notification. | |
| # Using this will cause the git commit to exit more slowly. | |
| # Setting to false will fork the notification process allowing | |
| # the git commit to complete and exit immediately. | |
| chatty: true, | |
| # Set :markup to :markdown to process commit messages as markdown text. | |
| # Markdown formatting: https://github.com/bhollis/maruku/blob/master/docs/markdown_syntax.md | |
| markup: :markdown, | |
| } | |
| ###################################################################### | |
| # # | |
| # No need to edit anything past this point. # | |
| # # | |
| ###################################################################### | |
| begin | |
| require 'maruku' | |
| @markdownable = true | |
| rescue LoadError | |
| puts "==== Enable markdown formatting by installing the maruku gem: $ gem install maruku ====" | |
| puts " Silence this notice by removing it from post-commit or by installing the gem." | |
| @markdownable = false | |
| end | |
| class CommitHandler | |
| def initialize(config = {}) | |
| @config = { | |
| chatty: false | |
| }.merge(config) | |
| expand_branch_settings | |
| # Find current branch | |
| @current_branch = nil | |
| git_branches = (`git branch`).split("\n").each { |b| @current_branch = b[2..-1] if b[0] == "*" } | |
| @current_branch.downcase! | |
| end | |
| def run | |
| branch_options = branch_options_for_current_branch | |
| if branch_options | |
| tell("Sending notification for branch `#{@current_branch}` to:\n" + branch_options[:mail_to].join("\n")) | |
| tell("") | |
| else | |
| tell("Branch `#{@current_branch}` has no notification rules. Nothing to send.") | |
| tell("") | |
| return | |
| end | |
| commit = GitCommit.new | |
| if @config[:markdownable] && @config[:markup] == :markdown | |
| m = [] | |
| m << "#{@config[:project_name]}" | |
| m << "==================================================" | |
| m << "" | |
| m << "## New Git Commit on branch: `#{@current_branch}`" | |
| m << "--------------------------------------------------" | |
| m << "" | |
| m << "* __Authored BY:__ #{commit.author}" | |
| m << "* __Committed On:__ #{commit.date}" | |
| m << "* __Commit ID:__ #{commit.commit}" | |
| m << "" | |
| m << "--------------------------------------------------" | |
| m << "" | |
| m << commit.message | |
| m << "" | |
| msg_txt = m.join("\n") | |
| msg = Maruku.new(msg_txt).to_html | |
| else | |
| msg = "<h1>#{@config[:project_name]}</h1><h2>New Git Commit on #{@current_branch}</h2><p style=\"font-family:monospace;\">#{commit.message}</p>" | |
| msg_txt = "New Git Commit\n\n" + commit.message | |
| end | |
| subject = branch_options[:subject] | |
| subject.gsub!(/\{project\}/, @config[:project_name]) | |
| subject.gsub!(/\{branch\}/, @current_branch) | |
| mail_using = :smtp | |
| if mail_using == :smtp | |
| ActionMailer::Base.delivery_method = :smtp | |
| ActionMailer::Base.smtp_settings = @config[:mailer] | |
| else | |
| ActionMailer::Base.delivery_method = :sendmail | |
| end | |
| Notifier.notify(branch_options[:mail_to], subject, msg, msg_txt).deliver | |
| tell "" | |
| tell "MAILING NOTIFICATION:" | |
| tell msg | |
| tell "" | |
| tell "" | |
| end | |
| private | |
| def expand_branch_settings | |
| @config[:notification_branches] = {} | |
| @config[:branches] = {} unless @config[:branches].class == Hash | |
| @config[:branches][:default] = {} unless @config[:branches][:default].class == Hash | |
| @config[:branches][:default][:subject] = "NOTIFICATION: New Git commit for {project} on {branch}" unless @config[:branches][:default][:subject] | |
| @config[:branches].each do |branches, settings| | |
| result_settings = @config[:branches][:default].merge(settings) | |
| branches = [branches] unless branches.class == Array | |
| branches.each do |branch| | |
| if branch.kind_of?(Regexp) | |
| @config[:notification_branches][branch] = result_settings | |
| else | |
| @config[:notification_branches][branch.to_s] = result_settings | |
| end | |
| end | |
| end | |
| end | |
| def branch_options_for_current_branch | |
| result = nil | |
| @config[:notification_branches].each do |branch_key, branch_settings| | |
| if branch_key.kind_of?(Regexp) | |
| result = branch_settings if @current_branch =~ branch_key | |
| else | |
| result = branch_settings if @current_branch == branch_key.to_s | |
| end | |
| end | |
| result | |
| end | |
| def tell(msg) | |
| return if !@config[:chatty] | |
| puts(msg) | |
| end | |
| end | |
| class GitCommit | |
| attr_accessor :commit, :author, :date, :message | |
| def initialize | |
| log_lines = `git log -1`.split("\n") | |
| @commit = log_lines.shift.split(' ')[1..-1].join(' ') | |
| @author = log_lines.shift.split(' ')[1..-1].join(' ') | |
| @date = log_lines.shift.split(' ')[1..-1].join(' ') | |
| log_lines.shift | |
| @message = log_lines.collect { |l| l.to_s[4..-1] }.join("\n") | |
| end | |
| end | |
| # ActionMailer notification | |
| class Notifier < ActionMailer::Base | |
| default :from => "[email protected]" | |
| def notify(recips, subject, msg, msg_txt) | |
| mail(:to => recips, :subject => subject) do |format| | |
| format.text { render :text => msg_txt} | |
| format.html { render :text => msg} | |
| end | |
| end | |
| end | |
| if options[:chatty] | |
| CommitHandler.new(options.merge({markdownable: @markdownable})).run | |
| else | |
| fork do | |
| CommitHandler.new(options.merge({markdownable: @markdownable})).run | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment