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?