<p>One possible answer could come from the reason for using multiple branches as basis for environments in the first place.</p>

<p>In some organisations (typically for large scale projects and often for historical reasons) it is desired to allow for cherry-picking hot fixes in each environment to limit the amount of changes (thus the risk) picked up in each iteration on that environment. I'd argue that such approach is not really aligned with continuous integration/delivery at the project level (it may be at each of the branch levels). </p>

<p>In this context the branches will diverge, so build-once, deploy everywhere principle is similarly applicable only at the branch/environment level, it cannot be applied at the project level. The GitHub/GitLab flow could work well in such case.</p>

<p>If, however, there is no cherry-picking between branches and <strong>strictly</strong> straight/fast-forward merges from upstream branch refpoints are used to propagate changes to the downstream branches/environments then the reason for using multiple branches is IMHO questionable. A <strong>single/master</strong> branch can be used instead, the environments being implemented simply as different steps/stages in the CI/CD processing pipeline.</p>

<p>The pipeline would be triggered on the branch tags/refpoints from which the original change propagation would be initiated in the multi-branch scenario (ideally for each and every commit).</p>

<p>The build-once, deploy everywhere principle can easily be enforced in this approach, which aligns very well with continuous integration/delivery/deployment at the entire project level. You just need to consider each build as potential release candidate from the very beginning of your pipeline processing.</p>

<p>Note that nothing in this scenario conflicts with using GitLab/GitHub (or any other modern version control system) itself, you just don't <strong>have to</strong> use all the features they offer ;)</p>

CC BY-SA 4.0
2020-01-22T16:52:41.107Z
Thanks, partially read that and took a while to come back around.  :)  I appreciate the detailed & realistic answer.
John Humphreys
CC BY-SA 4.0
2020-01-18T16:37:51.580Z
2020-01-18T16:37:51.580Z
Dan Cornilescu
<p>Historically, especially in the Java world, build-once, deploy everywhere has been a very big thing for deployments.  Artifacts should be built exactly one time when a release is made and stored somewhere like Nexus or Artifactory where they are immutable and can be deployed to all environments, repeatedly and safely.</p>

<p>GitLab flow, on the other hand, seems to recommend having a branch per environment and deploying to that environment as an event upon doing a merge request to the branch.  E.g. a master -> staging merge runs CI/CD on the staging branch, resulting in a deployment there.  Merging the staging to the production branch does the same in production (with the possibility of forcing a manual agreement to the run).</p>

<p>So, GitLab flow causes us to rebuild our artifacts for every environment rather than build once deploy everywhere.</p>

<p><strong>Does this mean we should totally ditch build-once deploy-everywhere when moving to modern tools like GitLab/GitHub?  Is that a good thing?</strong></p>

<p>I guess we can augment GitLab flow by:</p>

<ul>
<li>Build artifacts on merge into DEV branch and store in a maven/etc repo.</li>
<li>Do deployment using those artifacts. </li>
<li>Have merges to staging/prod skip build/test and only do deploy using the same artifacts.</li>
</ul>

<p>This seems like forcing GitLab/etc to do something against their model though, so I'm thinking its not a good idea.</p>

<hr>

<p>Note: I also am wondering how building/testing/deploying in every environment separately is possible in some large projects.  E.g. Facebook's presto has like an hour of tests in a maven build (or more)... I wouldn't want my production release taking hours; that's the opposite of modern.</p>

<p><strong>Any thoughts here?</strong></p>

CC BY-SA 4.0
2020-01-13T08:21:56.583Z
Does https://12factor.net/ provide any illumination?
Bruce Becker
CC BY-SA 4.0
2020-01-13T11:23:15.230Z
Good question.  I’ve been through that a few times before and generally follow most of the practices.   But I’ll go reread it with this in mind :).  Thanks!
John Humphreys
<deployment><gitlab><continuous-deployment><cicd><build-pipeline>
Is GitLab flow (or GitHub flow, etc) anti build-once deploy-everywhere?
John Humphreys
# Is GitLab flow (or GitHub flow, etc) anti build-once deploy-everywhere?

(Asked by: username_0 on 2020-01-13)

Historically, especially in the Java world, build-once, deploy everywhere has been a very big thing for deployments. Artifacts should be built exactly one time when a release is made and stored somewhere like Nexus or Artifactory where they are immutable and can be deployed to all environments, repeatedly and safely.

GitLab flow, on the other hand, seems to recommend having a branch per environment and deploying to that environment as an event upon doing a merge request to the branch. E.g. a master -> staging merge runs CI/CD on the staging branch, resulting in a deployment there. Merging the staging to the production branch does the same in production (with the possibility of forcing a manual agreement to the run).

So, GitLab flow causes us to rebuild our artifacts for every environment rather than build once deploy everywhere.

**Does this mean we should totally ditch build-once deploy-everywhere when moving to modern tools like GitLab/GitHub? Is that a good thing?**

I guess we can augment GitLab flow by:

* Build artifacts on merge into DEV branch and store in a maven/etc repo.
* Do deployment using those artifacts.
* Have merges to staging/prod skip build/test and only do deploy using the same artifacts.

This seems like forcing GitLab/etc to do something against their model though, so I'm thinking its not a good idea.

---

Note: I also am wondering how building/testing/deploying in every environment separately is possible in some large projects. E.g. Facebook's presto has like an hour of tests in a maven build (or more)... I wouldn't want my production release taking hours; that's the opposite of modern.

**Any thoughts here?**

**Tags:** deployment, gitlab, continuous-deployment, cicd, build-pipeline

> **Comments:**
> **username_1**: Does https://12factor.net/ provide any illumination?  
> **username_0**: Good question.  I’ve been through that a few times before and generally follow most of the practices.   But I’ll go reread it with this in mind :).  Thanks!  

---

## 1 answers

### Answer by username_2 on 2020-01-18. Score: 2 | Accepted answer

One possible answer could come from the reason for using multiple branches as basis for environments in the first place.

In some organisations (typically for large scale projects and often for historical reasons) it is desired to allow for cherry-picking hot fixes in each environment to limit the amount of changes (thus the risk) picked up in each iteration on that environment. I'd argue that such approach is not really aligned with continuous integration/delivery at the project level (it may be at each of the branch levels).

In this context the branches will diverge, so build-once, deploy everywhere principle is similarly applicable only at the branch/environment level, it cannot be applied at the project level. The GitHub/GitLab flow could work well in such case.

If, however, there is no cherry-picking between branches and **strictly** straight/fast-forward merges from upstream branch refpoints are used to propagate changes to the downstream branches/environments then the reason for using multiple branches is IMHO questionable. A **single/master** branch can be used instead, the environments being implemented simply as different steps/stages in the CI/CD processing pipeline.

The pipeline would be triggered on the branch tags/refpoints from which the original change propagation would be initiated in the multi-branch scenario (ideally for each and every commit).

The build-once, deploy everywhere principle can easily be enforced in this approach, which aligns very well with continuous integration/delivery/deployment at the entire project level. You just need to consider each build as potential release candidate from the very beginning of your pipeline processing.

Note that nothing in this scenario conflicts with using GitLab/GitHub (or any other modern version control system) itself, you just don't **have to** use all the features they offer ;)

> **Comments:**
> **username_0**: Thanks, partially read that and took a while to come back around.  :)  I appreciate the detailed & realistic answer.  

---

