I've been using the GitLab Flow paradigm for managing branches and environments of Platform.sh projects. At a minimum, this involves setting up a
master, see below) branch as the default for the repository, and a separate
production branch. If CI/CD processes require it, a third
pre-production branch could be inserted in between. These branches should be protected -- preventing deletion and any direct pushes (i.e., all commits must be done via a merge request).
Preparing a new Platform.sh project to use GitLab Flow
First use the "move" command in git to copy the entire
master branch to a new
main branch, and push to the upstream repository.
git branch -m master maingit push -u origin main
main the default branch in GitLab. To do so, go to "Settings" > "Repository" for your project. At the top is a section marked "Default Branch" -- expand it to select "main" instead of "master". Then click "Save changes".
Next, remove the
master branch. Go to "Repository" > "Branches" for your project. Under the "Active Branches" find "master" and click the trashcan icon to the right to delete the branch (say "Ok" to the warning about not being able to undo the delete).
Create a new
production branch that will automatically be deployed to the live site (i.e., trigger a build) when changes are made to it.
git checkout -b production
And, lastly, protect both
production branches, allowing "Maintainers" to merge to either but disallowing all users from pushing directly.
Configuring branches and environments in Platform.sh
First, configure your project repository's integration with Platform.sh, making sure to include the following features:
- Fetch branches from the GitLab repository to your project.
- Remove branches from your project that have disappeared from GitLab.
- Re-sync environment data on every pull request build.
Once the integration is working, you will see two new inactive environments off of the "Master" environment in Platform.sh: one that mirrors the
main git branch and another mirroring
production. The remaining steps require that you are running a local copy of the project (see Lando). Once you have a local webserver running and have downloaded and installed the Platform.sh CLI, you can proceed (steps extracted from the Platform.sh documentation).
First, remove the parent association from the "production" environment and make it top-level.
platform environment:info -p <Project ID> -e production parent -
Re-link "main" to use "production" as its parent.
platform environment:info -p <Project ID> -e main parent production
Reconfigure the default branch by deactivating the "master" environment, setting the project's
default_branch property, and then deleting the "master" environment entirely.
platform environment:delete master --no-delete-branch -p <Project ID>platform project:info default_branch production -p <Project ID>platform environment:delete master --delete-branch -p <Project ID>
Following the GitLab Flow paradigm
production branches are protected, all development should occur on additional feature branches from
main. Once the development on a particular feature branch is complete, its changes should first be rebased onto the
main branch to pick up any other changes that have been introduced since the feature branch was created (or last rebased).
Next, create a merge request to merge the feature branch into
main. Ensure that "Squash commits when merge request is accepted" is checked off (preferably set as the default/required setting in the project's repository settings). Once code review is complete and the reviewer(s) "accept" the merge request, you can choose to complete the merge (note that this may have to be done in the GitLab UI if pushing directly to
main is not allowed -- see above).
At this point, GitLab should trigger a new build on the "main" environment in Platform.sh. Review/test the changes just incorporated on this newly built environment and, when ready, submit another merge request -- this time to merge
production. Once that merge request is approved and the merge is complete the new changes will be deployed to the "production" environment and will be visible live.
The recommendation is to use a "semi-linear" branching structure, which can be selected in the project's repository settings (go to "Settings" > "Repository"). This means that feature branch should be rebased onto
main just prior to submitting a merge request -- and when merging, the feature branch's commits should be "squashed" into a single merge commit when incorporated back into
main. Subsequently, any deployments to the "production" environment will be made by a single merge commit from
production (as detailed above).
This approach will ensure that the git history remains clean and understandable, while capturing the commit history of a particular feature's development as set by the author. For more information, see "Git Interactive Rebase, Squash, Amend and Other Ways of Rewriting History" by Tute Costa.
(Note that these annotations do not correspond to the visual order in the image.)
- 40d1854: Project initialized with
- de337be: Code update pushed directly to both branches (should be avoided!)
- b8e510c: Feature branch created, commits made, rebased onto
mainand then merged into
main-- triggering a deployment to the "main" environment
productionand then merged -- triggering a deployment to the "production" environment
- a32f775: At some point prior to the deployment, a feature branch called
site-aliasesis created and a commit is made.
- 4734625: Now that
main(from which the
site-aliasesbranch had been created) is ahead of
site-aliases, that feature branch is rebased onto
main-- which applies its commits to the head of
main, and leaves
site-aliasesas only a local branch (to be deleted).
mainis merged into
production-- triggering a deployment to the "production" environment again.