This is a high level overview of managing the source code of your mobile application project in the IBM MobileFirst Platform (MFP). You should come away with enough foundational knowledge to start implementing Source Code Management (SCM) in your own project.
Why manage source code?
There are many varied reasons for using an SCM system. Some reasons are more relevant to developing code as part of a team. SCM helps:
- Share code with others
- Coordinate and share changes with others
- Understand what work has been done, when, where and by whom
But, SCM provides a lot of value, even if you are a development team of one. SCM helps:
- Organize your changes into a series of steps
- Identify the codebase for all releases
- Compare versions of code
- Review history of changes
- Compartmentalize or package specific feature or bug fixes for distribution
There are many, many reasons why SCM makes sense and those reasons apply to mobile development project as much as any other type of project.
SCM and the IBM MobileFirst Platform
There are basically two ways you can develop software for the IBM MobileFirst Platform: using MobileFirst Studio (hereafter referenced as simply “Studio”) or the MobileFirst Command Line Interface (CLI). The concepts I will be discussing apply to both. Most SCM tools provide a CLI that can be used to issue necessary commands to commit your changes, create branches, etc. if you are not using Studio.
Studio is based on the Eclipse IDE. This makes it possible to use any Eclipse SCM tool integration directly from the IDE. These Eclipse integrations provide some really useful graphical tools that help you visualize the changes to your code and merge conflicts when necessary. If the IDE integration doesn’t do everything you need, you can revert to the CLI when you have to.
For this article, I am going to focus on Studio. I’m also going to focus on the SCM system Git. Git is quite popular these days as it is lightweight and open source. The concepts I will discuss in Git can be applied to other SCM systems as well.
IBM provides some guidance on source control for Mobile First Platform in the Knowledge Center at http://www-01.ibm.com/support/knowledgecenter/SSHS8R_7.0.0/com.ibm.worklight.dev.doc/devref/r_integrating_with_source_contro.html. This page is the place to start when you are considering implementing SCM on your project. The hierarchy diagram depicts the structure of a MobileFirst project. It is important to understand this because not all files in the project should be put under SCM control.
Types of files in MobileFirst projects
Git provides a mechanism using files called .gitignore that enables you to ignore or just not manage certain files. Why wouldn’t you control all files in the project? Let’s break the project down into categories of files to understand that better.
The IBM documentation doesn’t use the term “derived” file. That’s my own term for files that are produced or generated by MFP when you perform an operation such as build or deploy. The www folder within the native folder of each environment is a good example. When developing a hybrid application, MFP enables you to create code once, but use it in all your environments. The tools used to build the app (such as the SDK for Android or Xcode for iOS environments) might require all hybrid content to exist within the structure of the native folder. The hybrid content from the MFP common folder is copied to the environment’s www folder during the build phase. Therefore, there is no benefit to managing the content of the www folders within the environments. That content just gets overwritten with each new build. If you accidentally deleted it, nothing is lost. It is best to just ignore all these files and not put them under SCM control.
Derived but Required Files
Things get a little trickier when you start considering how you will share your project with others. There is a category of files whose contents are derived, but MFP only generates them when the environment is first created. The files are not generated or copied with each build or deploy. However, these files are required to exist by the build tools such as Xcode. If you don’t include them in SCM and your teammate grabs a copy of your code, the project won’t build without them.
Let’s look at an example. I am building a hybrid app named mySampleApp in an MFP project named mySampleProject that will run on iPad. When I first create the iPad environment, MFP creates the file mySampleProjectmySampleAppIpad-Info.plist in the iPad native folder. This file contains, among other things, the app version number string. If I change the app version number in the application-descriptor.xml file and rebuild, the *Info.plist file is changed and I have a new version to check into in SCM. I would like to avoid that since the version number in the *Info.plist file is derived. But, if I don’t add the *Info.plist file into my SCM system and my teammate tries to build without this file, the build will fail. The file is not automatically created by MFP if it doesn’t exist.
This leads you to a bit of a quandary: you don’t want to control these derived files, yet you need to add them to source control in order to maintain a complete, buildable project.
The best approach is to put them under source control and live with the minor consequences. Those consequences are that each time certain changes are made by developers, those files show up as changed. You can often decide to do nothing with the change and you will be fine because the build will regenerate the content within the file.
As mentioned earlier, Git provides a way to specify files you want to ignore. You create one or more .gitignore files and include the list of derived files you don’t want to be put under control. Git supports the notion of multiple .gitignore files spread across the file system, the effects of which are cumulative. As a best practice, I would recommend against this. Keeping a single .gitignore at the root of your MFP project is sufficient and it makes it obvious where to go if you need to make changes to the .gitignore file.
Andrew Ferrier has created a great template .gitignore file (https://github.com/andrewferrier/mfp-gitignore). You can download and use the file freely and he welcomes any feedback or improvements.
Cleaning up the mess of a bad start
You probably won’t get the .gitignore right the first time. That’s fine – you can tweak as you go. But, you need to know that adding a file to .gitignore does not remove it from Git. If the file was already in Git, the .gitignore file has no effect.
The best course of action in this case is to merge everything back into a single branch, fix the .gitignore file, then remove files from source control as needed. Andrew Ferrier has also created a tool that will help you automate the task (https://github.com/andrewferrier/git-utilities/blob/master/gitaliases ).
An effective branching model
Once you have your code in Git, you need to decide how you are going to work with it. Git is very flexible so you really need to establish some conventions and procedures so your entire team knows what is going on.
Branching and tagging conventions are probably the most important things to agree upon. Again, there are many ways you could do this, but one of the most widely accepted models is one proposed by Vincent Driessen several years ago (http://nvie.com/posts/a-successful-git-branching-model/ ). This model may be more than you need on a small project, but there are lots of good ideas here you can glean.
Daniel Kummer has created some Git extensions that automate Driessen’s model (http://danielkummer.github.io/git-flow-cheatsheet/ ). This is nothing you couldn’t do through adhering to your established conventions, but it helps automate and enforce it.
In the next post, I will walk through an example using IBM DevOps Services as the master Git repository for the project.