Dev opens a PR, and CI runs tests, checks if the build passes, code review is done, and the merge is made to main.
All new code on main will generate a new CI and CD, a release for the staging environment, where QA is performed by stakeholders (Dev, QA, Product).
Control of what can be displayed by environment is done through feature flags, basically an if
statement in the code that checks if the feature can be activated or deactivated in environment X (staging | production).
Feature flags serve both bug fixes and new features, meaning any code changes. They serve to avoid breaking changes.
A new production release is generated by tags, and the feature is enabled in production through feature flags, accessed via the back office: env files, also feature_flags in the database, or even a front-end where you have basic CRUD operations for feature flags.
Diagram demonstrating the described processes.
- Having a single branch (main)
- Having feature flags, can start with ENVs and the sky is the limit like having a back office
- Smaller pull requests
- Automated tests for more security in sending code to production, as the delivery will be faster
- Writing better code and having code reviews, this workflow makes the development team write better and test better by themselves, as they will try to avoid delivering something not very functional, hence the tests.
- Database migration execution needs to be automated
- The codebase will have some scattered
if
statements to activate and deactivate the feature flags - More branches, databases to maintain
- Branch parity since there is only one, always moving forward avoiding break-changes
- Avoiding multiple environments making cloud resources more expensive
- Code quality
- Responsibility on the part of the teams ...
The approach described above solves a problem of a flow where code cherry-picking is done from branches, for example, a task was approved by QA who tested it in the develop environment, for staging. The commit hash of this task is cherry-picked and sent to the develop branch, then passed to the staging branch, and then sent to production once tested by the product team in staging. You end up having to maintain 3 branches, 3 databases, doing this will probably lead to many conflicts and the developer will spend hours dealing with git instead of maintaining or coding new features, besides the terrible developer experience that this approach brings.