📜 ⬆️ ⬇️

Git + TrackStudio - development automation

This is an article on how to use TrackStudio and Git to organize a convenient software development process. In the article considered a variant for OS Windows. But if you wish, it is not difficult to do everything for other OC.
For this we need:
  1. TrackStudio is a universal task management system.
  2. Git - VCS.
  3. Blat - Small (70kB) open source console program for Windows, which allows you to send e-Mail via SMTP protocol from the command line, with attached files.
  4. STunnel - A program that allows you to encrypt arbitrary TCP connections inside SSL. The tool is available for Unix and Windows.
    It is necessary if you use gmail.com as a mail service. Since blat cannot work directly with gmail.
Task:
Organize the workflow in such a way that when you commit to git, comments were automatically added to the TrackStudio task with different types of messages and the text of this comment was the text of the commit message.

Installation

TrackStudio

We do everything as it is written here.
Installation of all other applications is very simple, I note only one thing: blat should be put in the folder with git.exe (I have C: / Program files / Git / bin), or the folder in which blat is added to PATH.


Customization

TrackStudio

TrackStudio is able to pick up emails from emails and import them as tasks.
To configure this process, you need to set the mail collection parameters in the TS_HOME \ etc \ trackstudio.mail.properties file (if you do not have one):
mail.pop3.apop.enable=\ mail.store.forward=     email mail.store.fwdaddress=email      mail.store.host=pop  mail.store.password=  mail.store.port= mail.store.protocol= mail.store.user= , email,    trackstudio.emailSubmission=yes trackstudio.mailimport.interval=   
Here is an example for gmail.com:
 mail.pop3.apop.enable=\ mail.store.forward=yes mail.store.fwdaddress=mymail@gmail.com mail.store.host=pop.gmail.com mail.store.password=password mail.store.port=995 mail.store.protocol=pop3s mail.store.user=srvmail@gmail.com 
More details are described in the documentation .


Script to create an import rule

Now in TS, for an ancestor of each task with the category category “Change” or “Error”, it is necessary to create an import rule and it is desirable that they are created as administrator. But to do it every time, it is expensive with pens - we solve this problem by writing a plug-in. In the TS_HOME \ plugins \ scripts \ after_create_task folder (it contains scripts that are executed after creating tasks) create the file createRuleImport.bsh with the following code:
  1. / **
  2. * The script creates an import rule for the ancestor task when creating a child task.
  3. * /
  4. import com.trackstudio.app.adapter.AdapterManager;
  5. import com.trackstudio.exception.GranException;
  6. import com.trackstudio.secured. *;
  7. import com.trackstudio.securedkernel.SecuredMailImportAdapterManager;
  8. import com.trackstudio.securedkernel.SecuredStepAdapterManager;
  9. import java.util. *;
  10. import com.trackstudio.secured.SecuredUserBean;
  11. import com.trackstudio.app.session. *;
  12. import com.trackstudio.app.csv.CSVImport;
  13. try {
  14. // object for working with mail import rules
  15. SecuredMailImportAdapterManager mam = AdapterManager.getInstance ()
  16. .getSecuredMailImportAdapterManager ();
  17. // contains methods for working with message types
  18. SecuredStepAdapterManager sam = AdapterManager.getInstance ()
  19. .getSecuredStepAdapterManager ();
  20. // list of available message types for task and current user
  21. ArrayList arrMS = sam.getAvailableMstatusList (task.getSecure (), task.getId ());
  22. // type of message
  23. SecuredMstatusBean curMS = null ;
  24. String pefixStr = "new" ;
  25. / **
  26. * Check the type of category of the created task.
  27. * If the task category is “Error” = category name in TS
  28. * /
  29. if (task.getCategory (). getName (). equals ( "Error" ))
  30. pefixStr = "bug" ;
  31. / **
  32. * Generate a key for importing messages from the current task:
  33. * prefix + parent task number + # + task number
  34. * this key should be in the subject line
  35. * eg:
  36. * new759 # 2845 any text, anyway it will be ignored when adding a message.
  37. * /
  38. String mailimKey = pefixStr + task.getParent (). GetNumber () + "#" + task.getNumber ();
  39. / **
  40. * Do I need to create a rule.
  41. * Since an ancestor task can have several subtasks,
  42. * it is necessary to check the existence of the import rule,
  43. * so as not to produce them.
  44. * /
  45. boolean found = false ;
  46. for ( int i = 0; i <arrMS.size (); i ++) {
  47. curMS = (SecuredMstatusBean) arrMS.get (i);
  48. msn = curMS.getName ();
  49. // "Commentary" or "Comment" is the name of the message type
  50. if (msn.compareToIgnoreCase ( "Comment" ) == 0 || msn.compareToIgnoreCase ( "Comment" ) == 0) {
  51. // Get data by root user
  52. SecuredUserBean adminUser = new SecuredUserBean (CSVImport.findUserIdByLogin ( "root" ), sc);
  53. // Current user context
  54. SessionContext needSc = task.getSecure ();
  55. // check whether root has logged in
  56. if (SessionManager.getInstance (). existUserSession (adminUser.getUser ())) {
  57. for (SessionContext curSc: SessionManager.getInstance (). getSessions ()) {
  58. if (curSc.getUser (). getLogin (). equals ( "root" )) {
  59. // if yes then we get its context
  60. needSc = curSc;
  61. break ;
  62. }
  63. }
  64. }
  65. else {
  66. // if not, create its context
  67. needSc = SessionManager.getInstance (). getSessionContext (
  68. SessionManager.getInstance (). Create (adminUser.getUser ()));
  69. }
  70. if (! found)
  71. for (SecuredMailImportBean curMailS: mam.getAllAvailableMailImportList (needSc, task.getParentId ())) {
  72. // We are looking for the rule of importing new tasks from the ancestor.
  73. found = curMailS.getKeywords (). equals (pefixStr + task.getParent (). getNumber ());
  74. if (found)
  75. break ;
  76. }
  77. if (! found) {
  78. / **
  79. * if not found, then create a new import rule for the ancestor
  80. * as root, as TS supports the ability to create
  81. * users of individual rules for importing mail, you must
  82. * so that this rule could be seen by everyone.
  83. * /
  84. mam.createMailImport (needSc, pefixStr + task.getParent (). getNumber (),
  85. task.getParentId (), pefixStr + task.getParent (). getNumber (), 1, i,
  86. task.getCategoryId (), curMS.getId (), "" , true , false );
  87. found = true ;
  88. }
  89. }
  90. }
  91. // Add a value for the UDF field with the name "Branch name in git".
  92. AdapterManager.getInstance (). GetSecuredUDFAdapterManager (). SetTaskUDFValueSimple (
  93. task.getSecure (), task.getId (), “Branch Name in git” , mailimKey);
  94. }
  95. catch (GranException e) {
  96. throw new com.trackstudio.exception.UserMessageException (e.getMessage ());
  97. }
  98. return task;

