Automatically updating Redmine from Rhodecode

For various reasons I'm switching my issue tracker from Mantis to Redmine. Redmine supports various Source Control Management systems (SCM), for Mercurial (my favourite one) they need access to a local copy of the repository, not an issue for me, but something to keep in mind.

Forward push to Redmine

After you activate the Mercurial in the general settings (/settings?tab=repositories), you need to activate the Fetch commits automatically and Enable WS for repository management
Then go to your Redmine project and open the settings\repositories page
Add a new repository and specify the details (note that you will need a local path.
Now for the Rhodecode side, we need a changegroup hook, you can add a local file on the server with the following contents (for Linux):
PROJECT="$(echo $PROJECT | tr '[A-Z]' '[a-z]')"
echo "Mercurial project: "$PROJECT
echo "Updating Changeset to Redmine Bug Tracker"
curl "http://REDMINESERVER/sys/fetch_changesets?key=$KEY&id=$PROJECT"&

Replace the REDMINESERVER with the actual webaddress of the Redmine server, and replace APIKEY with the key generated/shown by Redmine in the general settings page.

Make sure the local file is executable by the Rhodecode server user. Then switch to the Rhodecode Hooks page (/_admin/settings/hooks/edit), and add a changegroup.redmine hook and add the file location as the action:

Linking issues from commits

In the general Redmine Repositories settings page (/settings?tab=repositories) you can specify how Redmine should detect issue references from the commit message.
I have the following settings:
Be aware that Redmine expects a # in front of the issue number, so for referencing an issue you can use : ID #3. And for closing: fixes #45.

Now if you push your commit to Rhodecode, it will be forwarded to Redmine and linked to the correct issue, and show up in the tracker for that issue. If you want to track time used for the issue you can use the @ identifier followed by the amount of time use (see Redmine documentation)


Code Capture Tool Plugin Example

With the release of the Code Capture Tool v 3.2 (and up) plugins are supported in the Code Capture Tool (more details). A screencast on this process (with a demo plugin!) has been created (direct link): Unable to display content. Adobe Flash is required. Here's the Print plugin created.
Or a snippet created with the Imgur plugin:


Code Capture Tool Plugins - An introduction for developers

Plugin introduction

The Code Capture Tool 3.2 (CCT) introduces a new feature plugins. These plugins allows the user to store different info to the clipboard than the standard functions:
  • None
  • Image
  • File Path
A plugin functions as a post-capture hook, and allows you to take the stored image and alter the text of the code stored on the clipboard.


Included with the CCT 3.2 is an imgur plugin. This plugin is available if you have LabVIEW 2010 or greater, and returns a URL to a stored image on imgur.com. Imgur keeps the images online if they are viewed at least once every half year. (Thanks to Jordan Kuehn for supplying his code)


You can add your own plugins from the help window (in the plugins page), or via the context menu on the Clipboard listbox:
Plugin creation
This will open (after a confirmation dialog) a new VI from a template.


A plugin VI is created and opened. The plugin gets some parameters from the CCT when it's called:
Empty Plugin VI
  • Saved image path
    Path of the captured image file
  • FP Mode
    The capture mode of the frontpanel
  • BD Mode
    The capture mode of the block diagram
  • Snippet
    Whether this is a Snippet enabled image
  • Snippet Version
    The file version of the embedded snippet
  • Snippet Header
    Text of the snippet header
A plugin can use this information to take an action with this image. The plugin should return a Clipboard text, and a Success? status. If Success? is false the end user is informed that the plugin has failed.


To customize the text in the Clipboard listbox you should edit the Title of front panel, to give the end user more information about your plugin (in the Help dialog) the VI description is used together with the VI icon:
Plugin documentation
An end user can edit your VI directly from the Help dialog, consider locking the BD using a password if you want to prevent that.


If you want to distribute your plugins to different installation, you can choose two locations:
  • <vi.lib>\LAVA\_Code Capture Tool\Plugins
  • <LabVIEW Data>\CCT Plugins
Per default LabVIEW shares the second location between LabVIEW versions but not between users, while the first location is LabVIEW version specific, but shared between users.

If you use VIPM for creating a distributable plugin, you should use the first location (VIPM does not support LabVIEW data as a target).

Plugin inspiration

There are endless options with plugins how about this inspiration list:
  • Email image
  • Upload image to Facebook
  • Upload image to FTP
  • Add overlay to image 
  • Upload image to knowledge base
  • ......


Using Markdown to generate reports and documentation

Markdown is a hit on the internet. It's being supported by more and more platforms, it started for me with Stackoverflow and later on my favourite project hosting website (Bitbucket) made it their default Wiki markup language.

And I like Markdown, it's syntax is quite simple, you can read the document and get a feel for it's structure (emphasize, headings, lists) without a conversion to HTML. But it had a thing missing, a LabVIEW Markdown generator.
And it bugged me.
So I created a project (a while ago) in LabVIEW, and just the last week I took the time to finish the project.
It's now a Class that overrides the LabVIEW Report Generation VIs, you can use your existing 'write to HTML/DOC/XLS' code to write a Markdown report.

It's not a full override of the Report Generation toolkit VIs, some functionality is not available in Markdown (margins) or in the toolkit's generic VIs (headings).

You can download the package from Bitbucket, and file your feature requests or bugs there as well.

Now what to do with this tool?
Well I wrote a simple VI that took some pre-written Markdown, added information about the toolkit, and pushed the information into the Bitbucket wiki. So the documentation of the toolkit is using the toolkit.
A screenshot of this VI is this:
As you can see, the only special from a normal report is that we instantiate a Markdown class that we upcast to a generic Report class. And the we use normal report functions (add text, add image) to generate valid Markdown.
Sometimes it takes some tweaking to get the result you want, adding extra linefeeds after/before an image is sometimes necessary (and can vary depending on your MD to HTML converter).

Please spread the word about Markdown, and the report toolkit, post your findings here. Add feature requests and bugs to the Bitbucket repo.

PS Markdown even got a semi-official logo [M↓]

PPS The report generation VIs are a mess. Please NI start over from scratch.


Using private Rhodecode repositories with Mantis BT

As you know you can use Mantis BT and Rhodecode in conjunction to keep your issues and code connected. However this only worked if you opened up your Rhodecode repositories (either GIT or Mercurial) for everyone to read. With the latest version (0.3.1) of the Rhodecode Mantis connector you can use Rhodecode API keys to have an authenticated user get the information needed by Mantis.

Update 29-12-2012:
Version 1.5.0 of Rhodecode changes the Raw-Changeset page. For interaction with Rhodecode 1.5.x you need version 0.4.0 of the Mantis RhodeCode connector


  • Install the Source Integration plugin into Mantis,
  • To allow api access to private repositories you need to edit the Rhodecode source files.
  • Open the file changeset.py (Mine was located in /usr/local/lib/python2.7/dist-packages/RhodeCode-1.3.6-py2.7.egg/rhodecode/controllers/changeset.py)
  • Locate '@LoginRequired()' and replace it with '@LoginRequired(api_access=True)', save the file and restart Rhodecode
  • In Rhodecode allow a user to have read-only access to that repository (I added a Read-Only group with a Mantis user)
  • Go to the admin page for that user (via http://%rhodecode%/_admin/users) and note the api-key listed there
  • Install v 0.3.1 of the Rhodecode Mantis connector into Mantis
  • Open the Plugins configuration dialog for the plugin (via http://%mantis%/plugin.php?page=SourceRcWeb/config)

  • Insert the API key from Rhodecode into the API Key field
Now you can use the Repositories function for private repositories just like public repositories


LabVIEW, web services and optional inputs

LabVIEW has an import web services module for several versions, and it’s quite a useful tool.

After an import your WSDL specification (the web service) has been translated into a .net library, and an accompanying LabVIEW library with proxy support.

The tool is pretty good and straightforward, but lacks one little detail: support for optional input that aren’t arrays or strings.

Optional inputs in web services are sent as a NULL object via the XML data, but that’s not working for booleans, timestamps and numerics since these data types have a valid value that can be null. In the web service definition (WSDL) this is shown with the following XML:

<s:element name="GetGlobalTable">
<s:element minOccurs="1" maxOccurs="1" name="from" type="s:dateTime"/>
<s:element minOccurs="1" maxOccurs="1" name="to" nillable="true" type="s:dateTime"/>
<s:element minOccurs="1" maxOccurs="1" name="highImpactCount" nillable="true" type="s:int"/>
<s:element minOccurs="1" maxOccurs="1" name="trainPassageID" nillable="true" type="s:int"/>

Elements that are nullable (arrays and string) have a minOccurs value of 0, data types that aren’t nullable have a nillable=’true’ field in the definitions.

The code generated by the web service importer for these nillable datatypes isn’t working ‘out of the box’:


Since the properties are read-only we can only read the value but not update, however the Nullable class is correct, so we need to recreate these classes.

The fix is quite easy (once you’ve figured it out):


This is a snippet from a VI dedicated to generate a nullable I32. With a parameter we decide whether the object is NULL, if that’s the case we just output a constant NULL.

If the parameter isn’t optional we use the LabVIEW supplied ‘To .Net Object’ to generate a basic .NET object, that we upcast to a Nullable of the appropriate type. The output is feeded into the .Net method for getting data.

This method works the same for booleans and timestamps.


Connecting Mantis with Rhodecode

This how-to describes how I have setup Mantis and Rhodecode to communicate with each other.
Update (16-7-2011):
Version 0.3 of the Mantis plugin supports repository groups, introduced in RhodeCode 1.2
Update (03-09-2011): Adjusted hook in rhodecode from changegroup to incoming.
Adjustment (02-09-2012):
Version 0.3.1 support api-keys (more info)
Update (29-12-2012):
Version 1.5.0 of Rhodecode changes the Raw-Changeset page. For interaction with Rhodecode 1.5.x you need version 0.4.0 of the Mantis RhodeCode connector


Mantis Bug Tracker is a FOS (Free and Open Source) issue tracker widely used in the Open Source community running on PHP. John Reese has added a plugin category called Source Integration (source). This offers several integration advantages between your preferred Source Control solution (Git(hub), SVN) and Mantis.
With this integration you can connect a commit/checkin/push to a specific issue (bug, feature, task) so you can track those. Using special commit messages it’s possible to change the status of issues to resolved.


Rhodecode is a python-based local webservice for a set of Mercurial repositories built by Marcin Kuzminski. It has some nice features not found in the default Mercurial web-server:
  • Authentication based on LDAP
  • Private repositories
  • User-levels (admin, write, read, none)
  • Gravatar integration
Looking at the roadmap, Rhodecode wants to offer Git-hosting as well.
You can look at Rhodecode as a private/local Bitbucket version

Connecting Mantis with Rhodecode

The connection between Mantis and Rhodecode consist of two parts:

Mantis Source integration plugin

Prerequisite: Installed Source Integration plugins.
First part is an extension of the Source Integration plugin, you can download that from Bitbucket (version 0.2.1), extract this plugin and copy the SourceRcWeb directory into the Mantis BT plugins directory and log-in to Mantis.
When you open the Manage Plugins page (http://%yourmantisURL%/manage_plugin_page.php) you’ll see a Rhodecode plugin in the available plugins list:
Now click the Install link, and the plugins is installed.
Proceed by going to the RhodeCode plugin configuration page (http://%yourmantisURL%/plugin.php?page=SourceRcWeb/config):
This dialog allows you to set a default URL for your repositories, this can be overwritten per repository.

Installing Rhodecode hook

Prerequisite: Installed and working Rhodecode setup.
Rhodecode supports the same hooks as Mercurial, however there is currently (version 1.1.8) not an integrated Web-UI way to setup hooks.
To install the hook script (located in the root of the download) you’ll need to edit the SQLite database file used by Rhodecode (rhodecode.db by default).
I used SQLite Database browser, and edited the rhodecode_ui table and added a record with the following contents:
  • ui section: hooks
  • ui key: incoming.mantis
  • ui value: path of the changegroup file
The used incoming file is the hook script. Make sure the script is executable by the user running Rhodecode (eg: www-data).

Adjusting Rhodecode hook

The Rhodecode hook uses curl to call the webinterface of Mantis, you’ll need to adjust it to math your situation.
# Replace mantis with the URL of your actual mantis install
echo "Mercurial project: "$PROJECT
echo "Mercurial node: "${HG_NODE}
echo "Updating Changeset to Mantis Bug Tracker"
${CURL} -s -S -d "repo_name=${PROJECT}" -d "data=${HG_NODE}" ${URL}
Line 3 contains the URL of you the checkin php script, make sure this is adjusted and accessible from the Rhodecode server. If you are running version 0.16.3 of the Mantis plugin you’ll need to add an API-key to the curl command (info):
${CURL} -s -S -d "repo_name=${PROJECT}" -d "data=${HG_NODE}" -d "api_key=${API_KEY}" ${URL}
This hook is triggered every moment something is added to the repository and sends the information about the commit (project and commit-id) to Mantis.

Adding a repository to Mantis

Now everything is setup we’ll need to add the repository to Mantis.
There is one prerequisite to read the Rhodecode information, the repository needs to be readable by an anonymous user in Rhodecode, so you’ll need to configure Rhodecode to allow anonymous read for the given repository.
On the repositories page (http://%yourmantisURL%/plugin.php?page=Source/index), there is an option to add a Rhodecode repository.
Make sure the Name is exactly the name of your repository, after ‘Create Repository’ the following dialog opens.
The details from the generic configuration as well as the repository name are used to configure the repository. Per default there is no additional configuration necessary.
After this action you can use the Import Latest Data function to get all the information from Rhodecode:
After these actions you have all the information connected, you can browse in Mantis all your commits, their parents and connected issues.

Connecting a commit to an issue

Mantis filters the commit message to connect a commit to a specific issue.
Per default the following patterns are recognized:
  • issue #ddd
  • issues #ddd
  • bug #ddd
  • bugs #ddd
  • report #ddd
  • reports #ddd
To fix an issue the following patterns are accepted:
  • fixes #ddd
  • fixed #ddd
  • fix #ddd
  • resolved #ddd
  • resolves #ddd
ddd is the number of the issue, the hash (#) is mandatory. Look in the configuration of the Source Plugin to alter these patterns if you need that.


What happens if you push something into Rhodecode, the hook will be triggered and you’ll see in the feedback from Rhodecode what Mantis is doing:
remote: Mercurial project: test
remote: Mercurial node: fe7fbe7c8644a6ff20f0ddf773c6e19eee6bc7dd
remote: Updating Changeset to Mantis Bug Tracker
remote: <pre>Retrieving test from ... </pre>Retrieving fe7fbe7c8644a6ff20f0ddf7
73c6e19eee6bc7dd ... Processing fe7fbe7c8644a6ff20f0ddf773c6e19eee6bc7dd ... sav