Development and Release Process

From RifidiWiki

Jump to: navigation, search

This document describes the development and release processes for the products in the Rifidi Suite as well as various conventions that developers should be following. This document is intended for developers who are fairly familiar with the Rifidi code base, especially with eclipse and OSGi concepts.

Goals

  1. Standardize the development and release processes for Rifidi Developers
  2. Enable a relatively lightweight release process that is able to be extended later by a fully automatic build tool like maven
  3. Define a common set of conventions to use when checking in, checking out, and tagging code.

This document is not intended to be a "how to" guide for eclipse, but rather to define some common operating procedures around how code is developed and released in the Rifidi project

Concepts

Target Platforms

About Target Platforms

A target platform is the set of base plugins that your application depends on. Normally when you build a project in eclipse that uses eclipse functionality (SWT, JFace, etc), eclipse gets that functionality from the plugins and features folder located in you eclipse installation. Therefore it is using your eclipse base installation as your target platform. However, it is possible to define your own target platform for the application you are building rather than relying on the default one. Doing this is useful for several reasons

  1. It creates a separation between the plugins you use in your developing environment and the plugins used by your application. This means that you can, for example, upgrade the eclipse you use as your IDE without upgrading the plugins used by your application. Also, you can add plugins to your application without using them in your IDE. For example suppose you want to use the GEF bundles in your application, but you don't want them inside your eclipse development environment.
  2. A closely related advantage is that you can limit the plugins that are available to your application. If you use the base eclipse installation as your target platform, all of the plugins are available to your application. This makes it easy for application developers to simply add dependencies as they like. However, because an added dependency often means changes to other things, such as build processes, adding bundle dependencies should require some deliberation. Having a target platform simply makes bundle dependencies more explicit.
  3. It is possible to place more than just eclipse base plugins in the custom target platform. You can put bundles in there that you have built that are required for you application. This means that you could put, for example, tagged, stable versions of all of the plugins in your application in your target platform. Then when you need to modify a plugin, you can check out the source code from svn. Because eclipse will look in your workspace before it looks in your target platform, it will find that plugin first. This means developers only have to check out code for bundles that they want to modify, which forces him to think about the code that he wants to write. It also means that, because the code in the target platform is tagged and stable, that if one developer checks in code with a change in it that breaks another plugin, that other developers can continue developing with the stable bundles in the target platform.

Target Platforms in Rifidi

Each major Rifidi project in the Rifidi suite should have its own target platform. For example, there is a target platform called org.rifidi.emulator.target. There should be a directory in the target platform called rifidi where all the bundle binaries that are required for that particular project. In addition there are various target platforms used for deploying products, such as org.rifidi.rcp.target.

Bundle Versioning

All bundles in OSGi have version numbers, with the following form 1.2.3, where 1 is the major version, 2 is the minor version, and 3 is the point version. The Rifidi project uses the following conventions:

  1. The major version should be increased only if there is a major API change for the bundle. A major version change usually involve a change that would break another plugin, for example, changing a method signature. A good rule of thumb is that if bundle X depends on bundle Y and bundle X was modified as a result of the changes to bundle Y, then bundle Y had a major API change. For example, suppose bundle Y has a method called foo(). Suppose bundle X, for some reason, needs to pass in a string to foo(). So you modify foo() to become foo(String string). This was a major change in bundle Y.
  2. The minor version should be increased if there is a minor API change. A minor API change is something that would not break existing compatibility with dependent bundles. For example, adding a method signature to a class, or adding more functionality to the bundle in the form of classes is a minor API change. The key difference between a minor and a major API change is that a minor API change will not cause other bundles that depend on it to break.
  3. The point version should be increased for small internal changes and bug fixes. These changes do not involve the bundle's API.

Note that it is not necessary to change the version numbers any time you submit. It is only necessary to modify the version numbers if the changes are relatively well tested and stable. For example, you might want to make some changes then submit the changes back to the trunk for another developer to look at, test, or modify. If you don't expect weight loss supplements to make any further changes to the code, then you should modify then version number

Dependencies

In OSGi there are two ways of specifying dependencies.

  1. Require-Bundle should be used for dependencies to bundles that contain code which is written for the Rifidi project. Usually, this is anything that begins with org.rifidi.*.
  2. Import-Package should be used for for dependencies to bundles that do not contain code that is maintained by the Rifidi project, for example, to third party libraries such as log4j, cajo, or eclipse base plugins such as SWT or GEF. It is also possible to find certain third party libraries that have already been made into a plugin at the eclipse eclipse orbit project.

The advantage to using Import-Package over Require-Bundle is that Import-Package is more flexible. The plugin is more flexible because it could use any loaded OSGi bundle that exposes that particular plugin with the given version constraints. In addition, because importing packages is more granular than requiring bundles, it makes the developer think a little more about the dependencies his is using.

