Sending notifications by mail when the project is deployed
In our project, with every deploy, developers, testers and a couple of people receive wonderful letters:
Such a solution helped us get rid of the testers' questions “Well, have they already posted the fix for bug XXX?”, “What's new on the test server?”. Also, all team members, the implementation department and the management are aware of what is happening with the code on the servers.
For work, git, capistrano (+ multistage), php, bash (+ some console utilities) are used. If interested - go under the cat.
We assume that we have a configs.ini file in the root of the repository that contains the runtime.version key . The basis was taken gist # 381852 .
What's going on here:
We read the incoming parameters and make sure that the tag has arrived:
Select the tag name, break it into pieces, look for the previous tag for this server:
If $ prevtag is empty, then this is the first installation on the server. If the version of the new and old tags matches, this is an update; if not, the installation of a new version. Thus, we generate the correct message header.
We begin to form the body of the letter. First, let's determine who dared to deploy:
Now let's analyze task commits. The latter in Jira are named after the mask <project alias> -, all developers must specify the task alias (uppercase) in the commit. If the task is larger than 30 minutes and requires more than 1 commit, a branch is created according to the task alias, and then in commits we no longer mention this task. In total, in order to get a list of tasks, we need to perform not complicated processing with a regular schedule:
Subject: Our project version v1.1.1 is updated on the server 'testing'
user1 posted the following updates on the server 'testing':
Task commits:
jira.local / browse / PROJECT-1234
Full list of commits from the previous update:
4392a53 Thu Aug 18 17: 50:32 2011 +0700 user1 / [PROJECT-1234] made a useful
f2fcfe2 Thu Aug 18 17:37:53 2011 +0700 user1 / made a terrible
cb1fcbe Wed Aug 17 15:18:10 2011 +0700 user2 / made
changes to the files:
file1 | 4 ++ -
file2 | 8 ++++ ----
file3 | 8 ++++ ----
3 files changed, 10 insertions (+), 10 deletions (-)
Such a solution helped us get rid of the testers' questions “Well, have they already posted the fix for bug XXX?”, “What's new on the test server?”. Also, all team members, the implementation department and the management are aware of what is happening with the code on the servers.
For work, git, capistrano (+ multistage), php, bash (+ some console utilities) are used. If interested - go under the cat.
Work algorithm
- Updating the code on the testing server (cap testing deploy)
- After deploy: restart, a hook is created that creates a tag in the repository. The tag is formed on the basis of the project version (stored in the config, in the repository), the name of the staging server and the name of the release
- A hook is triggered in the repository. If the tag does not come, we ignore it; if the tag is:
- We saw it into components: version, server
- We determine the previous tag on the same server
- If there is no tag, then this is the first installation and it’s not worth generating differences, there may be several thousand commits
- If there is a tag, we generate a list of differences, pull out a list of tasks from them; make a list of modified files
- Sending a generated email
Tag creation
About the setting of capistrano and capistrano-multistage, it’s not already written anywhere, so I’ll just tell you how we add the tag.We assume that we have a configs.ini file in the root of the repository that contains the runtime.version key . The basis was taken gist # 381852 .
namespace :deploy do
...
after "deploy:restart", "deploy:git:push_deploy_tag"
namespace :git do
desc "Place release tag into Git and push it to server."
task :push_deploy_tag do
user = `git config --get user.name`.strip
email = `git config --get user.email`.strip
version = `git cat-file -p #{real_revision}:configs.ini | fgrep runtime.version | awk -F '[ =]+' '{print $2}'`.strip
puts `git tag v#{version}-#{stage}-#{release_name} #{real_revision} -m "Deployed by #{user} <#{email}>"`
puts `git push --tags`
end
end
end
What's going on here:
- We retrieve the current user data (name and mail) from the git config
- We take the configs.ini file from the installed revision and pull out the version
- Create an annotated tag. In the annotation we indicate who and when
- Publish tags
Processing repository update
The pre-receive hook receives 3 values at the input (stdin): previous and current revisions, refname.We read the incoming parameters and make sure that the tag has arrived:
while read oldrev newrev refname
do
rev_type=$(git cat-file -t $newrev 2>/dev/null)
case "$refname","$rev_type" in
refs/tags/*,tag)
...
;;
esac
done
Select the tag name, break it into pieces, look for the previous tag for this server:
tag=${refname##refs/tags/}
version=`echo $tag | cut -d- -f1`
server=`echo $tag | cut -d- -f2`
prevtag=$(git describe --tags --abbrev=0 --match="*-$server-*" $newrev^ 2>/dev/null)
If $ prevtag is empty, then this is the first installation on the server. If the version of the new and old tags matches, this is an update; if not, the installation of a new version. Thus, we generate the correct message header.
We begin to form the body of the letter. First, let's determine who dared to deploy:
eval $(git for-each-ref --shell --format='
tagger=%(taggername)
tagged=%(taggerdate)' $refname
)
echo "$tagger выложил следующие обновления на сервер '$server':" > msg
Now let's analyze task commits. The latter in Jira are named after the mask <project alias> -
git log $rev_range --abbrev-commit --pretty="format:%s" > tmpfile
php >tickets <
Если в итоге файл tmpfile не пуст — добавляем его к телу письма.
Дальше идёт информация, которая интересует только разработчиков проекта: списки коммитов и изменённых файлов:
echo "Полный список коммитов с предыдущего обновления:" >> msg
git log $rev_range --no-merges --abbrev-commit --pretty="format:%h %ad %an / %s" >> msg
echo -e "\n\nИзменения по файлам:" >>msg
git diff --stat=140,110 $rev_range >>msg
Ну и, наконец, тупая отправка письма:
cat msg | mail -s "$subject" $MAIL_TO
Все файлы можно взять на гитхабе: github.com/zvirusz/git-deploy-notify
P.S. Если кто-нибудь поможет переписать кусок кода, выдёргивающий имена задач, на perl/bash — я буду очень рад.