NAME

Git::Hooks::Notify - Git::Hooks plugin to notify users via email

VERSION

version 4.0.0

SYNOPSIS

As a Git::Hooks plugin you don't use this Perl module directly. Instead, you may configure it in a Git configuration file like this:

[githooks]

  # Enable the plugin
  plugin = Notify

[githooks "notify"]

  # Define notifications From: header
  from = githooks@example.net

  # Define a URL pattern to embed links to commits in the notifications.
  commit-url = https://github.com/userid/repoid/commit/%H

  # Notify this email about all pushes
  rule = gnustavo@cpan.org

  # Notify this email about all pushes, except merge commits
  rule = --no-merges gnustavo@cpan.org

  # Notify these emails about changes in the lib/Git/Hooks/Notify.pm file.
  rule = fred@example.net barney@example.net -- lib/Git/Hooks/Notify.pm

  # Notify these emails about changes in the file Changes and below the
  # directory lib/.
  rule = batman@example.net robin@example.net -- Changes lib/

  # Notify the manager about any changes in branches which name start with
  # "release"
  rule = ^refs/heads/release manager@example.net

DESCRIPTION

This Git::Hooks plugin hooks itself to the hooks below to notify users via email about pushed commits affecting specific files in the repository.

  • post-receive

    This hook is invoked once in the remote repository after a successful git push. It's used to notify Jira of commits citing its issues via comments.

To enable it you should add it to the githooks.plugin configuration option:

[githooks]
  plugin = Notify

By default no notifications are sent. You have to specify rules telling the plugin which email addresses should receive notifications about any change or about changes in specific paths inside the repository. Each rule is checked for each branch affected by the git-push and each combination may produce a specific email notification, with configurable Subject and From headers.

You should avoid configuring too many rules because each one of them will trigger a git-log command and potentially send an email. All this processing will take place while the user is waiting for the command git-push to finish. In order to minimize the delay you should try to configure a single global rule and a single rule for each path specification, grouping all email addresses interested in the same path in the same rule.

The body of the message contains information about the changes and the result of a git log command showing the pushed commits and the list of files affected by them. For example:

Subject: [Git::Hooks::Notify] repo:myproject branch:master

This is a notification about new commits affecting a repository you're watching.

REPOSITORY: myproject
BRANCH: master
PUSHED BY: username
FROM: 75550b66ab08536787487545904fb062c6e38a7f
TO:   6eaa6a84fbd7e2a64e66664f3d58707618e20c72
FILTER: lib/Git/Hooks/

commit 6eaa6a84fbd7e2a64e66664f3d58707618e20c72
Author: Gustavo L. de M. Chaves <gnustavo@cpan.org>
Date:   Mon Dec 4 21:41:19 2017 -0200

    Add plugin Git::Hooks::Notify

305     0       lib/Git/Hooks/Notify.pm
63      0       t/02-notify.t

commit c45feb16fe3e6fc105414e60e91ffb031c134cd4
Author: Gustavo L. de M. Chaves <gnustavo@cpan.org>
Date:   Sat Nov 25 19:13:42 2017 -0200

    CheckJira: JQL options are scalar, not multi-valued

40      32      lib/Git/Hooks/CheckJira.pm
12      12      t/02-check-jira.t

The FILTER: line only appears if the rule specifies one or more pathspecs to only show commits affecting matching files.

Each commit shows the files it changes, perhaps filtered by the rule's pathspecs. They're shown in the format produced by the command

git log --numstat --first-parent -m

Merge commits are marked with an additional Merge: header and show files changed with regards to the first parent commit only.

You can change the git log format and a few other things in the message using the configuration options explained below.

NAME

Notify - Git::Hooks plugin to notify users via email

CONFIGURATION

The plugin is configured by the following git options under the githooks.notify subsection.

It can be disabled for specific references via the githooks.ref and githooks.noref options about which you can read in the Git::Hooks documentation.

rule [REFS] [OPTIONS] RECIPIENTS [-- PATHSPEC ...]

The rule directive adds a notification rule specifying which RECIPIENTS should be notified of commits pushed to a reference matching REFS, affecting the specified PATHSPECS.

If no REFS are specified, the recipients are notified about commits affecting any reference.

If no PATHSPECS are specified, the recipients are notified about commits affecting any file.

The commits are grokked as with the following command:

git log --numstat --first-parent -m

REFS is a space-separated list of regular expressions matching absolute reference names. They must begin with a caret (^), anchoring the match to the left. For example: ^refs/heads/master$, ^refs/heads/release, ^refs/heads/(?:feature|release).

