Code

- release preparation
[roundup.git] / doc / upgrading.txt
index 977665f091465e67ebecfd44aa38b130d2331216..eb0a68c9a0d9ea601fbc93c6790a2c2935d8c168 100644 (file)
@@ -3,34 +3,1038 @@ Upgrading to newer versions of Roundup
 ======================================
 
 Please read each section carefully and edit your tracker home files
-accordingly.
+accordingly. Note that there is information about upgrade procedures in the
+`administration guide`_.
+
+If a specific version transition isn't mentioned here (eg. 0.6.7 to 0.6.8)
+then you don't need to do anything. If you're upgrading from 0.5.6 to
+0.6.8 though, you'll need to check the "0.5 to 0.6" and "0.6.x to 0.6.3"
+steps.
 
 .. contents::
 
+Migrating from 1.4.16 to 1.4.17
+===============================
+
+There was a bug in 1.4.16 where files were unlinked from issues if a
+mail without attachment was received via the mail interface. The
+following script will list likely issues being affected by the bug.
+The date in the script is the date of the 1.4.16 release. If you have
+installed 1.4.16 later than this date, you can change the date
+appropriately to your installation date. Run the script in the directory
+of your tracker.
+
+#!/usr/bin/python
+import os
+from roundup import instance
+from roundup.date import Date
+dir     = os.getcwd ()
+tracker = instance.open (dir)
+db      = tracker.open ('admin')
+# you may want to change this to your install date to find less candidates
+last_release = Date('2011-05-13')
+affected = {}
+for i in db.issue.getnodeids():
+    for j in db.issue.history(i):
+        if i in affected:
+            break
+        if j[1] < last_release or j[3] != 'set' or 'files' not in j[4]:
+            continue
+        for op, p in j[4]['files']:
+            if op == '-':
+                affected [i] = 1
+                break
+print ', '.join(sorted(affected.iterkeys()))
+
+To find out which files where attached before you can look in the
+history of the affected issue.  For fixing issues you can re-attach the
+files in question using the "set" command of roundup-admin, e.g., if the
+list of files attached to an issue should be files 5, 17, 23 for issue42
+you will set this using
+
+roundup-admin -i /path/to/your/tracker set issue42 files=5,17,23
+
+Migrating from 1.4.x to 1.4.17
+==============================
+
+There is a new config-option `migrate_passwords` in section `web` to
+auto-migrate passwords at web-login time to a more secure storage
+scheme. Default for the new option is "yes" so if you don't want that
+passwords are auto-migrated to a more secure password scheme on user
+login, set this to "no" before running your tracker(s) after the
+upgrade.
+
+The standalone roundup-server now defaults to listening on localhost (no
+longer on all network interfaces). This will not affect you if you're
+already using a configuration file for roundup-server. If you are using
+an empty setting for the `host` parameter in the config-file you should
+explicitly put 0.0.0.0 there as the use of an empty string to specify
+listening to all interfaces is deprecated and will go away in a future
+version.  If you are starting the server without a configuration file
+and want to explicitly listen to all network interface, you should
+specify the -n option with the address `0.0.0.0`.
+
+Searching now requires either read-permission without a check method, or
+you will have to add a "Search" permission for a class or a list of
+properties for a class (if you want to allow searching). For the classic
+template (or other templates derived from it) you want to add the
+following lines to your `schema.py` file::
+
+  p = db.security.addPermission(name='Search', klass='query')
+  db.security.addPermissionToRole('User', p)
+
+This is needed, because for the `query` class users may view only their
+own queries (or public queries). This is implemented with a `check`
+method, therefore the default search permissions will not allow
+searching and you'll have to add an explicit search permission.
+If you have modified your schema, you can check if you're missing any
+search permissions with the following script, run it in your tracker
+directory, it will list for each Class and Property the roles that may
+search for this property::
+
+    #!/usr/bin/python
+    import os
+    from roundup import instance
+    
+    tracker = instance.open(os.getcwd ())
+    db = tracker.open('admin')
+    
+    for cl in sorted(db.getclasses()):
+        print "Class:", cl
+        for p in sorted(db.getclass(cl).properties.keys()):
+            print "    Property:", p
+            roles = []
+            for role in sorted(db.security.role.iterkeys()):
+                if db.security.roleHasSearchPermission(cl,p,role):
+                    roles.append(role)
+            print "        roles may search:", ', '.join(roles)
+
+
+Migrating from 1.4.x to 1.4.12
+==============================
+
+Item creation now checks the "Create" permission instead of the "Edit"
+permission for individual properties. If you have modified your tracker
+permissions from the default distribution, you should check that
+"Create" permissions exist for all properties you want users to be able
+to create.
+
+
+Fixing some potential security holes
+------------------------------------
+
+Enhanced checking was added to the user registration auditor. If you
+run a public tracker you should update your tracker's
+``detectors/userauditor.py`` using the new code from
+``share/roundup/templates/classic/detectors/userauditor.py``. In most
+cases you may just copy the file over, but if you've made changes to
+the auditor in your tracker then you'll need to manually integrate
+the new code.
+
+Some HTML templates were found to have formatting security problems:
+
+``html/page.html``::
+
+  -tal:replace="request/user/username">username</span></b><br>
+  +tal:replace="python:request.user.username.plain(escape=1)">username</span></b><br>
+
+``html/_generic.help-list.html``::
+
+  -tal:content="structure python:item[prop]"></label>
+  +tal:content="python:item[prop]"></label>
+
+The lines marked "+" should be added and lines marked "-" should be
+deleted (minus the "+"/"-" signs).
+
+
+Some HTML interface tweaks
+--------------------------
+
+You may wish to copy the ``user_utils.js`` and ``style.css` files from the
+source distribution ``share/roundup/templates/classic/html/`` directory to the
+``html`` directory of your trackers as it includes a small improvement.
+
+If you have made local changes to those files you'll need to manually work
+the differences in to your versions or ignore the changes.
+
+
+Migrating from 1.4.x to 1.4.11
+==============================
+
+Close potential security hole
+-----------------------------
+
+If your tracker has untrusted users you should examine its ``schema.py``
+file and look for the section granting the "Edit" permission to your users.
+This should look something like::
+
+    p = db.security.addPermission(name='Edit', klass='user', check=own_record,
+        description="User is allowed to edit their own user details")
+
+and should be modified to restrict the list of properties they are allowed
+to edit by adding the ``properties=`` section like::
+
+    p = db.security.addPermission(name='Edit', klass='user', check=own_record,
+        properties=('username', 'password', 'address', 'realname', 'phone',
+            'organisation', 'alternate_addresses', 'queries', 'timezone'),
+        description="User is allowed to edit their own user details")
+
+Most importantly the "roles" property should not be editable - thus not
+appear in that list of properties.
+
+
+Grant the "Register" permission to the Anonymous role
+-----------------------------------------------------
+
+A separate "Register" permission has been introduced to allow
+anonymous users to register. This means you will need to add the
+following to your tracker's ``schema.py`` to add the permission and
+assign it to the Anonymous role (replacing any previously assigned
+"Create user" permission for the Anonymous role)::
+
+  +db.security.addPermission(name='Register', klass='user',
+  +     description='User is allowed to register new user')
+   # Assign the appropriate permissions to the anonymous user's Anonymous
+   # Role. Choices here are:
+   # - Allow anonymous users to register
+  -db.security.addPermissionToRole('Anonymous', 'Create', 'user')
+  +db.security.addPermissionToRole('Anonymous', 'Register', 'user')
+
+The lines marked "+" should be added and lines marked "-" should be
+deleted (minus the "+"/"-" signs).
+
+You should also modify the ``html/page.html`` template to change the
+permission tested there::
+
+   -tal:condition="python:request.user.hasPermission('Create', 'user')"
+   +tal:condition="python:request.user.hasPermission('Register', 'user')"
+
+
+Generic class editor may now restore retired items
+--------------------------------------------------
+
+The instructions for doing so won't be present in your tracker unless you copy
+the ``_generic.index.html`` template from the roundup distribution in
+``share/roundup/templates/classic/html`` to your tracker's ``html`` directory.
+
+
+Migrating from 1.4.x to 1.4.9
+=============================
+
+Customized MailGW Class
+-----------------------
+
+If you have customized the MailGW class in your tracker: The new MailGW
+class opens the database for each message in the method handle_message
+(instance.open) instead of passing the opened database as a parameter to
+the MailGW constructor. The old handle_message has been renamed to
+_handle_message. The new method opens the database and wraps the call to
+the old method into a try/finally.
+
+Your customized MailGW class needs to mirror this behavior.
+
+Fix the "remove" button in issue files and messages lists
+---------------------------------------------------------
+
+The "remove" button(s) in the issue messages list needs to be altered. Find
+the following in your tracker's ``html/issue.item.html`` template::
+
+  <td>
+   <form style="padding:0" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@files" tal:attributes="value file/id">
+
+and add ``method="POST"`` as shown below::
+
+  <td>
+   <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@files" tal:attributes="value file/id">
+
+Then also find::
+
+  <td>
+   <form style="padding:0" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
+
+and add ``method="POST"`` as shown below::
+
+  <td>
+   <form style="padding:0" method="POST" tal:condition="context/is_edit_ok"
+         tal:attributes="action string:issue${context/id}">
+    <input type="hidden" name="@remove@messages" tal:attributes="value msg/id">
+
+
+Fixing the "retire" button in user management list
+--------------------------------------------------
+
+If you made the change to the "reture" link in the user management list as
+listed below in `Migrating from 1.4.x to 1.4.7`_ then you'll need to fix that
+change by adding ``method="POST"`` to the ``<form>`` tag::
+
+     <form style="padding:0" method="POST"
+           tal:attributes="action string:user${user/id}">
+      <input type="hidden" name="@template" value="index">
+      <input type="hidden" name="@action" value="retire">
+      <input type="submit" value="retire" i18n:attributes="value">
+     </form>
+
+
+Migrating from 1.4.x to 1.4.7
+=============================
+
+Several security issues were addressed in this release. Some aspects of your
+trackers may no longer function depending on your local customisations. Core
+functionality that will need to be modified:
+
+Grant the "retire" permission to users for their queries
+--------------------------------------------------------
+
+Users will no longer be able to retire their own queries. To remedy this you
+will need to add the following to your tracker's ``schema.py`` just under the
+line that grants them permission to edit their own queries::
+
+   p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
+      description="User is allowed to edit their queries")
+   db.security.addPermissionToRole('User', p)
+ + p = db.security.addPermission(name='Retire', klass='query', check=edit_query,
+ +    description="User is allowed to retire their queries")
+ + db.security.addPermissionToRole('User', p)
+   p = db.security.addPermission(name='Create', klass='query',
+      description="User is allowed to create queries")
+   db.security.addPermissionToRole('User', p)
+
+The lines marked "+" should be added, minus the "+" sign.
+
+
+Fix the "retire" link in the users list for admin users
+-------------------------------------------------------
+
+The "retire" link found in the file ``html/user.index.html``::
+
+  <td tal:condition="context/is_edit_ok">
+   <a tal:attributes="href string:user${user/id}?@action=retire&@template=index"
+    i18n:translate="">retire</a>
+
+Should be replaced with::
+
+  <td tal:condition="context/is_retire_ok">
+     <form style="padding:0" method="POST"
+           tal:attributes="action string:user${user/id}">
+      <input type="hidden" name="@template" value="index">
+      <input type="hidden" name="@action" value="retire">
+      <input type="submit" value="retire" i18n:attributes="value">
+     </form>
+
+
+Fix for Python 2.6+ users
+-------------------------
+
+If you use Python 2.6 you should edit your tracker's
+``detectors/nosyreaction.py`` file to change::
+
+   import sets
+
+at the top to::
+
+   from roundup.anypy.sets_ import set
+
+and then all instances of ``sets.Set()`` to ``set()`` in the later code.
+
+
+
+Trackers currently allowing HTML file uploading
+-----------------------------------------------
+
+Trackers which wish to continue to allow uploading of HTML content against issues
+will need to set a new configuration variable in the ``[web]`` section of the
+tracker's ``config.ini`` file:
+
+   # Setting this option enables Roundup to serve uploaded HTML
+   # file content *as HTML*. This is a potential security risk
+   # and is therefore disabled by default. Set to 'yes' if you
+   # trust *all* users uploading content to your tracker.
+   # Allowed values: yes, no
+   # Default: no
+   allow_html_file = no
+
+
+
+Migrating from 1.4.2 to 1.4.3
+=============================
+
+If you are using the MySQL backend you will need to replace some indexes
+that may have been created by version 1.4.2.
+
+You should to access your MySQL database directly and remove any indexes
+with a name ending in "_key_retired_idx". You should then re-add them with
+the same spec except the key column name needs a size. So an index on
+"_user (__retired, _name)" should become "_user (__retired, _name(255))".
+
+
+Migrating from 1.4.x to 1.4.2
+=============================
+
+You should run the "roundup-admin migrate" command for your tracker once
+you've installed the latest codebase. 
+
+Do this before you use the web, command-line or mail interface and before
+any users access the tracker.
+
+This command will respond with either "Tracker updated" (if you've not
+previously run it on an RDBMS backend) or "No migration action required"
+(if you have run it, or have used another interface to the tracker,
+or are using anydbm).
+
+It's safe to run this even if it's not required, so just get into the
+habit.
+
+
+Migrating from 1.3.3 to 1.4.0
+=============================
+
+Value of the "refwd_re" tracker configuration option (section "mailgw")
+is treated as UTF-8 string.  In previous versions, it was ISO8859-1.
+
+If you have running trackers based on the classic template, please
+update the messagesummary detector as follows::
+
+    --- detectors/messagesummary.py 17 Apr 2003 03:26:38 -0000      1.1
+    +++ detectors/messagesummary.py 3 Apr 2007 06:47:21 -0000       1.2
+    @@ -8,7 +8,7 @@
+     if newvalues.has_key('summary') or not newvalues.has_key('content'):
+         return
+
+    -    summary, content = parseContent(newvalues['content'], 1, 1)
+    +    summary, content = parseContent(newvalues['content'], config=db.config)
+     newvalues['summary'] = summary
+
+In the latest version we have added some database indexes to the
+SQL-backends (mysql, postgresql, sqlite) for speeding up building the
+roundup-index for full-text search. We recommend that you create the
+following database indexes on the database by hand::
+
+ CREATE INDEX words_by_id ON __words (_textid);
+ CREATE UNIQUE INDEX __textids_by_props ON __textids (_class, _itemid, _prop);
+
+Migrating from 1.2.x to 1.3.0
+=============================
+
+1.3.0 Web interface changes
+---------------------------
+
+Some of the HTML files in the "classic" and "minimal" tracker templates
+were changed to fix some bugs and clean them up. You may wish to compare
+them to the HTML files in your tracker and apply any changes.
+
+
+Migrating from 1.1.2 to 1.2.0
+=============================
+
+1.2.0 Sorting and grouping by multiple properties
+-------------------------------------------------
+
+Starting with this version, sorting and grouping by multiple properties
+is possible. This means that request.sort and request.group are now
+lists. This is reflected in several places:
+
+ * ``renderWith`` now has list attributes for ``sort`` and ``group``,
+   where you previously wrote::
+   
+    renderWith(... sort=('-', 'activity'), group=('+', 'priority')
+
+   you write now::
+
+    renderWith(... sort=[('-', 'activity')], group=[('+', 'priority')]
+
+ * In templates that permit to edit sorting/grouping, request.sort and
+   request.group are (possibly empty) lists. You can now sort and group
+   by multiple attributes. For an example, see the classic template. You
+   may want search for the variable ``n_sort`` which can be set to the
+   number of sort/group properties.
+
+ * Templates that diplay new headlines for each group of items with
+   equal group properties can now use the modified ``batch.propchanged``
+   method that can take several properties which are checked for
+   changes. See the example in the classic template which makes use of
+   ``batch.propchanged``.
+
+Migrating from 1.1.0 to 1.1.1
+=============================
+
+1.1.1 "Clear this message"
+--------------------------
+
+In 1.1.1, the standard ``page.html`` template includes a "clear this message"
+link in the green "ok" message bar that appears after a successful edit
+(or other) action.
+
+To include this in your tracker, change the following in your ``page.html``
+template::
+
+ <p tal:condition="options/ok_message | nothing" class="ok-message"
+    tal:repeat="m options/ok_message" tal:content="structure m">error</p>
+
+to be::
+
+ <p tal:condition="options/ok_message | nothing" class="ok-message">
+   <span tal:repeat="m options/ok_message"
+      tal:content="structure string:$m <br/ > " />
+    <a class="form-small" tal:attributes="href request/current_url"
+       i18n:translate="">clear this message</a>
+ </p>
+
+
+If you implemented the "clear this message" in your 1.1.0 tracker, then you
+should change it to the above and it will work much better!
+
+
+Migrating from 1.0.x to 1.1.0
+=============================
+
+1.1 Login "For Session Only"
+----------------------------
+
+In 1.1, web logins are alive for the length of a session only, *unless* you
+add the following to the login form in your tracker's ``page.html``::
+
+    <input type="checkbox" name="remember" id="remember">
+    <label for="remember" i18n:translate="">Remember me?</label><br>
+
+See the classic tracker ``page.html`` if you're unsure where this should
+go.
+
+
+1.1 Query Display Name
+----------------------
+
+The ``dispname`` web variable has been renamed ``@dispname`` to avoid
+clashing with other variables of the same name. If you are using the
+display name feature, you will need to edit your tracker's ``page.html``
+and ``issue.index.html`` pages to change ``dispname`` to ``@dispname``.
+
+A side-effect of this change is that the renderWith method used in the
+``home.html`` page may now take a dispname argument.
+
+
+1.1 "Clear this message"
+------------------------
+
+In 1.1, the standard ``page.html`` template includes a "clear this message"
+link in the green "ok" message bar that appears after a successful edit
+(or other) action.
+
+To include this in your tracker, change the following in your ``page.html``
+template::
+
+ <p tal:condition="options/ok_message | nothing" class="ok-message"
+    tal:repeat="m options/ok_message" tal:content="structure m">error</p>
+
+to be::
+
+ <p tal:condition="options/ok_message | nothing" class="ok-message">
+   <span tal:repeat="m options/ok_message"
+      tal:content="structure string:$m <br/ > " />
+    <a class="form-small" tal:attributes="href string:issue${context/id}"
+       i18n:translate="">clear this message</a>
+ </p>
+
+
+Migrating from 0.8.x to 1.0
+===========================
+
+1.0 New Query Permissions
+-------------------------
+
+New permissions are defined for query editing and viewing. To include these
+in your tracker, you need to add these lines to your tracker's
+``schema.py``::
+
+ # Users should be able to edit and view their own queries. They should also
+ # be able to view any marked as not private. They should not be able to
+ # edit others' queries, even if they're not private
+ def view_query(db, userid, itemid):
+     private_for = db.query.get(itemid, 'private_for')
+     if not private_for: return True
+     return userid == private_for
+ def edit_query(db, userid, itemid):
+     return userid == db.query.get(itemid, 'creator')
+ p = db.security.addPermission(name='View', klass='query', check=view_query,
+     description="User is allowed to view their own and public queries")
+ db.security.addPermissionToRole('User', p)
+ p = db.security.addPermission(name='Edit', klass='query', check=edit_query,
+     description="User is allowed to edit their queries")
+ db.security.addPermissionToRole('User', p)
+ p = db.security.addPermission(name='Create', klass='query',
+     description="User is allowed to create queries")
+ db.security.addPermissionToRole('User', p)
+
+and then remove 'query' from the line::
+
+ # Assign the access and edit Permissions for issue, file and message
+ # to regular users now
+ for cl in 'issue', 'file', 'msg', 'query', 'keyword':
+
+so it looks like::
+
+ for cl in 'issue', 'file', 'msg', 'keyword':
+
+
+Migrating from 0.8.0 to 0.8.3
+=============================
+
+0.8.3 Nosy Handling Changes
+---------------------------
+
+A change was made to fix a bug in the ``nosyreaction.py`` standard
+detector. To incorporate this fix in your trackers, you will need to copy
+the ``nosyreaction.py`` file from the ``templates/classic/detectors``
+directory of the source to your tracker's ``templates`` directory.
+
+If you have modified the ``nosyreaction.py`` file from the standard
+version, you will need to roll your changes into the new file.
+
+
+Migrating from 0.7.1 to 0.8.0
+=============================
+
+You *must* fully uninstall previous Roundup version before installing
+Roundup 0.8.0.  If you don't do that, ``roundup-admin install``
+command may fail to function properly.
+
+0.8.0 Backend changes
+---------------------
+
+Backends 'bsddb' and 'bsddb3' are removed.  If you are using one of these,
+you *must* migrate to another backend before upgrading.
+
+
+0.8.0 API changes
+-----------------
+
+Class.safeget() was removed from the API. Test your item ids before calling
+Class.get() instead.
+
+
+0.8.0 New tracker layout
+------------------------
+
+The ``config.py`` file has been replaced by ``config.ini``. You may use the
+roundup-admin command "genconfig" to generate a new config file::
+
+  roundup-admin genconfig <tracker home>/config.ini
+
+and modify the values therein based on the contents of your old config.py.
+In most cases, the names of the config variables are the same.
+
+The ``select_db.py`` file has been replaced by a file in the ``db``
+directory called ``backend_name``. As you might guess, this file contains
+just the name of the backend. To figure what the contents of yours should
+be, use the following table:
+
+  ================================ =========================
+  ``select_db.py`` contents        ``backend_name`` contents
+  ================================ =========================
+  from back_anydbm import ...      anydbm
+  from back_metakit import ...     metakit
+  from back_sqlite import ...      sqlite
+  from back_mysql import ...       mysql
+  from back_postgresql import ...  postgresql
+  ================================ =========================
+
+The ``dbinit.py`` file has been split into two new files,
+``initial_data.py`` and ``schema.py``. The contents of this file are:
+
+``initial_data.py``
+  You don't need one of these as your tracker is already initialised.
+
+``schema.py``
+  Copy the body of the ``def open(name=None)`` function from your old
+  tracker's ``dbinit.py`` file to this file. As the lines you're copying
+  aren't part of a function definition anymore, one level of indentation
+  needs to be removed (remove only the leading four spaces on each
+  line). 
+
+  The first few lines -- those starting with ``from roundup.hyperdb
+  import ...`` and the ``db = Database(config, name)`` line -- don't
+  need to be copied. Neither do the last few lines -- those starting
+  with ``import detectors``, down to ``return db`` inclusive.
+
+You may remove the ``__init__.py`` module from the "detectors" directory as
+it is no longer used.
+
+There's a new way to write extension code for Roundup. If you have code in
+an ``interfaces.py`` file you should move it. See the `customisation
+documentation`_ for information about how extensions are now written.
+Note that some older trackers may use ``interfaces.py`` to customise the
+mail gateway behaviour. You will need to keep your ``interfaces.py`` file
+if this is the case.
+
+
+0.8.0 Permissions Changes
+-------------------------
+
+The creation of a new item in the user interfaces is now controlled by the
+"Create" Permission. You will need to add an assignment of this Permission
+to your users who are allowed to create items. The most common form of this
+is the following in your ``schema.py`` added just under the current
+assignation of the Edit Permission::
+
+    for cl in 'issue', 'file', 'msg', 'query', 'keyword':
+        p = db.security.getPermission('Create', cl)
+        db.security.addPermissionToRole('User', p)
+
+You will need to explicitly let anonymous users access the web interface so
+that regular users are able to see the login form. Note that almost all
+trackers will need this Permission. The only situation where it's not
+required is in a tracker that uses an HTTP Basic Authenticated front-end.
+It's enabled by adding to your ``schema.py``::
+
+    p = db.security.getPermission('Web Access')
+    db.security.addPermissionToRole('Anonymous', p)
+
+Finally, you will need to enable permission for your users to edit their
+own details by adding the following to ``schema.py``::
+
+    # Users should be able to edit their own details. Note that this
+    # permission is limited to only the situation where the Viewed or
+    # Edited item is their own.
+    def own_record(db, userid, itemid):
+        '''Determine whether the userid matches the item being accessed.'''
+        return userid == itemid
+    p = db.security.addPermission(name='View', klass='user', check=own_record,
+        description="User is allowed to view their own user details")
+    p = db.security.addPermission(name='Edit', klass='user', check=own_record,
+        description="User is allowed to edit their own user details")
+    db.security.addPermissionToRole('User', p)
+
+
+0.8.0 Use of TemplatingUtils
+----------------------------
+
+If you used custom python functions in TemplatingUtils, they must
+be moved from interfaces.py to a new file in the ``extensions`` directory. 
+
+Each Function that should be available through TAL needs to be defined
+as a toplevel function in the newly created file. Furthermore you
+add an inititialization function, that registers the functions with the 
+tracker.
+
+If you find this too tedious, donfu wrote an automatic init function that
+takes an existing TemplatingUtils class, and registers all class methods
+that do not start with an underscore. The following hack should be placed
+in the ``extensions`` directory alongside other extensions::
+
+    class TemplatingUtils:
+         # copy from interfaces.py
+
+    def init(tracker):
+         util = TemplatingUtils()
+
+         def setClient(tu):
+             util.client = tu.client
+             return util
+
+         def execUtil(name):
+             return lambda tu, *args, **kwargs: \
+                     getattr(setClient(tu), name)(*args, **kwargs)
+
+         for name in dir(util):
+             if callable(getattr(util, name)) and not name.startswith('_'):
+                  tracker.registerUtil(name, execUtil(name))
+
+
+0.8.0 Logging Configuration
+---------------------------
+
+See the `administration guide`_ for information about configuring the new
+logging implemented in 0.8.0.
+
+
+Migrating from 0.7.2 to 0.7.3
+=============================
+
+0.7.3 Configuration
+-------------------
+
+If you choose, you may specify the directory from which static files are
+served (those which use the URL component ``@@file``). Currently the
+directory defaults to the ``TEMPLATES`` configuration variable. You may
+define a new variable, ``STATIC_FILES`` which overrides this value for
+static files.
+
+
+Migrating from 0.7.0 to 0.7.2
+=============================
+
+0.7.2 DEFAULT_TIMEZONE is now required
+--------------------------------------
+
+The DEFAULT_TIMEZONE configuration variable is now required. Add the
+following to your tracker's ``config.py`` file::
+
+    # You may specify a different default timezone, for use when users do not
+    # choose their own in their settings.
+    DEFAULT_TIMEZONE = 0            # specify as numeric hour offest
+
+
+Migrating from 0.7.0 to 0.7.1
+=============================
+
+0.7.1 Permission assignments
+----------------------------
+
+If you allow anonymous access to your tracker, you might need to assign
+some additional View (or Edit if your tracker is that open) permissions
+to the "anonymous" user. To do so, find the code in your ``dbinit.py`` that
+says::
+
+    for cl in 'issue', 'file', 'msg', 'query', 'keyword':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+        p = db.security.getPermission('Edit', cl)
+        db.security.addPermissionToRole('User', p)
+    for cl in 'priority', 'status':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+
+Add add a line::
+
+        db.security.addPermissionToRole('Anonymous', p)
+
+next to the existing ``'User'`` lines for the Permissions you wish to
+assign to the anonymous user.
+
+
+Migrating from 0.6 to 0.7
+=========================
+
+0.7.0 Permission assignments
+----------------------------
+
+Due to a change in the rendering of web widgets, permissions are now
+checked on Classes where they previously weren't (this is a good thing).
+
+You will need to add some additional Permission assignments for your
+regular users, or some displays will break. After the following in your 
+tracker's ``dbinit.py``::
+
+    # Assign the access and edit Permissions for issue, file and message
+    # to regular users now
+    for cl in 'issue', 'file', 'msg', 'query', 'keyword':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+        p = db.security.getPermission('Edit', cl)
+        db.security.addPermissionToRole('User', p)
+
+add::
+
+    for cl in 'priority', 'status':
+        p = db.security.getPermission('View', cl)
+        db.security.addPermissionToRole('User', p)
+
+
+0.7.0 Getting the current user id
+---------------------------------
+
+The Database.curuserid attribute has been removed.
+
+Any code referencing this attribute should be replaced with a
+call to Database.getuid().
+
+
+0.7.0 ZRoundup changes
+----------------------
+
+The templates in your tracker's html directory will need updating if you
+wish to use ZRoundup. If you've not modified those files (or some of them),
+you may just copy the new versions from the Roundup source in the
+templates/classic/html directory.
+
+If you have modified the html files, then you'll need to manually edit them
+to change all occurances of special form variables from using the colon ":"
+special character to the at "@" special character. That is, variables such
+as::
+
+  :action :required :template :remove:messages ...
+
+should become::
+
+  @action @required @template @remove@messages ...
+
+Note that ``tal:`` statements are unaffected. So are TAL expression type
+prefixes such as ``python:`` and ``string:``. Please ask on the
+roundup-users mailing list for help if you're unsure.
+
+
+0.7.0 Edit collision detection
+------------------------------
+
+Roundup now detects collisions with editing in the web interface (that is,
+two people editing the same item at the same time).
+
+You must copy the ``_generic.collision.html`` file from Roundup source in
+the ``templates/classic/html`` directory. to your tracker's ``html``
+directory.
+
+
+Migrating from 0.6.x to 0.6.3
+=============================
+
+0.6.3 Configuration
+-------------------
+
+You will need to copy the file::
+
+  templates/classic/detectors/__init__.py
+
+to your tracker's ``detectors`` directory, replacing the one already there.
+This fixes a couple of bugs in that file.
+
+
+
 Migrating from 0.5 to 0.6
 =========================
 
-- Introduced EMAIL_FROM_TAG config variable.
 
-- Added internationalization support. This is done via encoding all data
-  stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
-  web interface you should add the folowing line to your tracker's html/page
-  and html/_generic.help files inside <head> tag:
+0.6.0 Configuration
+-------------------
+
+Introduced EMAIL_FROM_TAG config variable. This value is inserted into
+the From: line of nosy email. If the sending user is "Foo Bar", the
+From: line is usually::
+
+     "Foo Bar" <issue_tracker@tracker.example>
+
+the EMAIL_FROM_TAG goes inside the "Foo Bar" quotes like so::
+
+     "Foo Bar EMAIL_FROM_TAG" <issue_tracker@tracker.example>
+
+I've altered the mechanism in the detectors __init__.py module so that it
+doesn't cross-import detectors from other trackers (if you run more than one
+in a single roundup-server). This change means that you'll need to copy the
+__init__.py from roundup/templates/classic/detectors/__init__.py to your
+<tracker home>/detectors/__init__.py. Don't worry, the "classic" __init__ is a
+one-size-fits-all, so it'll work even if you've added/removed detectors.
+
+0.6.0 Templating changes
+------------------------
+
+The ``user.item`` template (in the tracker home "templates" directory)
+needs to have the following hidden variable added to its form (between the
+``<form...>`` and ``</form>`` tags::
+
+  <input type="hidden" name=":template" value="item">
+
+
+0.6.0 Form handling changes
+---------------------------
+
+Roundup's form handling capabilities have been significantly expanded. This
+should not affect users of 0.5 installations - but if you find you're
+getting errors from form submissions, please ask for help on the Roundup
+users mailing list:
+
+  http://lists.sourceforge.net/lists/listinfo/roundup-users
+
+See the customisation doc section on `Form Values`__ for documentation of the
+new form variables possible.
+
+__ customizing.html#form-values
+
+
+0.6.0 Multilingual character set support
+----------------------------------------
+
+Added internationalization support. This is done via encoding all data
+stored in roundup database to utf-8 (unicode encoding). To support utf-8 in
+web interface you should add the folowing line to your tracker's html/page
+and html/_generic.help files inside <head> tag::
   
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 
-  Sinse latin characters in utf-8 has the same codes as in ASCII table, this
-  modification is optional for users who use only plain latin characters. 
+Since latin characters in utf-8 have the same codes as in ASCII table, this
+modification is optional for users who use only plain latin characters. 
+
+After this modification, you will be able to see and enter any world
+character via web interface. Data received via mail interface also converted
+to utf-8, however only new messages will be converted. If your roundup
+database contains some of non-ASCII characters in one of 8-bit encoding,
+they will not be visible in new unicode environment. Some of such data (e.g.
+user names, keywords, etc)  can be edited by administrator, the others
+(e.g. messages' contents) is not editable via web interface. Currently there
+is no tool for converting such data, the only solution is to close
+appropriate old issues and create new ones with the same content.
+
+
+0.6.0 User timezone support
+---------------------------
+
+From version 0.6.0 roundup supports displaying of Date data in user' local
+timezone if he/she has provided timezone information. To make it possible
+some modification to tracker's schema and HTML templates are required.
+First you must add string property 'timezone' to user class in dbinit.py
+like this::
+  
+    user = Class(db, "user", 
+                    username=String(),   password=Password(),
+                    address=String(),    realname=String(), 
+                    phone=String(),      organisation=String(),
+                    alternate_addresses=String(),
+                    queries=Multilink('query'), roles=String(),
+                    timezone=String())
+  
+And second - html interface. Add following lines to
+$TRACKER_HOME/html/user.item template::
+  
+     <tr>
+      <th>Timezone</th>
+      <td tal:content="structure context/timezone/field">timezone</td>
+     </tr>
+
+After that all users should be able to provide their timezone information.
+Timezone should be a positive or negative integer - offset from GMT.
+
+After providing timezone, roundup will show all dates values, found in web
+and mail interfaces in local time. It will also accept any Date info in
+local time, convert and store it in GMT.
+
+
+0.6.0 Search page structure
+---------------------------
+
+In order to accomodate query editing the search page has been restructured. If
+you want to provide your users with query editing, you should update your
+search page using the macros detailed in the customisation doc section
+`Searching on categories`__.
+
+__ customizing.html#searching-on-categories
+
+Also, the url field in the query class no longer starts with a '?'. You'll need
+to remove this question mark from the url field to support queries. There's
+a script in the "tools" directory called ``migrate-queries.py`` that should
+automatically change any existing queries for you. As always, make a backup
+of your database before running such a script.
+
+
+0.6.0 Notes for metakit backend users
+-------------------------------------
+
+Roundup 0.6.0 introduced searching on ranges of dates and intervals. To
+support it, some modifications to interval storing routine were made. So if
+your tracker uses metakit backend and your db schema contains intervals
+property, searches on that property will not be accurate for db items that
+was stored before roundup' upgrade. However all new records should be
+searchable on intervals.
+
+It is possible to convert your database to new format: you can export and
+import back all your data (consult "Migrating backends" in "Maintenance"
+documentation). After this operation all your interval properties should
+become searchable.
 
-  After this modification, you will be able to see and enter any world
-  character via web interface. Data received via mail interface also converted
-  to utf-8, however only new messages will be converted. If your roundup
-  database contains some of non-ASCII characters in one of 8-bit encoding,
-  they will not be visible in new unicode environment. Some of such data (e.g.
-  user names, keywords, etc)  can be edited by administrator, the others
-  (e.g. messages' contents) is not editable via web interface. Currently there
-  is no tool for converting such data, the only solution is to close
-  appropriate old issues and create new ones with the same content.
+Users of backends others than metakit should not worry about this issue.
 
 
 Migrating from 0.4.x to 0.5.0
@@ -753,3 +1757,4 @@ copy.
 
 .. _`customisation documentation`: customizing.html
 .. _`security documentation`: security.html
+.. _`administration guide`: admin_guide.html