This is the final post in our CI pipeline series. This time, we talk about how the pipeline stages loggregator-related changes to cf-release to other cf-release consumers (e.g. other teams) in a minimal-impact way. We also show how the pipeline uses git to rebase and merge the various repositories and branches that flow into it.
As indicated in this series’ first post, the pipeline’s final output is a “bump” of loggregator in cf-release. In other words, a commit in the cf-release repository (specifically, its “develop” branch) updates the loggregator submodule’s reference to the version which has passed all the testing and acceptance stages.
Sometimes, however, not all the changes related to a particular feature are contained within the loggregator repository. Some changes also require changes made directly in cf-release, such as changes to other components’ configuration that need to interface with loggregator.
Therefore, we also needed some way to stage these cf-release changes in our pipeline and pass them through testing/acceptance stages, before releasing them to other cf-release consumers.
We created a separate cf-release branch named “lamb-develop” for staging these changes. The pipeline’s integration test stage now includes three inputs, as illustrated below: The loggregator/master commit SHA to be tested, the cf-release/lamb-develop SHA to be tested, and the current SHA of cf-release/develop. The integration tests start automatically whenever any of these three versions change.
Before running the integration tests, the pipeline prepares the working directory as follows:
Once all the integration tests and acceptance stages have passed, the pipeline merges the locally modified lamb-develop branch back into develop (which is guaranteed to resolve as a fast-forward merge due to rebasing earlier,) and pushes develop into Github.
Drawbacks & Benefits
The primary benefit of this approach, compared to other approaches we tried before, is a clean commit log in cf-release/develop process. We see only those commits which were manually created in lamb-develop, and no additional merge commits. Also, we see only a single “bump loggregator” commit, instead of multiple commits, even if the integration tests ran multiple times before the acceptance stage.
The downside is that certain changes in cf-release/develop can cause the automatic rebase step to fail due to conflicts. If this happens, lamb-develop has to be fixed manually to resolve those conflicts. This isn’t too different from life before the pipeline: Developers would create short-lived branches in cf-release, and would be responsible for resolving merge conflicts with the main branch. In fact, we effectively treat lamb-develop as a short-lived branch by occasionally resetting it to the same SHA as develop, whenever all of the lamb-develop commits have been rebased and pushed into develop. This ensures that we won’t ever see conflicts unless we’re actively using lamb-develop to stage a change.
About the Author