In both Require-Bundle and Import-Package dependencies, the minimum version must be specified. It is also recommended that the maximum version be specified as well. This is because it is possible for more than one bundle with the same name but different versions to be loaded by OSGi during runtime. So if an incorrect version of a bundle is already loaded, but the bundle that requires that bundle does not specify the version it needs, bad things might happen.

A good way to specify versions is to have the minimum version be inclusive and the maximum version be exclusive. For example, if the minimum version is set to 2.2.0 inclusive and the maximum version is 2.3.0 exclusive, then any version starting with 2.2 is acceptable. This makes sense, because we have adopted a versioning scheme where the minor version number signifies a minor API change.

SVN Structure

There are four repositories used in Rifidi:

  • rep-external - main repository for Rifidi development
  • rep-internal - repository to hold code that is necessary, but that should not be released
  • rep-edge
  • sandbox - repository to hold projects for playing around with

rep-external and rep-edge are the main repositories for Rifidi development. They have the following structure:

  • org.rifidi.binary
    A project containing all the bundles as binaries for rifidi. It is used so that you don't have to check out the code when developing or releasing
  • readme
    a project that contains a text file that describes what all the bundles in trunk are used for
  • rifidi
    The code for the Rifidi project
    • branches
    If a developer want to add a major feature that requires alot of time, and he wants to check the code into the svn before he is ready to integrate the code back into the trunk, he can check the code into the branches directory
    • tags
      When a stable version of a bundle is reached, the code should be placed in a sub directory that has the name of the bundle's version. See Tags for a description of when to create a new tag
      • org.rifidi.bundle.a
        • 1.0.0 - contains eclipse project
        • 1.1.0 - contains eclipse project
        • 2.0.0 - contains eclipse project
      • org.rifidi.bundle.b
        • 1.0.0 - contains eclipse project
    • trunk
      The trunk contains the latest code for each bundle. It might be unstable. All changes to code should be made to the bundles located in the trunk
      • org.rifidi.bundle.a - contains eclipse project
      • org.rifidi.bundle.b - contains eclipse project

Tags

The purpose of tagging a bundle is to save the code at a stable point so that future changes can be reversed if they introduce a bug that older versions did not have. A new tag must be created in svn when either the major or the minor version number of the plugin is incremented. It is not required to create a new tag when the point version number is incremented, but it is ok to do so.

Product File

A product file defines the required plugins for a particular project. It is used to build the project. It is important to keep this file updated as new plugins are added or old ones are removed.

Processes

This section defines a few procedures that should be followed when developing code for the Rifidi project

Setting up a development environment

  1. Download the target platform for the project you are working with. For example, if you are developing a plugin for emulator, you would download the target platform for emulator
  2. Download org.rifidi.binary
  3. Download any bundles that you need to modify. For example, if you are making changes to the alien reader, download org.rifidi.emulator.reader.alien
  4. Set the target platform as the target platform for the workspace
  5. Clean the workspace

Modifying an Existing Bundle

Suppose you have modified an existing bundle and the changes are relatively stable and tested, and you are ready to integrate them back in with the rest of the project.

  1. If the changes you have made require a version change make sure that is done
  2. If you had to change the major or the minor version number, create a new svn tag for the plugin.
  3. Export the bundle as a binary bundle using the export wizard on the Manifest.MF file for the plugin
  4. Add the bundle to org.rifidi.binary
  5. Submit bundle changes and target platform changes back to trunk.

If you have made changes to a bundle but are not ready to integrate them back with the rest of the project, you can do one of two things:

  1. Submit them back to the trunk, but don't change the version numbers. This is ok to do because everyone else should be using tagged stable bundles in the target platform.
  2. Create a folder in the branches directory and put it there. Only do this if multiple developers are modifying the same plugin at the same time.

Creating a new Bundle

To create a new bundle called org.rifidi.xyz:

  1. Create a new plugin project with the name org.rifidi.xyz
  2. In the Manifest.MF file
    1. Add 'Pramari, LLC' as the provider
    2. Give the bundle a name such as 'Rifidi xyz'. It is important that the first word is 'Rifidi' so that all bundles created as a part of the Rifidi project are easy to locate when there are alot of bundles installed as part of an eclipse installation.
  3. Write the code for the plugin
  4. Follow the steps for Modifying and Existing Bundle
  5. If you tagged the bundle and added it to the target platform, then make sure you add the new bundle and its dependencies to the product file
  6. Add an entry to the readme project at the top level of the svn

Releasing a Product

  1. Download the rifidi build target platform and set it as the target platform for your workspace
  2. Download the project that contains the product file for the project you are trying to build
  3. Export the project using the export wizard
Personal tools