Best Practices@JDI : Branching Patterns & Use Cases
This article describes the usage of Tracks (in JDI) to address a few branching use-cases. A simple branching pattern is first used to indicate what is possible with Tracks, and the two concrete use-cases that follow provide detailed descriptions on how to structure a JDI landscape to develop multiple releases of a product.
The article assumes familiarity with JDI related abstractions, espectially the functions of CMS surrounding setting up and maintaining a landscape (like Track Creation, Import, Assembly, Approval). It also expects the reader to be familiar with aspects of Software Configuration Management (SCM) surrounding branching.
General SCM terms used:
Mainline : Code-line where main development is done.
Branch : Code-line parallel to Mainline; used for parallel (concurrent) development.
Merge : The operation of bringing together changes made in two branches.
The following extract from a paper on Branching Patterns describes two kinds of branching models supported by SCM (or Version Control) tools:
Most VC tools supporting branches do so at the granularity of a lone file or element. The revisions and branches for each file form a version tree which depicts the evolution of a single file. This is called file-oriented branching. Branches are used and organized and viewed in the context of a single file. While there may be a loose or coincidental similarity between the version trees of different files, file-oriented branching focuses primarily on physical modifications to individual files as the unit of change and change-flow.
But branching is most conceptually powerful when viewed from a project-wide or system-wide perspective; the resultant version tree reflects the evolution of an entire project or system. We call this project-oriented branching. With project-oriented branching, branches are used and organized and viewed in the context of an entire project, product, or system. Project-oriented branching imposes a more or less uniform structure on the version trees for all the files in the system. Instead of emphasizing modifications to individual files, project-oriented branching focuses primarily on the flow of logical changes across the entire system. Logical changes flow through and between streams of work in which product and component versions are integrated, built, baselined, and released.
DTR supports branching at the level of a Workspace (which is a collection of versions representing Files and Folders) – so in this sense it follows the Project oriented branching model mentioned in the above extract. In the context of scenarios using all parts of JDI (DTR, CBS and CMS), branching happens at the level of a Track. This article describes Track-based branching, and hence is not applicable for the scenario using only DTR (For this scenario – using only DTR for versioning – branching involves creating a new Workspace – that represents a branch – and integrating Closed Activities from the source to this target Workspace).
The branching pattern and use-cases listed below describe different Track-based landscapes with the following options for propagation (transport) of sources between them (In traditional SCM terminology, these options describe the different ways you can “merge” changes across different “branches”):
(A) Automatic Propagation
Automatic Propagation between tracks is achieved through Track Connections (which can be configured from the CMS Landscape Configurator). There are two kinds of connections possible:
Transport : This connection type transports all the Assembled and Approved SCAs to the target track. Thus, the granularity of transport is an SC.
Repair : This connection type transports Change Requests that were released (from the “Transport View” of the NetWeaver Developer studio). These Change Requests are placed in the import queue of the target track’s Dev system. Thus, the granularity of transport here is a Change Request (which can contain one or more activities pertaining to an SC).
(B) Manual Propagation
You can also manually forward SCs that have been Assembled and Approved in a Track. (The forwarding functionality is available in the “History” view of the “Approval” tab in the CMS Transport Studio.)
Note: All the above transports will lead to “Integration Conflicts” for files modified in both tracks. These conflicts can be viewed and resolved through the “Integration Conflicts” view in the DTR Perspective of NetWeaver Developer Studio. To resolve these conflicts, you can (a) accept existing version or (b) accept incoming version or (c) perform a 3-way merge.
Basic Pattern: Development in parallel branches
Summary: Branch from Mainline, develop in parallel and merge back into Mainline. (This allows you to isolate development of some functionality in a parallel branch, while continuing to develop in the Mainline).
Pre-requisites (Initial State): Existing track (Track A, representing Mainline) containing currently ongoing development.
Steps for branching:
(1) In Track A, assemble and approve the SCs containing sources that need to be branched.
(2) Create a new track (Track B) as a copy of existing track. (Use “Save as..” option in CMS Landscape Configurator).
(3) Forward the approved SCs from Track A to Track B.
(4) Import these SCs into the Track B.
(5) Import development configuration of the “dev” system of Track B into your Developer Studio -> this environment represents the branch where you can develop in parallel to the Mainline.
Steps for propagating changes back to Mainline:
Option A: Frequent propagation using “Repair” connection
(1) Create a track connection of type “Repair” from Track B to Track A
(2) While developing in Track B, check-in and activate your changes, but perform a release (from the “Transport View”) only when you wish to propagate your changes back to the Mainline (Track A). The released Change Requests will automatically be transported into the DEV system of Track A.
Note: Use this option if you wish to merge back to the Mainline on a regular basis.
Option B: Automatic propagation after approval of changes
(1) Create a connection of type “Transport” from Track B to track A.
(2) Each time you wish to merge changes back to the Mainline (Track A), assemble the SCs and approve them. Then import them into Track A.
Option C: Manual propagation
(1) Each time you wish to merge changes back to the Mainline (Track A), assemble, approve and forward the SCs. Then import them into Track A.
(1) A Track is a very coarse granular abstraction for branching. Creating a new track to represent a branch implies creating a new environment for all the SCs developed in the track – this may be too much when the parallel development involves, for example, only a few files in a DC. One way around this limitation is to keep the SCs small and develop each SC in a separate track (and bring them together in a final track) – but this increases the complexity of the track landscape.
(2) “Merging” changes across code-lines requires support from appropriate merge-tools. Currently, DTR detects conflicts at the file level and provides file-based merge tools for such conflict resolution. Merge tools for model-based development (using WebDynpro, for example), are currently not available.
Use Case 1: Parallel development in old and new release branches
Summary: After release of product developed in one branch, continue development (or maintenance) on side branch, in parallel to new release development in original branch.
Pre-requisites (Initial State): Existing track (Track DEVLP) containing sources of a release (which will now move into maintenance phase)
(1) For branching, follow the steps listed above in the Basic Pattern. (The second track is referred to as the MAINT track here).
(2) To ensure constant flow of the changes made from old release branch into the new release development branch, create a connection of type “repair” from Track MAINT to Track DEVLP. Once such a connection is setup, the release of Change Requests (from the “Transport View” of the NetWeaver Developer studio) in the MAINT track will result in the Change Request being available in the import queue of the “dev” system of the DEVLP Track. The conflicts that are caused by parallel development must be resolved in the “dev” system of the DEVLP track.
The automatic transport of changes from older to newer release code-lines is a feature that eliminates the need for “double-maintenance”. In most Version Control tools, such fixes must be manually re-implemented in all the relevant code-lines, and this can be error-prone. By configuring “repair” connections between Tracks, you only need to implement the fix once. (Note: If the fix is not relevant in new release, that Change Request can be deleted from import queue of the target track.)
Use Case 2: Multiple maintenance branches in parallel to the development branch
Summary: Maintenance is done in multiple branches (each corresponding to one state of the older release), while new release development goes on in parallel.
Pre-Requisites (Initial State): Two tracks – one for new release, and another for maintenance of older release.
This use-case will highlight the way a company can work on new release development and also in parallel develop Support Packages (SPs) of the older releases. The requirement is simple: there will be an SP delivered every few months, and the company needs to support two older SPs (i.e., provide patches for these delivered SPs, if needed).
The initial state, as described above, is displayed below:
In this landscape, the development of the new release happens in the DEVLP track, while the changes for the next SP of the older release are being made in the 1.0_SPx track. The “repair” connection ensures the propagation of fixes done in the old release to the new release track.
When the SP is ready for delivery, a new track 1.0_SPx-1 is created – this will be track where this delivered SP will be maintained (while the development of the next SP will proceed in the 1.0_SPx track). This is shown below:
To reach such a state, you need to perform the following steps:
1) Create a copy of track 1.0_SPx (using the “Save as.” function in the CMS Landscape Configurator) and name it 1.0_SPx-1
2) Forward the Assembled and Approved SCs from 1.0_SPx to 1.0_SPx-1
3) Import these SCs into the 1.0_SPx-1 track.
4) Setup a track connection of type “repair” from 1.0_SPx-1 to 1.0_SPx
Now, you can develop the next SP in the 1.0_SPx track, and for patches needed in the released SP you can use the 1.0_SPx-1 track
When the second SP is ready for delivery, a similar process is followed. This is shown again in the following diagram:
This will be the final track structure that will meet the original requirement (of developing a new release and maintaining an old release with the ability to patch two released SPs). When the third SP is released, the contents of the first SP (until then maintained in track 1.0_SPx-2 will be overwritten with the contents of the second SP which is present in track 1.0_SPx-1). In this fashion, you will retain the ability to patch the previous two released SPs (If more SPs need to be maintained, more tracks are necessary – but the pattern will be the same as described above).
The use-cases described above describe how to configure a Track-based landscape to achieve parallel development of SCs across multiple releases. Aspects surrounding layered development (involving working with multiple SCs with different release cycles) are beyond the scope of this article. However, the basics of track configuration and connections described here provide the foundation for building more complex landscapes.