Group Created with Sketch. Group Created with Sketch.

Source Control

We use Git for source control and GitHub for hosting unless a client requests otherwise.

If a client has their own GitHub team and wishes to own the repository, then the same process and expectations should be followed on their upstream repository. We should avoid forking their repo into our own Github team unless it's absolutely necessary.

We follow Github Flow for a branch-based workflow but have our own spin on it. Here are a few rules:

  • Anything in the master branch is always deployable
  • Use branches for features, hotfixes, and other changes
  • Use release branches to test deployments and merge into master
  • Never push directly to the master branch
  • Perform code reviews before anything is merged
  • Fix bugs in master first and release branches second
  • Commit messages reflect intent

Master

This should always reflect the code that is in production. CI (continuous integration) and CD (continuous deployment) should be used whenever possible to ensure that code merged into master is deployed to production as soon as possible.

The master branch should always be deployable to production. A branch should never be merged into master unless it's passed CI, approved in a review, and approved by the stakeholders for production release

Branching Model

All branches should be created off of the master branch. This branch should automatically deploy to a staging environment. Whatever is in master should be ready for production.

Developers can decide whether or not they want to fork a project or work on an upstream branch. Upstream branching is allowed and sometimes recommended to support continuous integration via Codeship.

When upstream branches are used it is courteous to delete your branch after it is merged to help keep the number of upstream branches reasonable.

The following labels should be added to each repository to help quickly determine the status of a pull request:

Work in progress: This PR should not be reviewed or merged

Awaiting API: This PR can be reviewed, but not merged until the backend is ready (usually an API endpoint is needed)

Awaiting FE: This PR can be reviewed, but should not be merged until the front end is ready

Awaiting Review: This PR is ready to be reviewed and, if approved, merged into master

Branching

All branches should be created off of the master branch. Each feature, bugfix, enhancement, and refactor should have a corresponding branch prefixed with the following:

feature/: A new feature that is being worked on. This, ideally, adds functionality that did not previously exist in the application.

patch/: Updates to a previously committed feature that is already in the master branch

bugfix/: A fix to an existing feature or to the core functionality of the application.

enhancement/: This pull requests makes some modifications and/or improvements to existing features and functionality without changing the

refactor/: This pull request should not affect the functionality of the application, but should be used when code is rewritten or reorganized

release/: This pull request is a combination of other pull requests that will get deployed together in a single release. These are not required unless there is a lot of activity happening on the repo daily

Other prefixes are acceptable if the purpose of the branch does not fit into these categories, but a branch name should always be prefixed.

Committing Code

Once you've created your branch, it's time to make your codebase changes. Commits keep track of progress as you work on the feature branch. Some best practices:

  • Commit as frequently as possible, making small incremental changes
  • Write clear commit message that make easier for other people to follow along

Pull Request

Pull requests are how we merge code into the master branch. All code changes should be submitted to master as a pull request – never directly committed to master.

Pull requests can be submitted when code is not complete. In these cases, create a draft PR in Github or prefix the name of your PR with [WIP], e.g. [WIP] New Commenting Feature. Work in progress PRs are useful when you want to get feedback on your potential solution or want to share initial feature implementation.

When submitting a pull request, make sure address the following:

  • Give the pull request a descriptive title (please don’t leave the prefixed branch name as the title)
  • Write any steps that might help to review the code as the initial comment of the pull request
  • Assign the team lead (and any other developers) to review the pull request

If you've pushed your code to a remote repository then you should avoid `git rebase` and only use `git merge`. Rebasing writes history so it can cause lots of problems when working wither other developers on the same features.

If your PR has no conflicts, then you can use Github's built-in merge tool. Otherwise, you can do the following locally:

  1. Checkout the master branch
  2. Pull any changes to master
  3. Checkout the feature branch
  4. Run git merge master --no-ff
  5. Resolve any conflicts
  6. Create a new commit
  7. Push your feature branch to the upstream
$ git checkout master
$ git pull origin master
$ git checkout my_branch
$ git merge master --no-ff
# resolve any conflicts
# create new commit for resolved conflicts
$ git push origin my_branch

Sometimes it’s difficult to know which changes to ignore and which to keep when resolving conflicts. If you run into a conflict you are not sure about, contact the team lead, and they will help you to resolve it.

Merge into Master

Although this is typically something handled by the lead developer, anybody on the team can merge a branch into master whenever it's ready to go. Here are some rules to follow by:

  • Pull request has been approved
  • All tests passed CI
  • Testing has been completed on staging/review environments
  • PM or stakeholder has given approval to deploy

When merging a branch, always use the Squash and Merge process. Squashing will combine all of the commits from the feature into a single commit. This makes reading the commit history much easier and helps us rollback if needed. You can use the built-in Github feature or use the Git commands:

$ git checkout master
$ git merge --squash my_branch
$ git commit

If a feature branch is ready to go and doesn't depend on any other features then this can be merged directly into master and deployed to production.

Release Branch

In many cases, we might need to roll up a few PRs into a single deploy. This is typical when we are deploying frequently and have multiple developers on a project. In these cases, it's best to create a release branch and merge that into master.

Release branches should be used whenever we are deploying a new build with multiple features. The release branch allows us to test all of the new features together without merging into master.

Here is a typical process:

  1. Create a release branch from master: "release/YYYMMDD" (if you're making another release in the same day, add "-2" or "-3" at the end
  2. Change the base branch of all the PRs you want to deploy into the new release branch
  3. Wait for CI to pass
  4. Deploy the branch to the staging/review environment
  5. Test with all developers involved
  6. Merge into the master branch and deploy
$ git checkout master
$ git checkout -b release/20190417-1
$ git merge --squash feature_1
$ git merge --squash feature_2
$ git merge --squash feature_3
$ git push origin release/20190417-1

If your unsure about anything, just reach out and somebody on the team will help. If you're interested in learning more about Git and how to use it, check out these helpful links: