Skip to content

technetiumjs/CONTRIBUTING

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 

Repository files navigation

CONTRIBUTING

Context

This document will go over the basic steps for contributing through git. The goal of the improved git workflow is to be able to maintain a current release cycle in addition to maintaining the ability to support older release patching. Such a structured standard is necessary for DevOps to support both a sensible container infrastructure, as well as support automated package deployments. Additionally these structured releases become very accomodating to agile development when used correctly.

A ------------------------------------------- N --- [master]
 \                                      \    /
  \                                      `- M ----- [release/1.x]
   \                                       /
    `- B ------------ G ------------- K - L --- O - [develop]
        \            / \             /
         \----- D - F   \           /               [feature/ft1]
          \              \         /
           `- C - E ----- H - I - J                 [feature/ft2]

+-----------------+------------------+
| Initial Commits | A, B, C, D, O    |
+-----------------+------------------+
| Feature Commits | C, D, E, F, I, J |
+-----------------+------------------+
| Merge Commits   | G, H, K, M, N    |
+-----------------+------------------+
| Tag Commits     | L                |
+-----------------+------------------+

Diagram

Demonstration of a typical workflow when handling a normal release cycle.

Table of Contents

Concepts

There are three concepts to discuss:

Prior to going into detail about the various branching strategies and the associated bureaucracy, it is important to discuss the details of these signficiant concepts.

Commits

Every additive action in git is represented with a commit. Four significant commit concepts will appear in this document:

There is value in discussing their distinction, as they are created by and represent different processes in the workflow.

Initial Commit

Initial commits, in the context of this git workflow, is an empty commit made to distinguish the start of a branch. These are not automatically made, and are effectively enforced with convention only. Intial commits are made, more speficially, after branching from a parent branch with the intent on merging the child branch back in. After making an initial commit, a pull request draft or WIP merge request should be opened by the developer and the appropriate reviewers should be assigned.

These commits are expected to be the first commit pushed into all branch types except for the release branchs.

Feature Commit

These are your typical commits denoting a change to the codebase. These are created by the developer and pushed directly into their branches.

The following is a list of branches in which feature commits are expected to be pushed:

Merge Commit

These are generally created automatically by merging a pull request.

An exception to that, the context of this document, is the merge commits found in master. The master branch should updated automatically by the CI/CD to point to the most recent and stable tag, triggered by merges into the release/<version> branches. See the Master Branch section for more information on this topic.

These commits are expected to be pushed into all branches except for master. Most of these commits will be generated by the pull request tool or by the CI/CD tool.

Tag Commit

Tag commits are the commits that associate tag changes. These must be completed manually, and should be the responsibility of the maintainer after accepting a pull request but prior to merging the pull request. Tags should follow semver guidelines.

The following is a list of branches in which tag commits are expected to be pushed:

These are pushed by maintainers.

Branches

There are a number of branch prefixes to be aware of. The five branch formats are:

They all have their own special meanings that will be covered.

Master Branch

This branch shows your latest stable commits. It should reflect your latest package version or your most recent deployment to production.

Updating the master branch should be done automatically by the CI/CD tool, and should be triggered on successful merges into the release/<version> branches. The HEAD of master should always point to the highest stable tag that has successfully deployed to production.

If no deployment to production has occured, it should contain only an initial commit with the message "First commit".

The logic on the CI/CD server for determining if master should be updated automatically may look something like the following:

if [[
  "$(git describe --abbrev=0)" != *"-"* &&
  "$(git describe --abbrev=0)" > "$(git describe --abbrev=0 xxx)"
]] ;
then
  echo "Update master" ;
else
  echo "Do not update master" ;
fi

Snippet

Example logic for determining if master needs to be updated. Expects that this is running in a CI/CD block allowed only by merges into a release/<version> branch.

Release Branch

Merges into this branch, from the develop branch are is managed by the code maintainer. A merge into this branch triggers the CI/CD to deploy the latest tagged commit to the appropriate system using SemVer naming standards.

All merges into the release/<version> branch should be tagged with an appropriate tag version. If major version are broken up across systems, then it would be expected that the correct branch is tagged major tag will be merged into the correct release branch.

When the CI/CD server is triggered by an update to a release branch, one would expect the CI/CD server to then release the latest tag in the current branch. The effect of this is to anticipate that only tagged commits are deployed.

The logic on the CI/CD server for determining if the current branch is a release branch may look like the following:

export RELEASE="release/.*"
if [[ "$(git branch | grep \* | cut -d ' ' -f2)" =~ $RELEASE ]] ; then
  echo "Release branch - checking out last tag $(git describe --abbrev=0)" ;
  git checkout $(git describe --abbrev=0)
else
  echo "Not release branch - moving forward." ;
fi

Snippet

Example logic for determining if the current branch is a release/<version> branch, if so it checks out the latest tag on the branch. The CI/CD system should proceed with deployment on the latest tag commit if it is on a release branch.

However, it's not just enough for a release branch to check if a tag exists - it also must deteremine what suffix the tag has. Is it a stable tag, a beta tag, or an alpha tag. This can help the CI/CD system determine what environment to publish the build artifacts into.

The logic on the CI/CD server for determining the alpha/beta/stable status of a tag may look like the following:

export TAG="$(git describe --abbrev=0)"
export ALPHA="^v?([0-9]+\d*)\.([0-9]+\d*)\.([0-9]+\d*)-alpha((\.[0-9]+)|$)$"
export BETA="^v?([0-9]+\d*)\.([0-9]+\d*)\.([0-9]+\d*)-beta((\.[0-9]+)|$)$"
export STABLE="^v?([0-9]+\d*)\.([0-9]+\d*)\.([0-9]+\d*)$"
if [[ "$TAG" =~ $ALPHA ]] ; then
  echo "Alpha tag $TAG" ;
elif [[ "$TAG" =~ $BETA ]] ; then
  echo "Beta tag $TAG" ;
elif [[ "$TAG" =~ $STABLE ]] ; then
  echo "Stable tag $TAG" ;
else
  echo "Unknown tag $TAG"
fi

Snippet

Example logic for determining if the current tag is considered alpha, beta, or stable. The CI/CD system should go on to deploy alpha code to a devl system, deploy beta code to a test system, and deploy stable code to a prod system.

Develop Branch

A common development branch, reflecting development progress on the latest version. Development should not occur directly on this branch, but instead should be done in feature/<version> branches and merged into develop. All merging into this branch should be performed by a code maintainer.

Feature Branch

Where active development occurs. Generally, one developer will be working on a single feature branch at a time.

These branches are expected to be up-to-date at the time of a merge request, but it is best if they are continuously kept in-sync with changes on develop.

Hotfix Branch

These branches are opened in response to immediate changes required on the latest version’s release branch. It is expected that these changes will be back-merged into the develop branch.

Support Branch

These branches are opened in response to immediate changes required on a legacy version’s release branch. It is expected that these changes will not be back-merged into the develop branch.

Contributors

There are two distinct contributors we need to address:

They both have unique roles to play in the SDLC workflow outlines here.

Developer

The person who develops features. They generally work out of a feature/<name> branch.

The developer is responsible for ensuring that merge conflicts do not arise for the code maintainer between their feature/<name> branch and the develop branch.

Maintainer

The person who is responsible for maintaining the code through code reviews, merge requests, and tagging.

Project Setup

Angular has a CLI tool for setting up an initial project. In addition to that, it provides the first commit. We can make use of that first commit and immediately push that to master. Following that, we will do the same with develop prior to starting with our first feature branch.

Angular Projects

  • Create a new project in GitHub
  • Generate a new Angular project locally with routing and SASS
  • Push first commit to origin/master
  • Checkout new develop branch from master
  • Push first commit to origin/develop
  • Setup GitHub branch protection
  • Start your first feature branch

this is what you might expect to see in the terminal:

ng new <project> --routing --style scss
cd <project>
git push -u origin master
git checkout -b develop
git push -u origin develop
git checkout -b feature/<title>

Snippet

Local steps for starting an Angular git project

General Projects

Setting up a git project locally for non-cli tools may be a little different than Angular projects. As an intial commit is not provided, we will generate an empty commit with the message "First commit" and push that to master. Following that, we will do the same with develop prior to starting with our first feature branch.

  • Create a new project in GitHub
  • Clone the project locally
  • Create a first empty commit "First commit"
  • Push first commit to origin/master
  • Checkout new develop branch from master
  • Push first commit to origin/develop
  • Setup GitHub branch protection
  • Start your first feature branch

This is what you might expect to see in the terminal:

git clone <project>
cd <project>
git commit --allow-empty -m "First commit"
git push -u origin/master
git checkout -b develop
git push -u origin/develop
git checkout -b feature/<title>
...

Snippet

Local steps for starting a simple git project

Workflow Scenarios

  • Feature development
  • Deploying patches and minor updates
    • Development (alpha)
    • Staging (beta)
    • Production (stable)
  • New major release
  • Hotfixing
  • Support Fixes

Feature Development

The latest release is the one that is actively being developed. The develop branch in it's current state is the unstable state for this release. Development is not done directly on the develop branch, but instead done on feature/<title> branches.

Using feature/<title> branches for active develop ensures that the maintainer has the ability to review all features as they are developed. Others working on different features know they can (and should) pull accepted features into their own feature/<title> branches once they have been approved and merged into develop by the maintainer. This will help protected parallel features from being burdened by compounding conflicts, and reduce the probability of last minute bugs occuring after accepting a feature.

INCORRECT

... -------------- E ------- H - [develop]
     \            /         /
      \----- B - D         /     [feature/<name1>]
       \                  /
        `- A - C --- F - G       [feature/<name2>]