The script has been created, now in TS we select in the menu “Task management -> Categories”,
first click on the category with the name "Change",

open the "Triggers" tab and in the "AFTER Trigger" list, mark the trigger, which is called createRuleImport.bsh .

Do the same for the category "Error".
')
If everything is done correctly, then when you create a new task, the Preda will have an import rule newNUMBER_PREACH or bugNUMP_REAL. When sending a letter to the email from which mail is imported, with the theme “newNUMBER_PREACH new task”, TS will create a task in the ANCIENT with a name that is equal to the subject of the letter. And if you send a letter in the subject, which is the key newNUMBER_BOOK # NUMBER_TASK (the task exists), TS imports the letter as comments to the task and the comment message will be the body of the letter. Moreover, if you attach a file to a letter, TS will attach it to the task.


How to add a UDF field

To do this, in TS top menu select “Task management -> Processes”, open the process of interest to you and in the “Additional fields” tab click on the “Line” button.

In the title, specify the name you need, in our case “Branch Name in git”, and click the Save button. But this is all just to copy and quickly paste into sh when creating a new branch in git, such as convenient.


Script for processing messages received via mail

TS already knows how to create messages from the “comments” type to the tasks from the letters.
Now we need to make TS change the message type to “Complete” or “Correct” for the category “Change” or “Error”, respectively (“Comments”, “Finish”, “Change” and “Error” - the names of the message type and categories , they depend on how you set up your workflow in TS; if you use the demo Russian database, they will be exactly like that). We need to create a script that will search in the message body, some sort of key, which will inform TS that it is necessary to change the type of message. I propose to use the [new_state = done] construct, but this is up to you. Create in the TS_HOME \ plugins \ scripts \ before_add_message folder , in which the scripts to be executed before adding the message are placed, changeType.bsh file with the code:
  1. / **
  2. * The script changes the type of the message being imported if it finds it in the message body.
  3. * construct [new_state = type], where type can be done or start
  4. * /
  5. import java.util. *;
  6. import java.util.regex. *;
  7. import java.io. *;
  8. try {
  9. if (message.description! = null )
  10. {
  11. String [] tempArr = null ;
  12. // Looking for the construction we need in the message
  13. String pattern = ". * \\ [(\\ w *) = (\\ w *) \\]. *" ;
  14. Pattern p = Pattern.compile (pattern, Pattern.MULTILINE);
  15. Matcher m = p.matcher (message.description);
  16. if (m.find ())
  17. tempArr = new String [] {m.group (1), m.group (2)};
  18. // whether the first parameter is scanned by the directive to change the type of message
  19. if (tempArr! = null && tempArr [0] .toLowerCase (). equals ( "new_state" )) {
  20. // determine what type to change the current message type
  21. if (tempArr [1] .toLowerCase (). equals ( "done" )) {
  22. // Remove the directive from the message
  23. message.description = message.description.replaceFirst ( "\\ [new_state = done \\]" , "" );
  24. // check which task belongs to
  25. if (message.getTask (). getCategory (). getName (). equals ( "Change" ))
  26. // set the new message type by its name
  27. message.setMstatus ( “Finish” );
  28. if (message.getTask (). getCategory (). getName (). equals ( "Error" ))
  29. message.setMstatus ( “Fix” );
  30. }
  31. if (tempArr [1] .toLowerCase (). equals ( "start" )) {
  32. message.description = message.description.replaceFirst ( "\\ [new_state = start \\]" , "" );
  33. if (message.getTask (). getCategory (). getName (). equals ( "Change" ) ||
  34. message.getTask (). getCategory (). getName (). equals ( “Error” ))
  35. message.setMstatus ( “Get started” );
  36. }
  37. }
  38. }
  39. }
  40. catch (Exception e) {
  41. throw new com.trackstudio.exception.UserMessageException (e.printStackTrace ());
  42. }
  43. return message;
