Code Management

GitHub

We use git for source control using GitHub https://github.com/Instrument/. Other source control systems are used as required by client needs.

When using service based source control like GitHub, it is important to make sure your account has 2FA(two-factor authentication enabled)

When updating your OS sometimes the keychain loses access to your SSH keys. If you find you’re having to enter your password every time you push or pull using SSH add

Host *
 AddKeysToAgent yes
 UseKeychain yes
 IdentityFile ~/.ssh/id_rsa

to your ~/.ssh/config file

PR Approvals

We use a Pull Request workflow which requires 2 approvals for merging. All code changes must be made in a branch or fork of the main development branch and submitted via Pull Request.

Ideally one approval comes from inside the project team and one comes from outside the project team to get an objective view.

Git Flow

Some variation of the Git Flow model is encouraged. For example:

Branches

  • master (production/tagged branch)
  • develop (main branch)
  • feature/[branch-name]
  • update/[branch-name]

Branching

  • master - a direct correlation to production code. The only time master is to be updated is from a merge from the dev branch and after code has been pushed and verified to a production environment. Merges should be tagged with a release version.
  • develop - a direct correlation of dev environment (if necessary). The only time develop should be updated is from a pull request and a merge from a feature/bug branch and only so the code can be verified in a dev/stage environment.
  • feature/bug - branched off of develop the branch should be a self contained feature/bug or set of features that can be easily added and reverted without affecting code that falls outside of a task scope. Branch should reference the issue # or name as applicable for tracking and regression.
  • sub-feature(optional) - branched from another feature branch typically for division of labor or experimenting. Must be pull-requested and merged into parent branch only
  • hotfix(optional) - for continuous delivery scenarios, a hotfix branch is the only branch that can be created off of master and is used to fix defects that are present in production and cannot be addressed through the normal development cycle. Once merged into master the change must be pulled into all other active branches. Use with caution.

Keeping it clean

Before submitting a pull request, developer should rebase the target branch onto their branch then squash all commits into the least amount possible so that the commits are self contained, easy to reference, and revertable should they need to be. This way, when the branch moves to a dev environment, there is only one or several commits that can be added and removed holistically.

New Project Workflow

  1. new project begins. Repo should be initialized with a Readme.md in master that is filled out with basic getting started information. Most repos should be initialized with GIT LFS for separate blob storage using text pointers.
  2. develop branch is created off of master and set as the default branch. Dev and staging, continuous integration, and other services should be setup at this time.
  3. work begins on a separate, feature branch off of the develop branch. Branches should be named from issues if possible.
  4. when work is complete, rebase the target branch onto their branch to fix any conflicts to ensure a pull request can be merged cleanly
  5. squash commits and submit a pull request
  6. pull request should be reviewed for code practices and tested in an environment for regression.
    • developers shouldn’t merge their own pull requests
  7. After a pull request is merged, the developer who created the feature/bug branch should delete that branch to keep the repo clean.

Commit Messages

Messages should have a summary line using 72 characters or fewer and an optional detailed message in paragraph form using complete sentences. If the detailed message is included, please enter a blank line between the two parts.

The summary will be the only part of the message visible in many git tools, so please be as descriptive as possible within the character limit.

Issue Tracking and Branches/Commits

Depending on the issue tracking being used you may have some GitHub integrations that allow auto-advancements of issues through a workflow based on branch names, commits, pull requests, and merges. The recommended tracking system is GitHub Issues. You may use services like Waffle.io on top of that for planning boards. Follow the guidance for those tools when commenting on commits and naming branches.

Rebasing and Squashing

Assuming you have some commits on a feature branch you want to squash and eventually merge:

  1. Use git log your-feature-branch ^branch-you-want-to-merge-into (example: git log feature/branch ^master) to see which commits are on your feature branch compared to the branch you want to merge into
  2. Use git rebase -i HEAD~NumberOfCommitsToSquash (example: git rebase -i HEAD~5)
  3. On the next screen you’ll have to ‘pick’ the first commit. Write the word ‘squash’ or the letter ‘s’ next to the other commits you want to squash into the first one. Save. Alternatively using ‘r’ reword for the first commit and ‘f’ fixup for the others will simplify the next step. Here is a nice guide to git rebasing.
  4. On the following screen choose your commit message. Delete the ones that were used and write a new one for the combined, squashed commit if necessary. Save.
  5. If the commits were local (not pushed) then you can push as you normally would. If the commits were already pushed you’ll have to force push using git push -f origin feature/branch
  6. Create a pull request

Remember, if possible, always try to squash commits before rebasing a master/develop branch so you don’t accidentally squash rebased master commits. And if you have any questions or need some help, ask someone.

GIT LFS

Blobs typically don’t need strict versioning and unnecessarily bloat your repository. GIT LFS provides a method of CDN blob storage for your media files using text pointers in the actual repo. This is much more efficient method of dealing with media in repositories and should be used in most cases when first setting up your repo. GIT LFS is supported on all repos for GitHub.

Gotchas

  1. If the repository isn’t initialized to use GIT LFS at time of creation it can be painful to convert later. Better to initialize GIT LFS and then optionally not use it.
  2. Everyone using the repository must use GIT LFS otherwise checking in/out becomes a mess where not GIT LFS users may be checking in media instead of the system of text pointers to CDN blob storage.
  3. Repositories used as things like NPM modules will not work with GIT LFS. 4.