+-----------------+------------+
| Initial Commits | A, B       |
+------------------------------+
| Feature Commits | C, D, F, G |
+-----------------+------------+
| Merge Commits   | E, H       |
+-----------------+------------+
| Tag Commits     |            |
+-----------------+------------+

Diagram

In this scenario, feature branches feature/<name1> and feature/<name2> may become out of sync. Potentially significant development may have occured in feature/<name2> after the merging of feature/<name1> into develop. As a result, possible conflicts may become compounded.

CORRECT

... -------------- E ------------- I - [develop]
     \            / \             /
      \----- B - D   \           /     [feature/<name1>]
       \              \         /
        `- A - C ----- F - G - H       [feature/<name2>]

+-----------------+------------+
| Initial Commits | A, B       |
+-----------------+------------+
| Feature Commits | C, D, H, H |
+-----------------+------------+
| Merge Commits   | E, F, I    |
+-----------------+------------+
| Tag Commits     |            |
+-----------------+------------+

Diagram

In this scenario, feature branches feature/<name1> and feature/<name2> may become out of sync. However, the parent develop branch is continuously synced into the active feature/<name2> branch in order to minimize the difficulty of resolving conflicts.

Deployment

Deployment is triggered when a merge request into the release/<version> branch succeeds. The latest tag will become an important factor in the deployment process for three reasons:

  1. The most recent tag in the branch will be used to determine target environment for deployment
  2. The most recent tag in the branch points to the commit that will be build and deployed
  3. The most recent tag in the branch, if a stable semver format, will be compared with the most recent tag in master to determine if master needs to be updated automatically

There are three supported formats for determining environment selection:

tag environment
v?.?.? Production
v?.?.?-beta Staging
v?.?.?-alpha Development

Table

Table referencing relationship between tag and environment in the context of merges into release/<version> branches. The ? characters in the tag column denote the following character set: /^[0-9]+$/. These deployment strategies are largely useful for applicaton deployment, though they can be used for publishing libraries to various artifact repository environments.

Deploy to First Release Branch

A --------------------------- I --- [master]
 \                      \    /
  \                      `- H ----- [release/<version>]
   \                       /   
    `- B -------- E - F - G --- J - [develop]
        \        /
         `- C - D                   [feature/<title>]

