With this blog I would like to offer an overview about building SAP HANA Cloud Platform applications by using an open source based continuous integration development infrastructure.
When you start with cloud application development you are usually not very interested in your build environment right from the beginning. But as soon as you have finished your first steps and implemented your first proof of concept the build topic becomes more important – at least when being confronted with questions like:
- How to test run unit and integration tests for applications?
- How to ensure that fixes can be done fast and to avoid regressions?
- How to deploy applications in a continuous and automated way to the cloud?
Having these questions in mind you probably do cloud application development using agile software methodologies to profit from much faster time-to-market.
So, on one hand we do have the known build infrastructure requirements like: building applications, running automated tests, supporting bug fixing processes and running automated deployments. These requirements belong to the core functionality of every build infrastructure, but additionally we do have demand for a light-weight infrastructure supporting agile and fast processes.
A few years ago, when we started with the development of SAP HANA Cloud Platform, we faced very similar questions inside SAP. After a phase of analysis we decided to setup a build infrastructure based on well-known open source components for two major reasons:
- We wanted to profit as much as possible from existing build solutions, provided by a huge community.
- We wanted to provide as much flexibility to our development teams as possible.
Build and Dependency Management
We decided to use Maven as our build tool since it’s open source, has a remarkable community, consists of a small core with a huge plugin ecosystem and finally because it supports versioned components. Maven plugins provide solutions for most of the existing build challenges. In the rare case where functionality is missing we can implement it as Maven plugins on our own.
Describing the advantages and usage of versioned components would be beyond the scope of this blog and therefore I can only scratch the surface here. In Maven any built artifact has a version, which is defined in a pom.xml file. Such versioned artifacts are published (deployed) into a maven repository from where they can be consumed by other builds.
Development Builds and Release Builds
In general, Maven distinguishes between development versions and release versions. Development versions end with ‘-SNAPSHOT’ e.g. 1.3.0-SNAPSHOT and are expected to be transient. Release versions like 1.3.0 are expected to be immutable and adhere to Semantic Versioning guidelines.
Let’s assume you want to add a new feature to your cloud application. During the development of a new feature you usually build development versions of your application. You deploy them to your cloud development account (e.g. with the SAP HANA Cloud Deployment Plugin), where the application is tested. With every new build the prior development version is replaced by the latest one. Using transient development versions fits well during the development phase, when you are not very interested in intermediate results. But as soon as you have finished your new feature and want to deploy it to your quality or production account in the cloud, it is strongly recommended to use immutable components, which can be reproduced and fixed. Therefore you build a release version (without ‘-SNAPSHOT’) of your application.
Additionally to the build of that release version you should create a tag in your source code management system (SCM) marking the source revision, which corresponds to the created release build artifact. This helps to find the correct source revision when you need to apply fixes later on.
Source Code Management Systems
This raises the question which SCM to use with an open source based development infrastructure. From my personal point of view it is a matter of taste. If you do have a source repository already, you most probably want to continue to use it. Inside SAP we did the same. We reused our existing SCM but in order to provide more flexibility and a code review system to our development teams we decided to go for Git and the code review system Gerrit.
In Gerrit developers comment, discuss and vote on proposed changes. Additionally build servers vote on any proposed source change in Gerrit by running pre-integration builds and automated tests. Only after a change is reviewed and accepted by other developers and the build and tests are successful, a proposed change is pushed into Git. This review process helps us to keep the code quality high. In addition it helps developers to get a common understanding of quality code.
For build servers we separate central build servers and local team build servers. Team build servers produce, test and deploy Maven development artifacts (SNAPSHOT-Versions). The centrally provided build servers produce release versions and apply product standard rules to the build process e.g. restrict dependencies required for the build.
Team build servers are hosted by individual development teams and it’s their choice which build server to use. Most teams use Jenkins, but also Hudson and TeamCity are also used, just to name a few. Team build servers act as continuous integration servers in the development infrastructure. They listen on SCM change events and build those changes right away to provide immediate feedback to developers.
Central Build Servers
For our centrally provided servers we decided to take Jenkins for similar reasons we picked Maven. It consists of a small core and tons of plugins provided by a strong community around the globe which takes care of its products.
Let me add here that the separation of local and central servers might be not required in your development organization. Inside SAP it helps us as it provides a good balance between flexibility and scalability, but your requirements may vary.
One mandatory component is still missing in the picture. In the Maven section above I told you that Maven artifacts are published into a maven repository from where they can be consumed by other builds. Usually a Maven build process does not just use a single repository, but several repositories. Those repositories are hosted on a repository manager. We decided to use Nexus as repository manager and this was a good choice. Nexus supports permission restrictions on the hosted maven repositories, configuring the lifetime of SNAPSHOT artifacts, and it supports a distributed setup with instances residing in different locations.
Exemplary Continuous Delivery Process
Now as we discussed all required components of our development infrastructure, I’d like to show the typical workflow of a developer, in which a new cloud application feature is implemented and released.
- A developer clones the existing cloud application from Git into eclipse using egit. The cloned sources contain a pom.xml file as build descriptor e.g. with current version 1.3.0-SNAPSHOT.
- After implementing the new feature and testing it on the SAP HANA Cloud local runtime, she/he probably wants to execute a maven build using m2eclipse to check that everything is ok. For this build Maven resolves the required dependencies and build plugins from Nexus and builds the sources inside Eclipse.
- Once the build has succeeded the developer pushes the change to Gerrit where it is reviewed by other developers. The team build server automatically clones the sources from Git and resolves maven dependencies from Nexus. After both sides vote that the proposed change is ok, the developer submits it into Git via a corresponding interface within the Gerrit code review system.
- Now the change is available in the development branch of the project. Next the team build server is notified to build the development branch of the cloud application. This build compiles the sources, runs all unit tests and publishes the build results to Nexus from where it can be deployed to the cloud development account.
Keep in mind: Since the project version ends with SNAPSHOT the version is transient and will disappear from Nexus after few days/weeks. Luckily our developer is a good one 🙂 and hence all tests on the development account are successful. Therefore she/he decides to publish a new release version of the cloud application.
- She/he updates the product version from 1.3.0-SNAPSHOT to 1.3.0 and executes the release build, which deploys the build result to nexus and tags the released version in Git. This can be done automatically. The release version 1.3.0 is immutable and will never disappear from Nexus.
- Afterwards that version can be deployed to the quality or production account. If bugs are detected fixing is possible since the artifact version 1.3.0 has a corresponding tag in Git which can be used.
I hope this blog helps to get an overview about an open source based development infrastructure. As always in the agile world feedback is welcome and fast feedback appreciated ;-).
PS: If transparency about code quality is desired, consider Sonar as additional component in your development infrastructure.