ciabot/INSTALL | 6 ciabot/README | 21 ++ ciabot/config.pl.sample | 11 + ciabot/libreoffice-bugzilla.pl | 243 ++++++++++++++++++++++++++++++++ ciabot/libreoffice-ciabot.pl | 290 +++++++++++++++++++++++++++++++++++++++ ciabot/projmap.json | 7 ciabot/run-libreoffice-ciabot.pl | 169 ++++++++++++++++++++++ ciabot/start-ciabot.sh | 5 ciabot/start-irker.sh | 7 irker-cia-proxy/projmap.json | 7 10 files changed, 759 insertions(+), 7 deletions(-)
New commits: commit c016e9de03ac9689874d208320d32049aeb47a17 Author: Miklos Vajna <[email protected]> Date: Sat Apr 13 16:22:55 2013 +0200 ciabot: add install instructions Change-Id: Iefe25cf7d51cda4f2603cd4b64ad29b77a674212 diff --git a/ciabot/INSTALL b/ciabot/INSTALL new file mode 100644 index 0000000..9684999 --- /dev/null +++ b/ciabot/INSTALL @@ -0,0 +1,6 @@ +The following steps are needed to use this code: + +- have this directory as ~/bin +- git clone git://gitorious.org/irker/irker.git ~/bin/irker +- git clone git://github.com/nenolod/irker-cia-proxy.git ~/bin/irker-cia-proxy +- cd ~/bin/irker-cia-proxy; ln -s ../projmap.json commit 3bee50d9f64bb91aaa7359c400d617a9ac9bb77f Author: Miklos Vajna <[email protected]> Date: Sat Apr 13 16:19:09 2013 +0200 Import the irc / bugzilla notification code. Authors: 23 Jan Holesovsky 10 Markus Mohrhard 9 Miklos Vajna Change-Id: I946d7b85031b0f8ebb187737926174b592ba1610 diff --git a/ciabot/README b/ciabot/README new file mode 100644 index 0000000..db6ce0d --- /dev/null +++ b/ciabot/README @@ -0,0 +1,21 @@ +How the IRC nofication part works: + +1) After a reboot, start-irker.sh and start-ciabot.sh has to be started +manually. The first starts irkerd, which -- in case of no errors -- has no +output. The second starts run-libreoffice-ciabot.pl in screen. + +2) run-libreoffice-ciabot.pl invokes libreoffice-ciabot.pl for each commit, which +has an XML output, piped into irker-cia-proxy.py, which sends the info to +irkerd. + +How to test the IRC notification part: + +1) Take the IRC bot "offline", by editing ~/bin/irker-cia-proxy/projmap.json, +e.g. redirect the channel from #libreoffice-dev to some test channel. + +2) Run: + +cd ~/libreoffice/core +perl ~/bin/libreoffice-ciabot.pl core f9453275d2710f9d3e9a4cc1285a57db334a5e2e | (cd ~/bin/irker-cia-proxy; python irker-cia-proxy.py -s) + +3) Once you're happy with the result, change projmap.json back. diff --git a/ciabot/config.pl.sample b/ciabot/config.pl.sample new file mode 100644 index 0000000..87f8edb --- /dev/null +++ b/ciabot/config.pl.sample @@ -0,0 +1,11 @@ +#!/usr/bin/perl -w + +use strict; + +# The bugzilla has contains the server, username and password for the targeted +# bugzilla installation. There's NO 'http://' in the server line. +our $bugzilla = { + server => 'bugs.freedesktop.org/', + user => '[email protected]', + password => 'secret', # CHANGE THIS! +}; diff --git a/ciabot/libreoffice-bugzilla.pl b/ciabot/libreoffice-bugzilla.pl new file mode 100755 index 0000000..560b6bf --- /dev/null +++ b/ciabot/libreoffice-bugzilla.pl @@ -0,0 +1,243 @@ +#!/usr/bin/perl -w + +use strict; + +# A hook script which integrates with bugzilla. It looks for bug IDs in +# commit messages and adds the commit message as well as a link to the +# changeset as a comment on the bug. + +# This program is released under the terms of the GNU General Public License +# version 2. A copy of the license may be obtained by emailing the author, +# or at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt +# +# The absolute lack of warranty and other disclaimers as per the license +# apply. +# +# Copyright 2008, Devendra Gera. All rights reserved. +# +# Author : Devendra Gera + +### user configurable section + +our $bugzilla = {}; + +do $ENV{'HOME'} . "/bin/config.pl"; + +# The bug_regex should extract the bug id from the commit message and place +# it in $1 +my $bug_regex = 'fdo#(\d+)'; + +# This contains the target version for all commits to master +# Adjust it if a new version branch has been created +my $master_target = '4.1.0'; + + +##### End user configurable section + +use vars qw ($tree @parent $author $committer); +use vars qw ($user $rev $logmsg); + +my $repo = $ARGV[0]; +my $sha = $ARGV[1]; +my $branch = $ARGV[2]; + +use WWW::Bugzilla; + +my $cgiturl = "http://cgit.freedesktop.org/libreoffice/$repo/commit/?id=$sha"; +my $next_version = ''; +my $target_version = ''; +my $target = 'target:'; + +if ( !defined( $branch ) || $branch eq '' ) +{ + $branch = "master"; + $target .= $master_target; +} +else +{ + $cgiturl .= "&h=$branch"; + + # the fix will be available in the first version that branches from this + if ( $branch =~ /libreoffice-([0-9]+)-([0-9]+)-([0-9]+)\b/ ) { + $next_version = "\nIt will be available already in LibreOffice $1.$2.$3."; + $target .= "$1.$2.$3"; + } + elsif ( $branch =~ /libreoffice-([0-9]+)-([0-9]+)\b/ ) { + $next_version = "\nIt will be available in LibreOffice $1.$2."; + my $next = -1; + $target .= "$1.$2."; + open BRANCHES, "git branch -r |" or die "cannot get the list of branches"; + while (defined (my $remote = <BRANCHES>)) { + if ( $remote =~ /$branch-([0-9]+)/ ) { + if ( $1 > $next ) { + $next = $1; + } + } + } + close BRANCHES; + if( $next == -1 ) { + my $tags = "libreoffice-"."$1.$2.0.*"; + open TAGS, "git tag -l $tags |" or die "cannot get the tags"; + my $beta = -1; + my $RC = 0; + while (defined (my $tag = <TAGS>)) { + if( $tag =~ /libreoffice-([0-9]+)\.([0-9]+)\.0\.0\.beta([0-9]+)/) { + if( $3 > $beta ) { + $beta = $3; + } + } + if( $tag =~ /libreoffice-([0-9]+)\.([0-9]+)\.0\.([1-9]+)/ ) { + if ( $3 > $RC ) { + $RC = $3; + } + } + } + + if( $beta == 2 || $RC > 0) { + $target = "target:$1.$2.0."; + $target .= $RC + 1; + } + else { + $target = "target:$1.$2.0.0.beta"; + $target .= $beta +1; + } + + } + else { + $next_version .= $next + 1 . "."; + $target .= $next + 1; + } + } + else { +# don't update bugzilla for feature branches + exit; + } +} + +my $line; + +open COMMIT, "git cat-file commit $sha|" or die "git cat-file commit $sha: $!"; +my $state = 0; +$logmsg = ''; +while (defined ($line = <COMMIT>)) { + if ($state == 1) { + $logmsg .= $line; + $state++; + next; + } elsif ($state > 1) { + next; + } + + chomp $line; + unless ($line) { + $state = 1; + next; + } + + my ($key, $value) = split(/ /, $line, 2); + if ($key eq 'tree') { + $tree = $value; + } elsif ($key eq 'parent') { + push(@parent, $value); + } elsif ($key eq 'author') { + $author = $value; + $author =~ s/ <.*//; + } elsif ($key eq 'committer') { + $committer = $value; + $committer =~ s/ <.*//; + } +} +close COMMIT; + +my ($bugNr) = ( $logmsg =~ /$bug_regex/ ); + +die "no bug number in the commit" unless defined $bugNr; + +my $comment = <<END_COMMENT; +$author committed a patch related to this issue. +It has been pushed to "$branch": + +$cgiturl + +$logmsg +$next_version + +The patch should be included in the daily builds available at +http://dev-builds.libreoffice.org/daily/ in the next 24-48 hours. More +information about daily builds can be found at: +http://wiki.documentfoundation.org/Testing_Daily_Builds +Affected users are encouraged to test the fix and report feedback. +END_COMMENT + +# sanitize the comment - we are not handling utf-8 correctly from some reason +for ( $comment ) { + s/á/a/g; + s/Ã/A/g; + s/é/e/g; + s/Ä/e/g; + s/Ã/E/g; + s/Ä/E/g; + s/Ã/i/g; + s/Ã/I/g; + s/ó/o/g; + s/Ã/O/g; + s/ú/u/g; + s/ů/ů/g; + s/Ã/U/g; + s/Å®/U/g; + s/ý/y/g; + s/Ã/Y/g; +} + +#commit the comment to bugzilla +my $bz = WWW::Bugzilla->new( + server => $bugzilla->{ server }, + email => $bugzilla->{ user }, + password => $bugzilla->{ password }, + bug_number => $bugNr + ); + +die "cannot connect to bugzilla" unless defined $bz; + +my $product = $bz->product; + +die "wrong product" unless $product eq 'LibreOffice'; + +my $whiteboard = $bz->status_whiteboard(); + +if ( !defined( $whiteboard ) || $whiteboard eq '' ) +{ + $whiteboard = $target; +} +elsif ( $target =~ /([0-9]+)\.([0-9]+)\.([0-9]+)/ ) +{ + my ( $major, $minor, $micro ) = ( $1, $2, $3 ); + + # check that we only get one entry of the form target:$1.$2 even + # if pushed to libreoffice-$1-$2 and libreoffice-$1-$2-$3 + if ( $whiteboard =~ /target:$major\.$minor\.([0-9]+)/ ) + { + if ( $micro < $1 ) + { + $whiteboard =~ s/target:$major\.$minor\.$1/$target/; + } + } + else + { + $whiteboard .= ' ' . $target; + } +} +else +{ + if( $whiteboard =~ $target ) { + } + else { + $whiteboard .= ' ' . $target; + } +} + +$bz->status_whiteboard($whiteboard); + +$bz->additional_comments( $comment ); + +$bz->commit; diff --git a/ciabot/libreoffice-ciabot.pl b/ciabot/libreoffice-ciabot.pl new file mode 100755 index 0000000..d2d0144 --- /dev/null +++ b/ciabot/libreoffice-ciabot.pl @@ -0,0 +1,290 @@ +#!/usr/bin/perl -w +# +# ciabot -- Mail a git log message to a given address, for the purposes of CIA +# +# Loosely based on cvslog by Russ Allbery <[email protected]> +# Copyright 1998 Board of Trustees, Leland Stanford Jr. University +# +# Copyright 2001, 2003, 2004, 2005 Petr Baudis <[email protected]> +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License version 2, as published by the +# Free Software Foundation. +# +# The master location of this file is in the Cogito repository +# (see http://www.kernel.org/git/). +# +# This program is designed to run as the .git/hooks/post-commit hook. It takes +# the commit information, massages it and mails it to the address given below. +# +# The calling convention of the post-commit hook is: +# +# .git/hooks/post-commit $commit_sha1 $branch_name +# +# If it does not work, try to disable $xml_rpc in the configuration section +# below. Also, remember to make the hook file executable. +# +# +# Note that you can (and it might be actually more desirable) also use this +# script as the GIT update hook: +# +# refname=${1#refs/heads/} +# [ "$refname" = "master" ] && refname= +# oldhead=$2 +# newhead=$3 +# for merged in $(git rev-list $newhead ^$oldhead | tac); do +# /path/to/ciabot.pl $merged $refname +# done +# +# This is useful when you use a remote repository that you only push to. The +# update hook will be triggered each time you push into that repository, and +# the pushed commits will be reported through CIA. + +use strict; +use vars qw ($project $from_email $dest_email $noisy $rpc_uri $mail + $xml_rpc $irker $ignore_regexp $alt_local_message_target); + + + + +### Configuration + +# Project name (as known to CIA). +$project = 'LibreOffice'; + +# The from address in generated mails. +$from_email = '[email protected]'; + +# Mail all reports to this address. +#$dest_email = '[email protected]'; +$dest_email = '[email protected]'; + +# If using XML-RPC, connect to this URI. +$rpc_uri = 'http://cia.vc/RPC2'; + +# The 'mail' program setup +$mail = 'mail'; + +# If set, the script will send CIA the full commit message. If unset, only the +# first line of the commit message will be sent. +$noisy = 0; + +# This script can communicate with CIA either by mail or by an XML-RPC +# interface. The XML-RPC interface is faster and more efficient, however you +# need to have RPC::XML perl module installed, and some large CVS hosting sites +# (like Savannah or Sourceforge) might not allow outgoing HTTP connections +# while they allow outgoing mail. Also, this script will hang and eventually +# not deliver the event at all if CIA server happens to be down, which is +# unfortunately not an uncommon condition. +$xml_rpc = 1; + +$irker = 1; + +# This variable should contain a regexp, against which each file will be +# checked, and if the regexp is matched, the file is ignored. This can be +# useful if you do not want auto-updated files, such as e.g. ChangeLog, to +# appear via CIA. +# +# The following example will make the script ignore all changes in two specific +# files in two different modules, and everything concerning module 'admin': +# +# $ignore_regexp = "^(gentoo/Manifest|elinks/src/bfu/inphist.c|admin/)"; +$ignore_regexp = ""; + +# It can be useful to also grab the generated XML message by some other +# programs and e.g. autogenerate some content based on it. Here you can specify +# a file to which it will be appended. +$alt_local_message_target = ""; + + + + +### The code itself + +use vars qw ($commit $tree @parent $author $committer); +use vars qw ($user $repo $branch $rev @files $logmsg $message); +my $line; + + + +### Input data loading + + +# The commit stuff +$repo = $ARGV[0]; +$commit = $ARGV[1]; +$branch = $ARGV[2]; + +open COMMIT, "git cat-file commit $commit|" or die "git cat-file commit $commit: $!"; +my $state = 0; +$logmsg = ''; +while (defined ($line = <COMMIT>)) { + if ($state == 1) { + $logmsg .= $line; + $noisy or $state++; + next; + } elsif ($state > 1) { + next; + } + + chomp $line; + unless ($line) { + $state = 1; + next; + } + + my ($key, $value) = split(/ /, $line, 2); + if ($key eq 'tree') { + $tree = $value; + } elsif ($key eq 'parent') { + push(@parent, $value); + } elsif ($key eq 'author') { + $author = $value; + } elsif ($key eq 'committer') { + $committer = $value; + } +} +close COMMIT; + + +open DIFF, "git diff-tree -r $parent[0] $tree|" or die "git diff-tree $parent[0] $tree: $!"; +while (defined ($line = <DIFF>)) { + chomp $line; + my @f; + (undef, @f) = split(/\t/, $line, 2); + push (@files, @f); +} +close DIFF; + + +# Figure out who is doing the update. +# XXX: Too trivial this way? +($user) = $author =~ /<(.*?)@/; + + +$rev = substr($commit, 0, 12); + + + + +### Remove to-be-ignored files + +@files = grep { $_ !~ m/$ignore_regexp/; } @files + if ($ignore_regexp); +exit unless @files; + + + +### Compose the mail message + + +my ($VERSION) = '1.0'; +#my $ts = time; +my $ts = time - 7*60*60; # Have to post it in cia.vc's local time ;-) + +$message = <<EM +<message> + <generator> + <name>CIA Perl client for Git</name> + <version>$VERSION</version> + </generator> + <source> + <project>$project</project> + <module>$repo</module> +EM +; +$message .= " <branch>$branch</branch>" if ($branch); +$message .= <<EM + </source> + <timestamp> + $ts + </timestamp> + <body> + <commit> + <author>$user</author> + <revision>$rev</revision> + <files> +EM +; + +foreach (@files) { + s/&/&/g; + s/</</g; + s/>/>/g; + $message .= " <file>$_</file>\n"; +} + +$logmsg =~ s/&/&/g; +$logmsg =~ s/</</g; +$logmsg =~ s/>/>/g; + +$message .= <<EM + </files> + <log> +$logmsg + </log> + </commit> + </body> +</message> +EM +; + + + +### Write the message to an alt-target + +if ($alt_local_message_target and open (ALT, ">>$alt_local_message_target")) { + print ALT $message; + close ALT; +} + + +### Send out to irker + +if ($irker) { + print $message; + exit; +} + + +### Send out the XML-RPC message + + +if ($xml_rpc) { + # We gotta be careful from now on. We silence all the warnings because + # RPC::XML code is crappy and works with undefs etc. + $^W = 0; + $RPC::XML::ERROR if (0); # silence perl's compile-time warning + + require RPC::XML; + require RPC::XML::Client; + + my $rpc_client = new RPC::XML::Client $rpc_uri; + my $rpc_request = RPC::XML::request->new('hub.deliver', $message); + my $rpc_response = $rpc_client->send_request($rpc_request); + + unless (ref $rpc_response) { + die "XML-RPC Error: $RPC::XML::ERROR\n"; + } + exit; +} + + + +### Send out the mail + + +# Open our mail program + +open (MAIL, "| $mail -r $from_email -s DeliverXML $dest_email") or die "Cannot execute $mail : " . ($?>>8); + + +print MAIL $message; + + +# Close the mail + +close MAIL; +die "$0: mail exit status " . ($? >> 8) . "\n" unless ($? == 0); + +# vi: set sw=2: diff --git a/ciabot/projmap.json b/ciabot/projmap.json new file mode 100644 index 0000000..4e53010 --- /dev/null +++ b/ciabot/projmap.json @@ -0,0 +1,7 @@ +{ + "LibreOffice": { + "template": "%(project)s (%(module)s) [%(branch)s] %(author)s * %(files)s: %(log)s", + "template-None": "%(project)s (%(module)s) %(author)s * %(files)s: %(log)s", + "to": "irc://irc.freenode.net/#libreoffice-dev" + } +} diff --git a/ciabot/run-libreoffice-ciabot.pl b/ciabot/run-libreoffice-ciabot.pl new file mode 100755 index 0000000..b7173b5 --- /dev/null +++ b/ciabot/run-libreoffice-ciabot.pl @@ -0,0 +1,169 @@ +#!/usr/bin/perl -w + +use POSIX; + +if ( ! -d 'core' ) { + print STDERR "Not a directory with libreoffice repos!\n"; + exit 1; +} + +sub error($) { + my ( $message ) = @_; + print STDERR "$message\n"; +} + +sub get_branches() { + my %branches; + if ( open REFS, "git show-ref |" ) { + while ( <REFS> ) { + chomp; + if ( /^([^ ]*) refs\/remotes\/origin\/(.*)/ ) { + if ( $2 ne 'HEAD' ) { + $branches{$2} = $1; + } + } + } + close REFS; + } + else { + error( "Cannot call git show-ref." ); + } + + return \%branches; +} + +sub timestamp() { + return strftime("[%Y-%m-%d %H:%M:%S]", localtime); +} + +sub report($$$) { + my ( $repo, $old_ref, $new_ref ) = @_; + my %old = %{$old_ref}; + my %new = %{$new_ref}; + my $ciabot = "timeout 60 libreoffice-ciabot.pl"; + my $ciaproxy = "| ( cd ~/bin/irker-cia-proxy/; python irker-cia-proxy.py -s )"; + + foreach my $key ( keys %new ) { + my $branch_name = $key; + $branch_name = '' if ( $branch_name eq 'master' ); + if ($branch_name =~ /aoo\//) { + next; + } + + my $old_head = $old{$key}; + my $new_head = $new{$key}; + + if ( defined( $old_head ) ) { + if ( $old_head ne $new_head ) { + my $ret = system("git rev-parse -q --verify $new_head^2 >/dev/null"); + if ($ret != 0) { + # not a merge commit, announce every commit + + # limit the number of commits we report + my $limit = 25; + if ( `git rev-list $new_head ^$old_head | wc -l` > 25 ) { + # something is wrong - probably a big rebase, + # or something, report just 1 commit + $limit = 1; + } + if ( open COMMITS, "git rev-list -n $limit $new_head ^$old_head | tac |" ) { + while ( <COMMITS> ) { + chomp; + print timestamp() . " Sending report about $_ in $key\n"; + if (!$test) { + qx($ciabot $repo $_ $branch_name $ciaproxy); + qx(perl -I ~/bin ~/bin/libreoffice-bugzilla.pl $repo $_ $branch_name); + } else { + print "$ciabot '$repo' '$_' '$branch_name' $ciaproxy\n"; + print "perl -I ~/bin ~/bin/libreoffice-bugzilla.pl '$repo' '$_' '$branch_name'\n"; + } + } + close COMMITS; + } + else { + error( "Cannot call git rev-list." ); + } + } else { + # just process the merge commit itself + print timestamp() . " Sending report about $new_head in $key\n"; + if (!$test) { + qx($ciabot $repo $new_head $branch_name $ciaproxy); + # no libreoffice-bugzilla.pl call for the merge commit + } else { + print "$ciabot '$repo' '$new_head' '$branch_name' $ciaproxy\n"; + } + } + } + } + else { + # Report the newest commit which is not in master + if ( open COMMITS, "git rev-list -n 1 $new_head ^refs/remotes/origin/master |" ) { + while ( <COMMITS> ) { + chomp; + print timestamp() . " Sending report about $_ in $key (newly created branch)\n"; + if (!$test) { + qx($ciabot $repo $_ $branch_name $ciaproxy); + # no libreoffice-bugzilla.pl call for newly created branch + } else { + print "$ciabot '$repo' '$_' '$branch_name' $ciaproxy\n"; + } + } + close COMMITS; + } + else { + error( "Cannot call git rev-list." ); + } + } + } +} + +print timestamp() . " Checking for changes in the libreoffice repo & sending reports to CIA.vc.\n"; + +@all_repos = ( + "binfilter", + "core", + "dictionaries", + "help", +); + +$test = 0; + +if ($test) { + @all_repos = ("test"); +} + +chomp( my $cwd = `pwd` ); + +my %old_ref; +foreach $repo (@all_repos) { + chdir "$cwd/$repo"; + qx(git fetch origin); + qx(git fetch --tags origin); + $old_ref{$repo} = get_branches(); +} + +while ( 1 ) { + foreach $repo (@all_repos) { + chdir "$cwd/$repo"; + + # update + qx(git fetch origin); + qx(git fetch --tags origin); + my $new_ref = get_branches(); + + # report + report( $repo, $old_ref{$repo}, $new_ref ); + $old_ref{$repo} = $new_ref; + } + + if (!$test) { + # check every 5 minutes + print timestamp() . " Sleeping for 5 minutes...\n"; + sleep 5*60; + } else { + print "Hit enter to report...\n"; + <STDIN>; + } +} + +# vim:set shiftwidth=4 softtabstop=4 expandtab: diff --git a/ciabot/start-ciabot.sh b/ciabot/start-ciabot.sh new file mode 100755 index 0000000..77c7da0 --- /dev/null +++ b/ciabot/start-ciabot.sh @@ -0,0 +1,5 @@ +#! /bin/bash + +cd ~/libreoffice + +test -n "`ps ax | grep run-libreoffice-ciabot.pl | grep -v grep`" || screen -d -m run-libreoffice-ciabot.pl diff --git a/ciabot/start-irker.sh b/ciabot/start-irker.sh new file mode 100755 index 0000000..ee09b53 --- /dev/null +++ b/ciabot/start-irker.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +cd ~/bin/irker +export PYTHONPATH=irc-8.0.1 +if test -z "`ps ax | grep irkerd | grep -v grep`"; then + ./irkerd &>irkerd.log & +fi diff --git a/irker-cia-proxy/projmap.json b/irker-cia-proxy/projmap.json deleted file mode 100644 index 4e53010..0000000 --- a/irker-cia-proxy/projmap.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "LibreOffice": { - "template": "%(project)s (%(module)s) [%(branch)s] %(author)s * %(files)s: %(log)s", - "template-None": "%(project)s (%(module)s) %(author)s * %(files)s: %(log)s", - "to": "irc://irc.freenode.net/#libreoffice-dev" - } -}
_______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
