On July 15th, Doguhan gave a talk at CodeStock 2016 titled Minimal MEAN. Doguhan’s talk focuses on adopting a minimalistic approach to leveraging frameworks of the popular MEAN stack, MongoDB, Express, Angular and Node. His suggestions extend beyond software frameworks, but also to the tools and infrastructure that enable cloud delivery and effective teamwork. This blog post highlights crucial insights into how best to utilize GitHub to achieve effective team work.
Are you using Git for your personal or professional projects? If not, you’re missing out on the most flexible and resilient source control technology available to you. The distributed nature of Git makes it ideal for small and large teams alike. You end up maintaining a full or partial copy of the source control database on your local environment. You don’t need to worry about checked-out or locked files. Your working copy and your local copy (aka cloned repository) are kept separate. You commit your changes against your local copy and then sync your changes with the central copy (aka remote repository). You may use Git Command Line tools or GUI tools like Git Extensions or Tower to interact with your local copy or the central copy. You may encounter merge conflicts along the way, where two people have changed the same line of the source code. There are robust tools available such as kdiff3 or Kaleidoscope to efficiently handle such conflicts when they happen.
Living with Git
Git is extremely popular with the open source community due to the distributed and asynchronous way Git can work. For most people, GitHub is synonymous with Git. GitHub is a Git repository host that provides free repositories for open source projects, private repositories hosted on their servers for individuals or companies and an enterprise solution that can be installed on-premises. With 38 million repositories in 2016, it’s no wonder GitHub has the mindshare.
If you are using Git chances are you’re using GitHub (or Bitbucket). I’ll be focusing on GitHub and it’s specific capabilities to demonstrate, how you can leverage to transform the way you develop, maintain and release software.
Much More than Just a Repo(sitory)
GitHub does more than just host Git repositories; it implements integrated issue tracking, collaborative code reviewing, team management, great integrations, security, extensibility, and more. The most important feature of GitHub is the GitHub workflow that is implemented through Pull Requests and webhooks. More on this later.
GitHub issues can replace your existing issue tracking system with ease. You set labels, milestones, assignees, and rich details to issue tickets. Best of it all, GitHub will automatically link specific commits to issues making it much easier to locate the piece of code that fixes a specific issue.
Through such deep links to specific commits, it is possible to kick of impromptu or enforced code reviews. Inline comments allow for feedback to be provided to the developer.
Need a Kanban/SCRUM board? You can easily set that up with Waffle.io based on your existing milestones and issues you’ve created on GitHub.
Danger — High Voltage
Git has some very powerful (and dangerous) command line functions. Sadly online communities such as StackOverflow can provide ammunition to novice users to shoot themselves (and sometimes their team) in the foot with bad or incomplete advice. Consider the top two replies to a question related to forcing git to overwrite local files on pull. The top reply is thorough and attempts to properly warn and educate the reader.
The second reply is terse and leaves the user hanging.
Unfortunately, novice users have a tendency of following the simplest and most direct instructions, potentially leading to lost work.
Need more convincing on how out of hand you can get with Git? Check this out.
GitHub to the Rescue
Thankfully with GitHub you can protect branches and prevent some of the more common harmful Git commands from making irreversible changes on your master branch. The master is the default mainline branch that you work on. You may choose to protect any other branch of your choosing as well. However, GitHub doesn’t just stop there, you can restrict who can push to a branch, and also you can disable pushes to branch altogether, forcing the use pull requests.
It may sound inconvenient, inefficient or a hassle to not to be able to directly commit to your master branch. This is not the case. In fact, if you and your team is directly committing to master, I can say that you’re using GitHub wrong. I’ll expand on why in the next section.
One of the greatest challenges working with Git can be in reverting pushed commits. You may want to do this for numerous reasons. Sometimes you may simply want to rollback an entire feature, sometimes you want to reject a certain commit due to bad code quality and other times the commit may have broken your Continuous Integration (CI) pipeline and your entire team is blocked.
Consider a team of 20 people working against the same repository and commit code changes multiple times a day. Developers should be committing code as atomically as possible, so this is actually desired. So if Developer 1 (A), commits code for a particular feature from their perspective the commits will be created in order, like A1, A2, A3 and on. When Developer 1 is done, he/she will push their code to the remote repository and their commits will become a part of the master branch based on the time they were pushed. Meanwhile, Developer 2 (B) has been committing code as well, like B1, B2, B3 and on. When Developer 2 pulls the updated code, Developer 1’s commit will appear on Developer 2’s local copy.
Developer 2’s local copy would look like this:
At this point, Developer 2 will retest his/her code and fix any bugs with their feature before pushing their changes. Let’s suppose Developer 2 finds a bug and creates commit B4.
So now the branch looks like:
We can extrapolate this across 20 developers, all working on their features and you could easily end up with a history that looks like:
For arguments sake, if each letter represented a feature across multiple commits, attempting to roll back any of these features have become a non-trivial and an error-prone task. Your commits have become a tangled mess, good luck untangling them.
Requiring status checks to pass before merging option in GitHub will prevent commit entanglement issues. Since you can’t commit directly to master anymore, you’ll need to first create a branch commit your code there and then submit a pull request (PR) before you code can be merged to the master. Doing this may seem like a chore, however GitHub’s excellent cross-platform GitHub Desktop client makes it easy.
Now developers will work on features in individual branches (A, B, C, D, E) and will submit a PR when the features is ready. This way developers can continue to collaborate on feature branches, while all commits related to a feature will be nicely bundled together. So if you want to rollback a feature, you can do so with easer. In case code quality and integration issues, the true benefits of status checks comes into play, when we start leveraging GitHub integrations and webhooks.
We can enable CI integrations to run all automated tests, unit tests, static analysis, code style/linting checks and more to all pass successfully before a PR is allowed to be merged to the master branch. This way we can guarantee a certain base level of quality on code that our team at large will be exposed to. This will prevent team blocking CI pipeline breakage issues that affect many software development teams.
Automated tools can go so far in ensuring great code. Utilizing tools like Review Ninja we can enforce code reviews to be completed as well before a PR can be merged to master. We can only allow a certain group of developers to be able to conduct code reviews or we can enable peer reviews.
Succeed with GitHub
If you implement the GitHub Workflow comprehensively and fully, your team may take a few weeks to get used to it, but shortly after your team will become more efficient and produce higher quality code with a dynamic code delivery mechanism that can adapt to business needs. In a 12 month long project, using an Agile SCRUM delivery methodology we may choose to start off with peer code reviews. However as the release date nears, we may choose switch to an SDLC workflow and intentionally create review bottlenecks to ensure quality of bug fixes and last minute feature deliveries.
Here’s an overview of how the workflow will look like from a developer’s perspective:
- When starting to work on an issue, new feature or even the most minor code change create a branch, include issue number and short description in the title whenever possible
- After creating the new branch, you can publish is without any commits so it’s visible to others for collaboration or observation
- Work on the issue, fix or new feature using the branch until its ready
- You can collaborate with others to work on the branch
- Plan to sync your branch often, at least once a day, so others can potentially pick up where you left
- Once a fix, issue, or feature is ready then create and send a Pull Request (PR) containing your changes
- A PR will be subject to a code-review (enforced via a webhook to Review Ninja)
- A PR will be subject to a successful CI run (enforced via a webhook to CI server)
- Optionally a PR may be subject to automated acceptance tests (enforced via a webhook to 3rd party service)
- You’ll only be able to merge your PR after all aforementioned checks have passed
- If a PR fails to go through all the checks, you can commit changes to the same branch and update the PR that has failed
I urge you to fully leverage all the capabilities that GitHub provides. You cut redundancies, errors and save much need time in the process.
Please let me know if you’ve any questions or comments!