Percipio.London: How we use the DevOps philosophy in our projects
How we use the DevOps philosophy in our projects
In this post, I want to break down the development cycle and describe how each new feature is carried through from planning, testing, release, and beyond.
DevOps (a combination of Development & IT Operations) enables us to evolve and deliver products more quickly than we could on a traditional release pipeline. Rather than pushing out a release once every two weeks, a month or longer, new features can be delivered to the user as often as required, and bug fixes can be deployed in minutes whilst always adhering to the same automated delivery pipeline.
This philosophy provides agility for our developers by allowing for multiple releases per month, week or day – depending on the project’s demands – whilst still maintaining a strict automated testing and review platform at each stage of the build process.
Having both development agility and simultaneously – and automatically – ensuring defective builds cannot hit a production server is somewhat of a systems nirvana that is essential to the ever more complicated nature of web application development.
The infinity loop in above breaks down the 8 stages of the DevOps cycle.
The Plan stage covers everything that happens before the developers start writing code, and it’s where a project manager sets the wheels in motion. Requirements and feedback are gathered from stakeholders and customers and used to build a product roadmap to guide future development. We track our project roadmap directly in the codebase in GitHub, breaking down projects into user stories with issue, milestones and requirements – these tasks are then used to plan development sprints and allocated among the team.
After a morning stand-up the developers get to work. We use our own build system here that provides us with a base developer toolkit and automatically sets up our default code dependencies and dev environments – automating this process helps to provide consistency both between developers and the codebase.
If we’re all writing from the same book, collaboration is easier and more efficient and any potential issues are flagged much quicker – this results in fewer failed software builds.
After a task as been completed, the developer will submit a pull request (share their code) to the shared project repository. Another team member, then reviews these changes, and upon approval this pull-request forms part of the new code foundation – the base code now has the completed task as part of it’s foundation. This quick review is very effective at identifying issues early on. As soon as the pull request is approved, several automated tasks kick in which build the software and run a series of end-to-end, fully integrated unit tests that check for build failures, errors or any code regressions.
If we’ve missed anything that could potentially cause an issue to a software build, we’re immediately notified and there’s zero chance of a failed build heading to a public release. By baking in this continuous cycle of checking code changes into our code repositories and running builds and unit tests, we minimise integration issues that arise when working through collaboration and highlight bugs early in the development lifecycle.
As soon as a build succeeds, it is automatically deployed to a staging environment to further test. Our staging environments mirror the production environment in all respects – operating systems, intepreter version , libraries and software version are all exactly the same as the production environment.
Once the application is deployed to the test environment, we have the new software version on an accessible server both ourselves and our clients can use. This allows for traditional User Acceptance Testing (UAT) to take place and user groups can highlight any issues and feedback refinements that should be addressed before this software revision is merged with production.
During this stage, we also run additional, automated security scans and test for accessibility compliance and performance benchmarks. Each client requires a different level of testing – some might want focus groups, others unit load tests, others deeper security tests – the web application generally dictates the requirements, but the tests performed on staging server informs us if to iterate based on feedback or move on to release.
Release is the point at which we say the code changes are ready for deployment into the production environment and ready for public consumption. We are confident in the knowledge that the current code changes have passed both a series of manual and automated tests and the build will succeed – at this stage, we know that breaking changes are unlikely.
We have automatic, atomic deployments here at Percipio, so we’re physically hands off on all deployment. This means – should we be inclined – we could deploy multiple releases every day without interruption to users. More often than not, we stick to a regular release schedule and only release new features once a milestone is met
Once the production build completes, the new build replaces previous release on the production environment – again this process is fully automated and occurs with zero downtime. Should find that we do encounter an issue on the production environment, we can instantly roll back to any previous software builds. With complicated builds, this is the most robust deployment method available and we’re pleased to be able to offer this with every single one of our projects.
Our production environment is now running the latest, stable software release – and we check again that that everything is running smoothly. Our hosting environments autoscale to handle any spikes in traffic that generally happen if a software release is timed with a national press release. Automatic server scaling is another feature we wouldn’t do without.
It’s at this stage that real world testing occurs – end users use our products in ways we couldn’t imagine, so we remain open to user testing and feedback.
Before we loop back to planning, we maintain to monitoring on the production environment. Collecting data through analytics, end user behaviour, server performance and error logs allows us to continue feature testing before finally feeding this information back to our product manager and the loop is closed on this feature release.
A continuous cycle
Whilst we can follow the steps here from plan through the monitor for a single task, the reality of the DevOps infinity loop on an active project is that it really is a closed continuous loop – it doesn’t start or stop through a product life cycle.
Every issue, task, feature, bug report – and there are often thousands through a product lifespan go through this cycle, it’s a continuous loop of improvement and innovation.