Tym razem w ramach rozwinięcia tematyki integracji SVN z systemem BugNET pokażę trochę bardziej zaawansowane rozwiązanie.
Integracja oparta jest o stabilną (nie beta i nie RC) wersję BugNET: 0.7.921. Niestety w tej wersji BugNet nie jest wyposażony w żadne mechanizmy (np. web-serwisy), które mogą zapewnić integrację (zgodnie z zapewnieniami autora BugNet jakieś web-serwisy pozwalające na integrację mają być dodane od wersji 0.8). Ten post proponuje, jaki web-serwis można dodać do BugNet by umożliwić integracje z SVN polegającą na automatycznym dodawaniu komentarza do problemu, po wykonaniu commit w subversion.
Informacja, którą chcemy umieścić jako komentarz w BugNet:
Nr rewizji
Autor
Data
Wiadomość danego commit’a
Lista katalogów w których nastąpiły zmiany
Konfiguracja i modyfikacja po stronie BugNET:
Dodajemy możliwość by BugNET miał web service obsługujący dodawanie komentarzy, czyli należy pobrać kod źródłowy, a następnie dodać następujące pliki do katalogu: BugNET-0.7.921\src\BugNET_WAP\Bugs:
CommentAdder.asmx
<%@ WebService Language="C#" CodeBehind="CommentAdder.asmx.cs" Class="BugNET.Bugs.CommentAdder" %>
CommentAdder.asmx.cs
using System; using System.Data; using System.Web; using System.Collections; using System.Web.Services; using System.Web.Services.Protocols; using System.ComponentModel; using BugNET.BusinessLogicLayer; namespace BugNET.Bugs { /// <summary> /// Summary description for CommentAdder /// </summary> [WebService(Namespace = "http://BugNetServer/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ToolboxItem(false)] public class CommentAdder : System.Web.Services.WebService { // Web Service method to add comment // bugid - issue identifier // comment - comment to be added // username - the name of the user that is adding the comment [WebMethod] public bool AddComment(int bugid, string comment, string username) { try { // creation of the new Comment object Comment newComment = new Comment(bugid, comment.Trim(), username); // it is time to save the comment newComment.Save(); return true; } catch { return false; } } } }
Otrzymujemy więc następujący serwis:
Konfiguracja i modyfikacja po stronie Subversion (SVN)
Po stronie Subversion trzeba stworzyć pewien skrypt/program, który zostanie wykonany po commit’cie (czyli należy dodać tzw. Post-commit Hook), można to zrobić wieloma sposobami, ja wykorzystam oprogramowanie Captain Hook for Subversion, by stworzyć (w C#) odpowiednią aplikację dodającą komentarz. W tym celu należy zaimplementować klasę dziedziczącą po: PostCommitHook
using System; using System.Collections.Generic; using System.Configuration; using System.IO; using System.Net.Mail; using System.Reflection; using System.Text; using System.Text.RegularExpressions; using CaptainHook.Subversion; using CaptainHook.Subversion.Hook; namespace Hook.Plugins { public class PostCommitBugnetLink: PostCommitHook { /// <summary> /// Handles the post commit hook by sending out an email. /// </summary> /// <param name="commitInfo">commit information prepared by Captain Hook</param> protected override bool HandleHookEvent( IRevisionInfo commitInfo ) { //creating a list of changed directories during commit: string[] changedDirectories = this.HostApplication.SubversionApplication.GetChangedDirectories( commitInfo.Revision ); string modifiedPaths = string.Empty; if ( changedDirectories != null && changedDirectories.Length > 0 ) { //each changed directory is in new line, separated by <br /> modifiedPaths = String.Join( Environment.NewLine + "<br/>", changedDirectories ); } // message to be stored as comment to particular issue string message = String.Format( "<p>Rev: <strong>{0}</strong>, author: <strong>{1}</strong> date:{2}</p>" + "<p>SVN log message:</p>" + "<p><span class=\"Code\">{3}</span></p>" + "<p>Modified paths:</p>" + "<p><span class=\"Code\">{4}</span></p>", commitInfo.Revision, commitInfo.Author, commitInfo.DateStamp, commitInfo.LogMessage.Replace(Environment.NewLine,Environment.NewLine+"<br/>"), modifiedPaths ); // comment should is added by particular use // in this example the user name is taken from application settings // the setting name is bugnet user string bugnetuser = ConfigurationManager.AppSettings[ "bugnetuser" ]; // if bugnetuser setting is empty or null (not set) we can utilise the "admin" user if ( String.IsNullOrEmpty( bugnetuser ) ) bugnetuser = "admin"; int bugid = 0; // now it is time to call BugNet web service to establish a connection BugNetLink.BugNETCommentAdder.CommentAdder remoteobj; try { remoteobj = new BugNetLink.BugNETCommentAdder.CommentAdder(); } catch ( Exception ex ) { System.Console.WriteLine( "Problem with creating remote object: " + ex.ToString() ); return false; } // now it is time to get a bug identifier (ID) from commit message. // to do it we have to get number after string "Issue #:" try { Regex pattern = new Regex( "Issue #: [0-9]+" ); string bugid_str = pattern.Match( commitInfo.LogMessage ).Value; pattern = new Regex( "[0-9]+" ); bugid_str = pattern.Match( bugid_str ).Value; bugid = System.Convert.ToInt32( bugid_str ); } catch { System.Console.WriteLine( "Bug ID not found" ); return false; } // if the issue idetifier is found we can call a web service and add a comment if ( bugid > 0 ) { try { return remoteobj.AddComment( bugid, message, bugnetuser ); } catch ( Exception ex ) { System.Console.WriteLine( "Problem with calling remote object: " + ex.ToString() ); } } return false;//PostCommit hooks ignore this anyways. } } }
Oczywiście należy pamiętać że wywołanie: BugNetLink.BugNETCommentAdder.CommentAdder, to odwołanie do referencji do serwisu CommentAdded.asmx (więc w projekcie w Visual Studio należy dodać odpowiednią referencję do web serwisu (przykład pokazujący jak to zrobić, choć dla innego web serwisu))
Konfiguracja po stronie repozytorium i TortoiseSVN:
Należy dodać odpowiednie właściwości tak jak to było opisane w poprzednim post’cie.
Podsumowanie
W niniejszym opisie wskazałem co należy zrobić, by informacja o wykonanym commit (w repozytorium) automatycznie była dodawana do informacji o pewnym problemie. Rozwiązanie te zdaje się być funkcjonalne, aczkolwiek można je pod paroma względami usprawnić i rozwiązać następujące problemy:
Trzeba ręcznie zmodyfikować kod BugNET (ma się to zmienić od nowej linii BugNet’a: 0.8)
Nie ma żadnego zabezpieczenia web serwisu,
Web serwis może się podszyć pod dowolnego użytkownika (być może jako nazwa użytkownika który dodaje komentarz, powinien być pobrana nazwa użytkownika wykonującego commit w SVN)
Commit’a można powiązać tylko z jednym "issue" (należałoby dać użytkownikowi możliwość wprowadzenia kilku numerów "issue” poprzez oddzielanie ich przecinkami
Opis problemu w komentarzu musi mieć konkretny format (np.: Issue #:1234) (ale w większości przypadków pilnuje tego TortoiseSVN
Doprawdy niezmiernie interesujący kod :)
OdpowiedzUsuń