-
Notifications
You must be signed in to change notification settings - Fork 15
/
git-workflow.txt
152 lines (110 loc) · 9.56 KB
/
git-workflow.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
We have approximately been releasing on a monthly cadence and sometimes have to work on minor releases concurrently. So
we have multiple release branches, instead of a single "master" branch like some of the other products that have a
longer release cycle do, e.g. PingDirectory, which follows a loose quarterly release schedule.
We also follow semantic versioning (semver.org), which states:
Given a version number MAJOR.MINOR.PATCH, increment the:
- MAJOR version when you make incompatible API changes,
- MINOR version when you add functionality in a backwards compatible manner, and
- PATCH version when you make backwards compatible bug fixes.
This also results in more frequent versions and branches to track those versions.
Branching and tagging:
Release branches are created after we release a particular version and commit to the next release as a team. They are
always created from the HEAD of the master branch. Release branches have a pattern of "v<major>.<minor>-release-branch",
e.g. v1.3-release-branch. Once a release has been qualified by the QA team, the release tag is created off of the tip
of the release branch. There is a tagging script under the build directory to do that.
This release strategy implies that you can develop code for (and potentially deliver) different major/minor versions
in parallel. For example, you can develop for v1.3.2 and a future v1.4.0 in parallel because they live in separate
release branches. However, maintenance releases on top of a minor release can only be developed sequentially. For
example, you cannot push changes for v1.3.3 into the v1.3-release-branch until v1.3.2 has been tagged.
Features that do not have a known release version must be maintained in their own feature branches until they are
targeted for the next release. It is the developer's responsibility to keep this branch in sync with the master branch
by performing periodic merges from it. If there are merge conflicts, the developer must reach out to the committer of
the code that resulted in the conflicts to ensure that the conflicts are resolved correctly.
Once a change has been made to a lower branch, it must be promoted to higher branches. The developer has the choice of
doing it themselves via the MR workflow (as described in the following section), or may defer it to the release
engineer to handle it. A release engineer will merge changes from lower branches all the way up into master
periodically, for example, from v1.3-release-branch -> v1.4-release-branch -> master. Multiple commits may be chained
to keep the CI pipeline from going berserk. But if it's not a fast-forward merge, and there are merge conflicts, the
release engineer may request the developer to perform the merge. See the "Promoting changes from lower to higher
versions" section below on how to do this, if necessary.
Note that the release branches are not long-lived branches. Once a particular version has been made end-of-life, or all
customers have been upgraded to a new version, the release branches may be deleted. For example, if all PingCloud
customers have moved onto v1.3.1, the v1.1-release-branch and v1.2-release-branch branches may be deleted.
Git Workflow:
1. When working on a bug or feature, the first thing to determine is the version for which it is targeted. Ask a
team member if this is not clear.
2. Find out which branch corresponds to that version in ping-cloud-base on GitLab. Ask a team member if this is
not clear.
3. After cloning ping-cloud-base, create a local feature/bug-fix branch. For example, to create a new local bug-fix
branch named pdo-288-increase-csd-timeout off of the current tip of the v1.3-release-branch, run these commands:
git clone git@gitlab.corp.pingidentity.com:ping-cloud-private-tenant/ping-cloud-base.git
git checkout v1.3-release-branch # Switch to the v1.3-release-branch
git pull # Get the latest changes from the server
git checkout -b pdo-288-increase-csd-timeout # Create the feature or bug-fix branch
Note: We use branch names to create unique DNS names on Route53 for each environment. DNS names must be 63
characters or shorter. So the branch name must not be too long such that it exceeds that limit. The maximum
recommended length for the branch name is 40 characters. A best-practice is to use the Jira issue number as the
branch name prefix, followed by a short description, e.g. pdo-723-wait-for-services.
4. Make your changes on your local branch. Periodically merge the source branch into your local branch. This is
especially important for massive changes, which should be generally avoided but do happen on rare occasions.
git stash # This is only required if you have uncommitted changes in your branch
git checkout v1.3-release-branch # Switch to the source branch, v1.3-release-branch
git pull # Fetch and merge the latest updates from the server into v1.3-release-branch
git checkout - # Switch back to the previous branch, e.g. pdo-288-increase-csd-timeout
git stash pop # This is only required if you had uncommitted changes
git merge v1.3-release-branch # Merge the changes from the v1.3-release-branch into your branch
At this point, you may have merge conflicts if another developer has updated one or more of the same files that you
have. You'll have to resolve them using a three-way merge tool. Most IDEs (e.g. IntelliJ IDEA) have plugins to do
this.
5. Repeat step 4 until you're done implementing and testing the feature or bug fix.
6. Push to the server when you're done. Git best practices dictate that you only push your changes after you've tested
your feature branch, i.e. try not to commit, then push repeatedly. Every push will trigger a pipeline on the server,
which will flood the shared CI/CD cluster.
Note: We currently have a unique situation with server profiles. If your change encompasses server profiles, then
you must push your branch for it to be mirrored onto AWS Code Commit so that your containers running on AWS EKS can
clone your branch with your server profile changes. In this case, use a commit message prefix of "[skip pipeline]"
to avoid triggering a CI/CD pipeline.
7. When finally done with your changes, commit your last changeset without the "[skip pipeline]" message so that a
CI/CD pipeline gets triggered.
Note: Without a successful CI/CD pipeline, you will not be able to merge your branch into the target branch on the
GitLab server.
8. From the GitLab UI, create a Merge Request. Set the target branch for the merge request to your original source
branch, e.g. v1.3-release-branch. Also check the following boxes:
- "Squash commits when merge request is accepted" to squash all the commits in your feature branch
- "Delete source branch when merge request is accepted" to delete the feature branch
If you'd like a different commit message for the "squashed commit" than the last commit on the branch, then you may
do so from the MR interface by clicking on the "Override squash commit message" link.
9. Subscribe to the beluga-notifications slack channel to be notified of MRs. Alternately, you may also post the MR to
the pda-dev channel, for example, if you'd like a specific subset of the team to review your changes or you need the
MR reviewed urgently.
10. Incorporate review feedback in your local feature branch and push those up. They will automatically show up in
your MR because the MR is associated with your branch.
11. Resolve all threads in the MR. Once approved and the pipeline passes, you will be able to merge your changes to the
target branch by hitting the "Merge" button.
Promoting changes from lower to higher versions:
Note that this workflow is only required if the developer wishes to perform this action by themselves so they have
complete ownership of a particular feature, or if a release engineer is unable to perform a merge of the changes from
a lower to a higher branch due to merge conflicts, being on leave, etc.. It is recommended that developers defer this
to the release engineer as much as possible, especially if they are not comfortable with git workflows.
Warning:
When promoting changes from lower to higher versions, cherry-picking must be avoided. Instead, a merge to the higher
version is preferred. This will ensure that the history of the changes made in the lower version's branch is preserved
and there are no duplicate commit IDs for the same changes - just an extra merge commit. Refer to the following
document on why cherry-picking should not be part of a normal git workflow:
https://dan.bravender.net/2011/10/20/Why_cherry-picking_should_not_be_part_of_a_normal_git_workflow.html
The following steps explain how to promote a bug-fix/feature (pdo-x) targeted for the v1.4-release-branch into master.
1. Create an MR from pdo-x to v1.4-release-branch using the "Git Workflow" steps above.
2. After the code is reviewed and merged into the v1.4-release-branch, the MR workflow will delete the pdo-x remote
branch. Retain your local copy of pdo-x for the merge.
3. Switch to your local copy of master and update it:
git checkout master
git pull
4. Create a local branch for merging pdo-x into master:
git checkout -b pdo-x-master
5. Merge pdo-x into pdo-x-master and push it to remote:
git merge pdo-x
git push --set-upstream origin pdo-x-master
6. Follow the MR process on GitLab UI requesting to merge pdo-x-master into master.
7. Once the branch has been merged, you may optionally get rid of your local branches:
git checkout master
git branch -D pdo-x pdo-x-master