Tips for Implementing a Software Release Process

Implement a release process for managing and controlling software application releases

Al-Waleed Shihadeh
Mar 11, 2020 · 12 min read
Photo by Dan Gold on Unsplash

Software Development process is not complete and mature without a well-defined release process for the software applications. Every software application needs to be delivered or deployed at some point in time and for agile projects, this is happening more often. Therefore, there is a need to maintain software quality across the application releases to avoid deploying untested or malicious code to production environments.

Defining a release process for software applications helps in ensuring that software releases maintain a constant release quality. In addition, software changes and new features are traceable or can be correlated to specific releases easily. As a result, changelogs and release notes are easier for a generation.

I this post, I will discuss some of the most important topics and areas regarding defining a release process for a software application and will provide some tips for the implementation of these topics.

Project Workflow:

  • Centralized Workflow: This workflow is suitable for projects and teams who are migrating from SVN such as Subversion. This workflow is utilizing a central repository with a single branch master, Engineers clone the repository, checkout master branch locally, develop new features and then merge the local master branch into the origin master branch.
  • Git Feature Branch Workflow: This workflow is almost the same as the centralized workflow except it is designed to shift the development process from the master branch to the feature branches. Here we still have one centralized repository and a master branch. However, the development of new features should be done on dedicated branches. Therefore the development process will be done using the following steps:

→ First, the Engineers need to clone the repository.

→ Then create new branches from the master branch (These branches are called feature branches).

→ After a successful implementations engineers can issues pull request to discuss the change and merge it back to master.

The main advantages of this workflow over the centralized workflow are: First it is possible now to keep master clean and free of bugs and second it is also possible that more than one engineer to work on the same feature branch without disturbing the main codebase (This can be done simply by pushing the feature branch to the origin and all contributors will be able to checkout and use that branch).

  • Gitflow Workflow: This workflow is designed to be used with projects using a scheduled release process. The workflow is defining the actions that need to be done during the release processes as well as how to perform these actions and how to contribute to the source code. Below is a brief overview of key items of the workflow
  1. Two branches are used for the development: the master branch is the branch that is used to store the official release history and used for the deployment and only should include stable code versions. The other branch is the “develop” branch which is the main repository branch where all new features are merged.
  2. Multiple types of branches are used during the software development cycle such as feature branches, release branches, and hotfix branches.
  3. Feature branches are created from develop and merged into develop branch when they are completed.
  4. Release branches are created from develop and merged into master and develop branches when they are successfully tested and approved.
  5. Hotfix branches are created from master branch in case of a bug in master and merged into master and develop branches when they are done.
  • Forking Workflow: This workflow is different from the previous workflows fundamentally because it utilizes more than one repository. Each contributor will have to fork the main repository often called upstream and have his own copy of the repository. As a result, each contributor will have two copies of the repository one local copy one remote copy. This will allow the contributors to work independently and there is no need for pushing to a centralized repository unless there is a need for integrating the changes into the upstream . Also, there is no need for granting permissions for every contributor to the upstream repository. This workflow is used mostly in public open-source projects.

Now we have an idea about the git workflows The question is, which one is the best and which one should we use?

The answer to the above question is highly dependent on what is the project needs and what we are trying to achieve, plus the above workflows are not the only ones and we can define our workflow based on our needs. Below I will present a custom workflow that can be also used for managing a release process.

