- Initial thoughts
- 1. First lines of code
- 2. First development environments
- 3. First stable environment
- 4. First production environment
- 5. First customers
- 6. Successful application
- Wrapping up
- Further reading
Initial thoughts
In this article, we will enhance our Git Workflow by gradually adding functionalities for starting web applications. Our main goal is to improve efficiency.
Developers, even experienced ones, have often struggled with the famous Gitflow :
However, the truth is that we don't need this complexity from day one. Many developers even argue that this level of complexity is never necessary in any case, but a symptom of an organisational problem.
Let's approach it differently: from team needs to workflow.
1. First lines of code
As we gather the team and prepare to write the first lines of code, the development team members have a few requirements:
- Share a common code base
- Collaborate on work in progress
- Conduct testing
Most web applications consist of a frontend module and a backend module. The question of using a multi-repo or mono-repo arises.
This article won't elaborate on the controversial topic, but for a starting web application project, we choose a mono-repo for the following reasons:
- No internal versioning required
- Local common module dependencies
- One feature, one feature branch
- Easy continuous integration
At this phase of the project, we don't need more than the following branches:
- Short-lived feature branches that are merged into
mainwhen ready, as frequently as possible - A
mainbranch for merged code
During the initial weeks of testing and demonstrations, local computers are sufficient. This allows time for the Platform Engineer to prepare real environments.
For code reviews, any Git platform, such as GitLab or GitHub, will suffice.
2. First development environments
Workflow
After a few weeks, code and features start to accumulate. Tracking bugs and conducting proper testing becomes essential. If the tools allow, these tests should occur before merging. Demonstrations should take place on a shared environment rather than on local computers.
To achieve this, we establish an integration environment that reflects the main branch.
If we have the right CI/CD technologies, we can also create an environment per branch, which greatly enhances team efficiency. Kubernetes and GitLab can help us achieve this goal with minimal effort.
Our Git workflow at this stage looks like this:
- Short-lived feature branches and their corresponding environments are merged into
main -
mainbranch and environment are used for development team collaboration and client demonstrations
Separate Infrastructure Repository ?
This is controversial and a bit off-topic, but this still a linked matter with efficiency choice at stake.
Many teams choose to separate application and infrastructure repositories. However, I believe that the main reason for this separation is governance and politics, not efficiency.
We choose to have infrastructure scripts in the same repository as the code. Although the lifecycles are different, separating them can lead to complex pipelines if everything is automated, right?
But do we really need full automation for infrastructure? While infrastructure-as-code is desirable, deployment automation may not be necessary. We like to follow the rule: "do not automate before it is boring." Since our product is just starting, nothing is boring regarding infrastructure. We don't need to reinstantiate our Kubernetes cluster every week.
For these reasons, we code and version the infrastructure but do not automate its deployment.
3. First stable environment
Sooner or later, stakeholders will test the application. Frequent redeployment of the main environment leads to downtimes and occasional bugs, which spoil the experience.
It's time to introduce the demo environment. This environment reflects the content of the main environment and is updated before each scheduled demonstration. It remains stable in the interim.
To adapt the flow, the update can be triggered by a Git tag or a Git branch. Here, we choose to create a new demo Git branch.
Our Git workflow now looks like this:
- Short-lived feature branches and their corresponding environments are merged into
mainand then deleted -
mainbranch and environment are merged intodemobefore demonstrations -
demobranch and environment are used for demonstrations
4. First production environment
With the MVP (Minimum Viable Product) just around the corner, a production environment has been built from the ground up and will soon be made public. It's time to deploy our application to the target production infrastructure.
To adapt the flow, the production deployment can be triggered by a Git tag or a Git branch. We choose to use tags since we don't need to handle hot fixes at the moment, and triggering deployment jobs can be done manually.
We don't cascade merges from main to demo to production. The demo and production environments have decoupled lifecycles.
Our Git workflow now looks like this:
- Short-lived feature branches and their corresponding environments are merged into
mainand then deleted -
mainbranch and environment are merged intodemobefore demonstrations -
demobranch and environment are used for demonstrations - Manual production deployment jobs are available on tags (created on
mainordemo, depending on the team preference)
5. First customers
As we had hoped from the beginning, we now have happy customers.
We want to ensure that we don't spoil their experience. When problems occur in their workflow, we want to be able to reproduce them in an iso-production environment, fix them, and test them in a pre-production environment as well. We will call this environment staging.
Since staging doesn't have real customers, we can deploy automatically using the same tags that trigger manual production deployment.
Our Git workflow now looks like this:
- Short-lived feature branches and their corresponding environments are merged into
mainand then deleted -
mainbranch and environment are merged intodemobefore demonstrations -
demobranch and environment are used for demonstrations - Automatic
stagingdeployment and manualproductiondeployment are triggered by tags
We still don't handle production hot fixes separately. The entire content of main is deployed to production on tags. Unfinished content is not merged into main or deactivated by a commit.
6. Successful application
Now our application is somewhat successful, with many customers using it daily.
Cash is flowing, and the development team is growing. It becomes increasingly difficult to find a satisfying main or demo state to be deployed to production.
Now is the time to add feature toggles (also known as feature flags or feature flipping). Anything can be deployed to production as long as it is protected by a switch to activate it or not.
Our Git workflow now looks like this:
- Short-lived feature branches and their corresponding environments are merged into
mainand then deleted -
mainbranch and environment are merged intodemobefore demonstrations -
demobranch and environment are used for demonstrations - Automatic
stagingandproductiondeployment are triggered by tags created onmain, and feature toggles are activated based on confidence
Wrapping up
We followed the journey of a starting project that progressively added only necessary complexity to the git flow.
By following this Git workflow, we believe that development teams can streamline their processes, improve collaboration, and efficiently deliver high-quality web applications to their customers.
What is your own best experience of Git workflow ? Please share in the comments below π€
Illustrations generated locally by Pinokio using Stable Cascade plugin
Further reading
π Git / π¦ GitLab
- Efficient Git Workflow for Web Apps: Advancing Progressively from Scratch to Thriving
- Forget GitKraken, Here are the Only Git Commands You Need
- A Python Script Displaying Latest Pipelines in a Group's Projects
- A Python Script Calculating DORA Metrics
- Deploy a Majestic Single Server Runner on AWS
- The Majestic Single Server Runner
- YAML Modifications: Tackling the Feedback Loop Problem
- 15+ Tips for Faster Pipelines
- 10+ Best Practices to Avoid Widespread Anti-Patterns
- Pages per Branch: The No-Compromise Hack to Serve Preview Pages
- Jobs Attributes Sorter: A Python Script for Consistent YAML Files
- Runners Topologies: Pros and Cons
βΈοΈ Kubernetes
- A Convenient Variable Substitution Mechanism for Kustomize
- Why Managed Kubernetes is a Viable Solution for Even Modest but Actively Developed Applications
- From Your Docker-Compose File to a Cluster with Kompose
- A Pragmatic Kubectl Aliases Collection
- Web Application on Kubernetes: A Tutorial to Observability with the Elastic Stack
- NGINX Ingress Controller: 10+ Complementary Configurations for Web Applications
- Awesome Maintained Links You Will Keep Using Next Year
- Managed Kubernetes: Our Dev is on AWS, Our Prod is on OVHCloud
- How to Deploy a Cost-Efficient AWS/EKS Cluster Using Terraform
- How to Deploy a Secured OVHCloud Managed Cluster Using Terraform
- FinOps EKS: 10 Tips to Reduce the Bill up to 90% on AWS Managed Clusters
π Miscellaneous
- Every Developer Should Review Code β Not Just Seniors
- Future-Proof Tech Blogging: Understanding AI's Core Traits
This article was enhanced with the assistance of an AI language model to ensure clarity and accuracy in the content, as English is not my native language.







Top comments (0)