The script has been created, now in TS we select in the menu “Task management -> Processes”, first click on the process with the name “Change”, then select the operation types tab and click on the operation with the name “Comment”

open the “Triggers” tab and in the “BEFORE Trigger” list, mark the trigger, which is called changeType.bsh .

We do the same for the “Error” process.

Like everything you can try.
Create a task -> copy from the field "Branch name in git" value ->

we create a letter with a topic into which we paste the copied value -> then in the body of the letter we write any text and add the directive [new_state = done].

In theory, after importing a letter for a task to change state, it should go to the state completed and the message body will be the message to this state.


Total

We have expanded TS abilities, now she can:

Stunnel

If you are not using gmail.com as your mail server, then skip this step!
In the folder where you installed stunnel find the file stunnle.conf (C: \ Program Files \ stunnel \ stunnel.conf). We change its contents to the following:
 socket = l:TCP_NODELAY=1 socket = r:TCP_NODELAY=1 debug = 7 output = stunnel.log client = yes [ssmtp] accept = 127.0.0.1:465 connect = smtp.gmail.com:465 
And in order for stunnel to start as a service, we automatically execute on the command line:
"C: \ Program Files \ stunnel \ stunnel.exe" –install
source: Sending letters from the Windows command line using a GMail account


Git

Everything related to TS was performed on the server side. And now all the settings will be at a specific workplace.
In order to configure the git behavior when committing a commit, we need to change 2 hooks first post-commit and prepare-commit-msg , the first is executed at the time of the commit, the second when the commit message is generated. The hook files are in the DIR_YOUR_REPO / .git / hooks directory.These files should lie with all programmers working on the project.


How it works

Most importantly, when starting work on a new task, it is necessary in the operational repository of the current programmer to create a branch with the name that TS created when creating the task.
The prepare-commit-msg hook inserts in the beginning of the commit message the parameters for sending a letter, such as:The post-commit hook checks the commit message for sending options. creates a patch file with the changes made and a letter, then sends a letter on behalf of the committer to the email specified in the “to” parameter. Here's an example of applying the changes:
Enter in the command line
$ git add --all & git gui


Then press Ctrl + Enter and at the interval that you set the mail collector in TS, check the status of the task.

Here the comment is decorated with html, but this is a topic for a separate post.

Conclusion

A standard workflow consists of 4 main steps:
  1. Setting a task in TS and copying the branch name for git.
  2. Creating a branch in git and going to it.
    You can execute one command:
    $ git checkout -b _
  3. Doing the task.
  4. Completion of work on a task in TS, committing a commit in git.
Step 3 can be extended by intermediate commits in the message, which will not be a directive [new_state = done] - TS will add comments to the task.


Why use just such a mechanism

The reason is that TS does not yet have integration with SCM GIT.
And when to appear, it is not clear how the work with distributed repositories will be implemented.
And this solution allows you to work on a task for several programmers who have their own zoo repositories. And then combine them into one central, in which order and cleanliness.
In addition, it is very convenient to work without having direct access to TS.
A project manager can create tasks and assign specific people to them as responsible. They will receive emails stating that a task has been created or that he has been appointed responsible. He sees in the message of the letter what task is set and the name of the branch for git, begins work on the task. At the end of the work, it quietly makes a commit in the repository and may no longer worry that the task should be completed. Moreover, he can also remotely create subtasks knowing the key of the ancestor's task by sending emails from which mail is imported into TS with the subject in which the required key is present. In response, they will also receive letters that he has created a task.

Sources

Source: https://habr.com/ru/post/113554/


All Articles