diff --git a/buildVersion.py b/buildVersion.py
new file mode 100755
index 0000000000000000000000000000000000000000..5fd5531d144efcc15aa3cf61584429ecf75d075d
--- /dev/null
+++ b/buildVersion.py
@@ -0,0 +1,249 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+""" 
+   NAME
+          buildVersion -- helper script to build and tag a plugin_dbui version
+
+    SYNOPSIS
+          buildVersion [options] version
+
+    DESCRIPTION
+          Helper script to build a version of the plugin_dbui.
+          
+          The version identifier should contains alphanumeric characters 
+          including ".", "-" and "_".
+          
+          Push version identifier in the javascript library.
+          Push version number in the CHANGELOG.
+          Build debug and minified version of the javascript library.
+          Commit the new version in git and tag it
+          Build the web2py plugin file
+
+    OPTIONS
+
+          --help, -h
+                print a short help file.
+
+          -n
+              dry run
+              
+    EXAMPLES
+
+            > buildVersion
+            > buildVersion 0.4.3
+
+    AUTHOR
+          R. Le Gac, renaud.legac@free.fr
+
+"""
+
+import optparse
+import os
+import re
+import subprocess
+import sys
+import urllib2
+
+from datetime import datetime
+
+print 'start buildVersion'
+#-----------------------------------------------------------------------------
+APP = 'mygit_dbui_04x'
+CHANGELOG = 'static/plugin_dbui/CHANGELOG'
+JSBASE = 'static/plugin_dbui/src/appbase.js'
+JSLIBDEBUG = 'static/plugin_dbui/dbui-debug.js'
+JSLIBMIN = 'static/plugin_dbui/dbui-min.js'
+JSLIBSRC = 'static/plugin_dbui/src'
+PACK_PLUGIN_URL = 'http://localhost:8000/admin/default/pack_plugin/%s/dbui' % APP
+#-----------------------------------------------------------------------------
+#    define main applications
+#
+GIT = '/usr/bin/git'
+
+VERSION = '2.4.6'
+SRC_PATH = "$HOME/lib/yuicompressor-%s/build/yuicompressor-%s.jar"
+YUICOMPRESSOR = os.path.expandvars(SRC_PATH %(VERSION, VERSION))
+
+WEB2PY = os.path.expandvars('$HOME/myweb/web2py/web2py.py')
+
+if not os.path.exists(GIT):
+    print '\n\tgit application is missing !'
+    sys.exit(1)
+    
+if not os.path.exists(YUICOMPRESSOR):
+    print '\n\tYUiCompressor application is missing !'
+    sys.exit(1)
+
+if not os.path.exists(WEB2PY):
+    print '\n\tweb2py application is missing !'
+    sys.exit(1)
+    
+#-----------------------------------------------------------------------------
+#     setup and parse script options
+#
+ops = optparse.OptionParser()
+
+ops.add_option("-c", "--clean",
+               action="store_true",
+               dest= "clean",
+               help= "clean build files and exit.")
+
+ops.add_option("-g", "--git",
+               action="store_true",
+               dest= "git",
+               help= "run the git steps.")
+
+ops.add_option("-n", "--dry-run",
+               action="store_false",
+               dest= "run",
+               help= "dry run, no files modification, no commit, no tag.")
+
+ops.add_option("-u", "--update",
+               action="store_true",
+               dest= "update",
+               help= "run the update version step.")
+
+ops.add_option("-y", "--yuicompressor",
+               action="store_true",
+               dest= "yuicompressor",
+               help= "run the yuicompressor step.")
+
+ops.add_option("-w", "--web2py",
+               action="store_true",
+               dest= "web2py",
+               help= "run the web2py step.")
+
+ops.set_defaults(clean=False,
+                 git=False,
+                 run=True,
+                 update=False,
+                 yuicompressor=False,
+                 web2py=False)
+
+(opt, args) = ops.parse_args()
+
+# by default run all steps: update, git, YUIcompressor and web2py
+if not (opt.update or opt.git or opt.yuicompressor or opt.web2py):
+    opt.update = True
+    opt.git = True
+    opt.yuicompressor = True
+    opt.web2py = True
+    
+#-----------------------------------------------------------------------------
+#     clean previous build
+if opt.clean:
+    os.remove(JSLIBDEBUG)
+    os.remove(JSLIBMIN)
+    print 'files', JSLIBDEBUG, JSLIBMIN, 'were removed.'
+    sys.exit(0)
+
+#-----------------------------------------------------------------------------
+#    update step
+#    Push version identifier in the CHANGELOG and appbase.js
+#
+if opt.update:
+    # version identifier
+    if args:
+        version = args[0]
+        
+    else:
+        version = raw_input('Enter the version identifier: ')
+
+    print 'Modified', JSBASE
+    s = open(JSBASE, 'rb').read()
+    
+    # look for a pattern App.version = '0.8.3'; in appbase.js
+    # split the the string in 3 parts (pre, version, post)
+    m = re.match("(.+App.version = ')([\w._-]*)(';.*)", s, re.DOTALL)
+    
+    if m.group(2) == version:
+        print '\n\tVersion "%s" already exists in the appbase.js file !' % version
+        rep = raw_input('\tDo you want to continue [n]?')
+        if rep not in ('y', 'yes'):
+            sys.exit(1)
+
+    # update the version and write a new file    
+    s = m.group(1) + version + m.group(3)
+    if opt.run:
+        fi = open(JSBASE, 'wb')
+        fi.write(s)
+        fi.close()
+    else:
+        print s
+    
+    # look for a pattern HEAD in the CHANGELOG
+    # split the the string in 3 parts (pre, HEAD, post)
+    print 'Modified', CHANGELOG
+    s = open(CHANGELOG, 'rb').read()
+    
+    m = re.match("(.+)(HEAD\n)(.*)", s, re.DOTALL)
+    
+    if m == None:
+        print '\n\tNo HEAD tag in the CHANGELOG!\n'
+        rep = raw_input('\tDo you want to continue [n]?')
+        if rep not in ('y', 'yes'):
+            sys.exit(1)
+
+    # update the version and write a new file    
+    s = '%s%s (%s)\n%s' % (m.group(1), version, datetime.now().strftime('%b %Y'), m.group(3))
+    if opt.run:
+        fi = open(CHANGELOG, 'wb')
+        fi.write(s)
+        fi.close()
+    else:
+        print s
+
+#-----------------------------------------------------------------------------
+#    YUIcompressor step
+#
+if opt.yuicompressor:
+    # debug version of the javascript library
+    print 'Debug version of the javascript library', JSLIBDEBUG
+    subprocess.call('cat %s/*.js > %s' % (JSLIBSRC, JSLIBDEBUG), shell=True)
+
+    # Minified version of the javascript library
+    print 'Minified version of the javascript library', JSLIBMIN
+    cmd = ["java", "-jar", YUICOMPRESSOR, "-o", JSLIBMIN, JSLIBDEBUG]
+    subprocess.call(cmd)
+
+#-----------------------------------------------------------------------------
+#    git step
+#
+if opt.git:
+    # Commit the new release in git an tag it
+    print 'git add', JSBASE, CHANGELOG, JSLIBDEBUG, JSLIBMIN
+    cmd = ["git", "add", JSBASE, CHANGELOG, JSLIBDEBUG, JSLIBMIN]
+    if opt.run: subprocess.call(cmd)
+    
+    print 'git commit'
+    cmd = ["git", "commit", "-m", "Release version %s" % version]
+    if opt.run: subprocess.call(cmd)
+    
+    print 'git tag', version
+    cmd = ["git", "tag", version]
+    if opt.run: subprocess.call(cmd)
+
+#-----------------------------------------------------------------------------
+#    web2py step
+#
+if opt.web2py:
+    # build the web2py plugin
+    print 'Build the web2py plugin binary file'
+    raw_input('Check that the web2py service is running ? Type CR to continue.')
+#    f = urllib.urlopen(PACK_PLUGIN_URL)
+#    print f.read()
+    auth_handler = urllib2.HTTPBasicAuthHandler()
+    auth_handler.add_password(realm='web2py',
+                              uri='http://localhost:8000/admin',
+                              user='admin',
+                              passwd='f')
+    opener = urllib2.build_opener(auth_handler)
+    urllib2.install_opener(opener)
+    f = urllib2.urlopen(PACK_PLUGIN_URL)
+    print f.read()
+
+#-----------------------------------------------------------------------------
+#     exit
+#
+print 'Exit buidVersion'
+sys.exit(0)
\ No newline at end of file