Hybrid workflow: I called this workflow hybrid because it is based on both the Gitflow and the Forking workflows. Below are the main key points that describe the workflow and the actions needed during the release cycle.

  1. Each new project repository should have two branches, the master branch representing the latest version of the software and the “develop” branch which is the main branch of the repository and where all new changes or features need to be integrated.
  2. Engineers who would like to contribute to the project need to fork the project repository to their namespace. The forked repository will be called the origin while the project main repository will be called upstream. The upstream remote will be used by all contributors and source code integration will be done on it.
  3. The upstream repository should only have the following branches at any given time: master, developand release branches.
  4. Contributors will start by cloning the project repository form their fork and adding the upstream remote to the project.
  5. New feature branches should user upstream develop branch as a base branch. It is important to pull all changes from upstream using the command git pull upstream develop and then creating the feature branch form the develop branch git checkout -b feature_x upstream/develop.
  6. After completing the work on a feature branch pull requests need to be created to merge the changes for the contributor repository to the upstream repository.
  7. Release branches need to be created form the upstream develop branch and pushed to the upstream repository.
  8. In case a bug found in the release branch a bugfix branch is created for the release branch and once the fix is complete the bugfix branch is merged back into the release branch.
  9. Once the release is done, The release branch needs to be merged with master branch and the master branch, then tag the master branch with the release tag and merge the master branch into develop branch.
  10. In case a bug is found in the productions environment a hotfix branch needs to be created form the master branch and once the fix is implemented and tested the hotfix branch needs to be merged into master branch, tag the master branch and merge it into develop.

Changelog

Implementing a change log process can be very simple, however, it can be also very complicated. As a simple and straight forward solution that does not require a lot of resources, the changelog can be implemented by a single text file added to the project repository. This file should include a list of all the changes introduced to the source code. We can improve and enhance the quality of the changelog file by following the below points

  • Ensure the change log process by requiring the update of the changelog file with each of the pull requests that introduce a change in the source code.
  • Define a schema or a template for adding new changes to the changelog file. For instance, each change item should have the following required attributes:

→ A category which can be one of Improvement, New Feature, BUgfix, or Refactoring (you can define these categories based on your needs).

→ The severity of the change indicates if the change is introducing breaking changes for the future release or not. do we change the application API with this change?

→ A clear description of the change.

→ Any special instructions (if there is any) that need to be applied for upgrading the software application.

You can argue that we can use the git history for this purpose instead of introducing a new file for the changes on the source code 🤔, I can agree with this statement in case that we keep the git history as clean as possible, by having a clear description of the changes in the git commits and allowing only one commit per pull requestor better per feature. However, I think that is difficult to achieve especially if a large team or multiple teams are contributing to the source code. Moreover, merge and revert commits can introduce some noise on the git history.

On the other hand, The changelog process can be implemented by other tools such as issue tracking tools like Redmine or JIRA. Issue tracking tools provide sophisticated mechanisms or methods to be able to track issues status and progress. Below I describe an Idea for implementing a change log process with such tools:

  • Restrict all the changes on source code to have an issue ticket. NO code or any change is merged without a ticket.
  • Tickets are well defined and have a clear description and acceptance criteria.
  • Once a ticket is resolved or closed, it should be reviewed by the release manager and assigned a fixVersion value, this is an attribute that represents the potential release number that this change will go with.
  • Reports can be created using the issue tracking tools to list all the changes introduced to a given release version based on the value of the fixVersion attribute.

Release cycle

  • Development:

This is the stage where the change in the source code will take place, all the new features, improvements and refactoring tickets should be implemented during this stage. This stage is mostly done by the engineers who contribute to the source code and can be facilities by product owners and product managers to prioritize the tickets that need to be implemented in each of the releases. The engineers should follow the project workflow for integrating new changes into the project source code and the Changelog policy can be controlled either by the release manager or the engineers.

  • Code freeze

The release cycle process is highly affected by the code freeze policy defined in the project. The term code freeze means that the integration of any new features or changes into the release source code is forbidden after the freeze date. 😕 so are we going to stop the development? and how long this can last?.

The development of new features should not be affected by the code freeze (at least if it is implemented properly ). The code freeze is more about isolating a version of the source code that could represent a candidate version of the source code for the next release. This goal can be achieved simply by creating a new branch ( release branch ) from upstream develop branch, Only bug fixes should be allowed to be merged with this branch.

The period needed for the code freeze on the release branch depends on the reediness of the release branch itself. if the release branch has too many bugs and needs a lot of fixes this could take a long time or even the release could be canceled. One the other hand, if the release branch if free of bugs this can take much less time.

Despite the fact the release redlines period cant be estimated or figured out before starting the release process, it is possible to control or minimize the risk of having too long code freeze periods by ensuring the quality of the code. For example, implementing CI/CD pipelines to validate the code quality, execute the unit tests, check for Security Vulnerabilities in each of the pull requests can help in sustaining a healthy “develop” branch that is free of syntax errors at least 😆. In addition, Automating the integrations and performance testing will definitely help in reducing the time needed for testing the release branch (especially in case we need to perform these tests more than once due to bug fixes).

  • Stage deployment:

Once the code freeze takes place and the release branch is created and pushed to the upstream repository, The stage or pre-production deployment could take place. These environments should look like the production environment as much as possible to able to simulate running the source code in production environments.

  • Release Testing

Once the release is delayed to the stage/pre-production environments the verifications of the release branches can take place. In this stage, several actions can be done depending on the resources available for the project. below is a list of some actions that could be implemented here.

  1. Running the integration tests suites against the deployed applications. All features so far should be covered by the unit tests, however, if the software application is is a microservice or an application that can be integrated with other applications/microservice, There is a need to test the integration with these applications. For instance, If the application is supposed to expose an API for mobile applications or consume the APIs from another application, then there is a need to test the uses cases for such cases on the stage environment.
  2. Running E2E test integrations, This is related to the previous point and can be considered as an integration test, but I want to make it explicitly clear that there is a need to perform integrations tests uses cases without the usage mock services.
  3. Manual testing of the deployed applications: QA engineers can perform manual testing to verify the quality of the release candidate version and make sure that there are no bugs in the release. This is a very important step especially if the integration tests and unit tests suites are not covering every single use case or feature supported by the application.
  4. Running Performance Testing: It is also important to make sure that the release is maintaining a certain performance quality. For example, for applications that expose http APIs, it is good to measure how many concurrent API requests that the application can handle and to maintain this across all releases. Performance testing could results in improvements not only on the source code but also on the hosted environments too.
  5. Running Penetration testing: It also important to test the software form a security point of view and try to find any security holes or vulnerabilities in the software application.
  • Packaging

The next stage after completing the release testing and approving the release candidate is to start preparing the release package. Steps that should be done during this stage need to done by multiple engineers (for small projects this could be done a single engineer):

  1. Compile the release notes based on the changelog file or the tickets contributed to the release. The Release notes should be written in a way that is easy to understand and does not require deep technical skills. This is one of the changes between the release notes and changelog. The changelog audience is technical people who need to know what is the exact change on the release and in most cases is only used internally by the contributors to the source code. While the release notes are meant to be read by people who would like to use the software, therefore it should be clear and focus on the added value of the release.
  2. Follow the Project workflow to prepare the project repository for packaging the software. This step can be done by one of the contributors or by the release manager and it may involve merging the release branch with master , then master with develop , tag matser branch with the release version, and maybe creating a release on the git repository.
  3. Execute all CI/CD pipelines that are needed for generating the packages needed for the release deployment. This could involve compiling source code, liking packages, and building docker images needed for the release.
  • Deployment or Delivery

The last step in the release cycle is the deployment/delivery of the release packages. This is dependent on the project itself, in cases that the production environment is managed by the development team the deployment of the release most probably will be included in the release cycle. On the other hand, if the production environment is managed by other entities such as external customers, the deployment will not be part of the release cycle. As a result, the delivery or distribution of the release package to the customer could be considered the last step of the release cycle.

Conclusion

Implementing a release process is a necessity for most of the software development projects. The implemented process should define the release cycle and the actions taken during each of the stages of the release cycle as well as the adopted project workflow. In the next post, I will discuss and show what parts of the release cycle can be automated and to which degree.

Platform Engineering

All Platform, DevOps and service deployment Topics

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store