+-----------------+------------+
| Initial Commits | A, B, C, J |
+-----------------+------------+
| Feature Commits | D          |
+-----------------+------------+
| Merge Commits   | E, H, I    |
+-----------------+------------+
| Tag Commits     | F          |
+-----------------+------------+

Deploy to Current Release Branch

... ------------ E --- [master]
                /
... ---------- D ----- [release/<current>]
              /   
... ---- B - C --- F - [develop]
        /
... -- A               [feature/<title>]

... ------------------ [release/<legacy>]

+-----------------+---------+
| Initial Commits | F       |
+-----------------+---------+
| Feature Commits | A       |
+-----------------+---------+
| Merge Commits   | B, D, E |
+-----------------+---------+
| Tag Commits     | C       |
+-----------------+---------+

Diagram

This workflow shows merging into to an existing release branch.

Deploy to New Release Branch

... ------------ E --- [master]
           \    /
            `- D ----- [release/<current>]
              /   
... ---- B - C --- F - [develop]
        /
... -- A               [feature/<title>]

... ------------------ [release/<legacy>]

+-----------------+---------+
| Initial Commits | F       |
+-----------------+---------+
| Feature Commits | A       |
+-----------------+---------+
| Merge Commits   | B, D, E |
+-----------------+---------+
| Tag Commits     | C       |
+-----------------+---------+

Diagram

This workflow shows up a subsequent new release branch and merging into it.

Hotfixing

Finding bugs in production is unfortunate but unavoidable. Depending on the severity of the bug, the fix may require bypassing the next scheduled release. In these cases, a hotfix patch must be merged back into the active release/<version> branch directly from a hotfix/<version>-<title> branch. Depending on the scope of the bug and the number of legacy release branches in play, a support fix may also be required.

Similarly to how merging a feature into the develop branch should prompt all developers to merge develop into their respective feature/<title> branches, merging a hotfix into develop should be followed with develop being merged into all active feature branches.

The hotfix branch takes the form hotfix/<title>, where name is a short, unique, and descriptive name identifying the problem. Two WIP pull request should be opened by the developer immediately after they are given an initial commit; one into the release branch and one into the development branch. A maintainer should assigned to these pull request by the developer. The developer should remove the WIP status from the pull requests once they believe that the hotfix is complete. The maintainer should then review the pull request into the feature branch. If the review is rejected then the developer will be required to resolve the concerns of the maintainer. If the review is accepted, then the maintainer will push a version tag and then merge the pull request into the release branch. Once the change is deployed, the merge request into develop should be merged by the maintainer.

... ---------------- E --- [master]
                    /
... -------------- D ----- [release/<current>]
     \            /
      `- A - B - C         [hotfix/<title>]
                  `--.
                      \
... ------------------ F - [develop]

+-----------------+---------+
| Initial Commits | A       |
+-----------------+---------+
| Feature Commits | B       |
+-----------------+---------+
| Merge Commits   | D, E, F |
+-----------------+---------+
| Tag Commits     | C       |
+-----------------+---------+

Diagram

This workflow shows merging a support into to an existing legacy release branch.

Support Fixes

Support fixes are like hotfixes in that they are done on special branches made from a given release/<version> branch and that they are merged directly back into the release branch. However, they are different in that their changes are to be applied to legacy releases, and they cannot be merged back into develop. If the bug affects multiple releases, they must be addressed independently to avoid issues with merging stale code and mixing version tags between releases.

... ------------------ [master]

... ------------------ [release/<current>]

... -------------- D - [release/<legacy>]
     \            /
      `- A - B - C     [support/<legacy>-<title>]

+-----------------+---+
| Initial Commits | A |
+-----------------+---+
| Feature Commits | B |
+-----------------+---+
| Merge Commits   | D |
+-----------------+---+
| Tag Commits     | C |
+-----------------+---+

Diagram

This workflow shows merging a support into to an existing legacy release branch.


... ---------------- E --- [master]
                    /
... -------------- D ----- [release/<current>]
     \            /
      `- A - B - C         [hotfix/<title>]
                  `--.
                      \
... ------------------ F - [develop]

... ---------------- D' -- [release/<legacy>]
     \              /
      `- A' - B' - C'      [support/<legacy>-<title>]

+-----------------+-------------+
| Initial Commits | A, A'       |
+-----------------+-------------+
| Feature Commits | B, B'       |
+-----------------+-------------+
| Merge Commits   | D, D', E, F |
+-----------------+-------------+
| Tag Commits     | C, C'       |
+-----------------+-------------+

Diagram

This workflow shows merging a support into to an existing legacy release branch while also pushing a similar yet independent patch from a hotfix branch into the current release.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages