Moves serves two primary functions: Creating releases and deploying those releases to Containers (a.k.a App Servers). This section discusses the release process in detail.
A typical MIT application (for example a web app) will contain
We will call these MIT apps, MIT components and 3rd party components respectively.
Each MIT app and MIT component exists as a maven project. That project is housed in a subversion repository, using the subversion "trunk, tags, branches" pattern. That is, for every MIT application and every MIT component, there exists a subversion URL which contains the sub-folders "trunk", "tags" and "branches". In general, development occurs in the "trunk" folder, but on rare occasions development can occur in a subfolder of the "branches" subfolder. (See http://svnbook.red-bean.com/en/1.2/svn.branchmerge.maint.html for an overview of the "trunk, tags, branches" pattern.
Within trunk, there will be a file called pom.xml. All builds are built by Maven. The pom.xml tells maven how to build an app/component, and which components that app/component depends upon. While Maven is primarily designed for building java apps and components, plugins exist whereby it can be used to package and assemble other types of components/application. A complete overview of Maven is beyond the scope of this document. However, for those new to maven, the following is a great place to begin learning http://www.sonatype.com/books/maven-book/.
The pom.xml file contains an element called version. In the subversion trunk *the version will always contain the -SNAPSHOT suffix.
For many/most mainstream open source components (for example the Spring Framework), source and binary code is automatically accessible to your project simply by declaring a dependency. For example, to include the Spring framework, we would add the following dependency
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.0.3.RELEASE</version> </dependency> |
Since spring-web version 3.0.3 and all of it's dependencies exist in the standard maven repositories, then we're done.
It is possible to add repositories directly to your pom.xml. However, it is preferable to have a MIT Maven Repository Admin mirror the 3rd party repository. This will make the component available to all projects, while also decreasing network loads. (For the SAIS teams, the mirror configured in the MIT Maven Repository should be visible to the "saisGroupRepo" repository. See your network admin for details.) Once this is done, add your dependency to pom.xml as described in "Declaring dependencies on 3rd Party components - the easy way"..
Sometimes the 3rd party components we wish to use will not exist in the standard Maven repositories. This may be because they are closed source, or because the vendor has their own repository. In this case, you will potentially need to perform the following tasks
Once this is done, add your dependency to pom.xml as described in "Declaring dependencies on 3rd Party components - the easy way".
In our Continuous Integration environment, we desire to always (or nearly always!) build apps that depend on the latest version of a component. This ensures that we know as soon as possible when a change is made to a component that breaks a dependency from another app/component. Thus we want our "trunk" builds to always point to the latest available version of an MIT component. That will be the trunk build of the component itself. To accomplish this we do two things.
Below is an example of an app which specifies a dependency range for the MIT component edu.mit.ist.es.common:sais-common
<dependency> <groupId>edu.mit.ist.es.common</groupId> <artifactId>sais-common</artifactId> <version>[0.0.0,999.999.999)</version> </dependency> |
Below is an excerpt from the sais-common pom.xml file which shos how to configure sais-common, such that applications which depend on sais-common will use snapshot builds when resolving a dependency range.
... <build> <plugins> <plugin> <!-- because this component is a plugin, and because dev and ci builds always point to the LATEST SNAPSHOT, we will configure the maven-install-plugin to consider snapshot builds to the local repo to be a release. --> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> <version>2.3.1</version> <configuration> <updateReleaseInfo>true</updateReleaseInfo> </configuration> </plugin> ... </plugins> ... </build> ... |
When you use Moves to perform a release of a component/application, the following steps happens
Thus at the end of the process, the following changes will have occurred:
Moves provides a facility for creating branches. If you need to branch a project, and if that project might have a release associated with it, then you should use Moves to create a branch.
The answer to this is almost never. Branches add complexity, and changes made to a branch must be applied to the trunk. The process is subject to human error.
Valid reasons for creating a branch include
Let's suppose we have application example-web-app which has version 2.5.3 deployed to production. It depends on edu.mit.ist.es.common:sais-common:3.1.5 (the sais-common component version 3.1.5). Let's suppose it also depends on edu.mit.ist.es.components:example-component:1.2.3 (example-component version 1.2.3). A bug is found in production, and the trunk is not in a releasable state (perhaps we have a bunch of untested changes). We need a release as soon as possible. It is found that the bug fix requires changes to sais-common and example-web-app, but not to example-component.
(In trunk, example-web-app is at version 2.6.0-SNAPSHOT, sais-common is at 4.1.2-SNAPSHOT and example-component is at 1.2.4-SNAPSHOT).
The following will need to occur.
From: <dependency> <groupId>edu.mit.ist.es.common</groupId> <artifactId>sais-common</artifactId> <version>3.1.5</version> </dependency> To: <dependency> <groupId>edu.mit.ist.es.common</groupId> <artifactId>sais-common</artifactId> <version>[3.1.5b1.0, 3.1.5b1.999)</version> </dependency> |
Your project should now build and deploy. Moreover, Moves will allow you to select a branch build after you commit all of your changes.
Once the branch has been created, the release process is much like the trunk release process. However, instead of the versions incrementing from, say 1.2.3-SNAPSHOT to 1.2.4-SNAPSHOT, they will increment from, say 1.2.3b1.0-SNAPSHOT to 1.2.3b1.1-SNAPSHOT. This allows you to perform multiple releases on the branch, until the branch cycle is completed. The corresponding released versions will be 1.2.3b1.1, 1.2.3b1.2, 1.2.3b1.3 etc.
TODO