OPTIONS is a space-separated list of extra options to pass to the git log command. Avoid options that may change the output formatting. Feel free to use the commit limiting options, as documented in the git log manual.

RECIPIENTS is a space-separated list of email addresses.

PATHSPECS is a space-separated list of pathspecs, used to restrict notifications to commits affecting particular paths in the repository. Note that the list of paths starts after a double-dash (--).

For example:

[githooks "notify"]
  rule = gnustavo@cpan.org
  rule = fred@example.net barney@example.net -- lib/Git/Hooks/Notify.pm
  rule = --no-merge batman@example.net robin@example.net -- Changes lib/
  rule = ^refs/heads/release manager@example.net

The first rule above sends notifications to gnustavo@cpan.org about every commit pushed to the repository.

The second rule sends notifications to the Bedrock fellows just about commits affecting the lib/Git/Hooks/Notify.pm file.

The third rule sends notifications to the Dynamic Duo just about commits affecting in the Changes file in the repository root and about commits affecting any file under the lib/ directory, except merge commits.

The fourth rule sends notifications to the manager about commits to any branch which name starts with "release".

You can read all about pathspecs in the git help glossary.

transport TRANSPORT [ARGS...]

By default the messages are sent using Email::Simple's default transport. On Unix systems, it is usually the sendmail command. You can specify another transport using this configuration.

TRANSPORT must be the basename of an available transport class, such as SMTP, Maildir, or Mbox. The name is prefixed with Email::Sender::Transport:: and the complete name is required like this:

eval "require Email::Sender::Transport::$TRANSPORT";

So, you must make sure such a transport is installed in your server's Perl.

ARGS is a space-separated list of VAR=VALUE pairs. All pairs will be tucked in a hash and passed to the transport's constructor. For example:

[githooks "notify"]
  transport = SMTP host=smtp.example.net ssl=starttls sasl_username=myself sasl_password=myword
  transport = Mbox filename=/home/user/.mbox
  transport = Maildir dir=/home/user/maildir

Please, read the transport's class documentation to know which arguments are available.

from SENDER

This allows you to specify a sender address to be used in the notification's To header. If you don't specify it, the sender will probably be the user running your hooks. But you shouldn't count on it. It's better to specify it with a valid email address that your users can reply to. Something like this:

[githooks "notify"]
  from = "Git::Hooks" <git@yourdomain.com>

subject SUBJECT

This allows you to specify the subject of the notification emails. If you don't specify it, the default is like this:

Subject: [Git::Hooks::Notify] repo:%R branch:%B

The %letters symbols are placeholders that are replaced automatically. The three placeholders defined are:

  • %R: the repository name.

  • %B: the branch name.

  • %A: the username of the user who performed the git-push command.

preamble TEXT

This allows you to specify a preamble for the notification emails. There is no default preamble.

max-count INT

This allows you to specify the limit of commits that should be shown for each changed branch. Read about the --max-count option in git help log. If not specified, a limit of 10 is used.

commit-url URL_PATTERN

If your Git repository has a web interface it's useful to provide links to the commits shown in the notification message. If configured, each SHA1 contained in the git-log output is substituted by URL_PATTERN, with the %H placeholder replaced by the SHA1.

The %R is another placeholder which is substituted by the repository name, as returned by Git::Repository::Plugin::GitHooks's repository_name method.

See below how to configure this for some common Git servers. Replace the angle-bracketed names with values appropriate to your context:

  • GitHub

    https://github.com/<USER>/<REPO>/commit/%H
  • Bitbucket Cloud

    https://bitbucket.org/<USER>/<REPO>/commits/%H
  • Bitbucket Server

    <BITBUCKET_BASE_URL>/projects/%R/commits/%H
  • Gerrit with Gitiles

    <GERRIT_BASE_URL>/plugins/gitiles/%R/+/%H

html BOOL

By default the email messages are sent in plain text. Enabling this option sends HTML-formatted messages, which look better on some email readers.

Make sure you have the HTML::Entities module installed, because it's needed to format the messages.

TO DO

These are just a few of the ideas for improving this plugin.

  • Generalize the commit-url template.

    It should support other placeholders for the Git server's base URL, repository name, user name, etc. So that we could configure a single template for all repositories in a server. Currently one has to configure a different commit-url for each repository.

  • Send notifications on Gerrit's change-merged hook.

SEE ALSO

AUTHOR

Gustavo L. de M. Chaves <gnustavo@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2024 by CPQD <www.cpqd.com.br>.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.