I have been developing software for 10 years, participated in several open source projects and numerous non-open source projects, worked in large and small teams, and everywhere we used Github as a versioning repository.
During this time, I tried different workflows, and I want to share tips on how to build an effective and pragmatic workflow for creating and maintaining quality software that can be used in any project.
There are many signs of quality software: reliability, stability, modularity, security, performance, scalability, ease of use, testing and maintenance. And many other signs, depending on the type of application. In this article I will focus on the following properties:
- Good documentation: readme, documentation sites, and change logs.
- Detailed agreements and coding standards.
- Correct versioning with semantic versioning.
- Automated tests: use them too little, focus on functional non-regression tests.
- Of course, the happiness of the developer!
I propose to build a pragmatic workflow using open source tools that help to perform and automate many tasks.
')
If you are working in an open source project, you probably want to publish your Github project. Git and Github have completely changed the way OSS is developed, becoming de facto, respectively, the standard versioning language and platform for collaboration.
The workflow officially proposed by Github is called
github flow . It is beautifully described
on the site . This process, with minor variations, is followed by the majority of open source projects.
Github Flow is very flexible in the sense that it does not dictate to you how to release and document changes, what merge strategy to use, when to accept pull requests, what tools to use, what commit standards to follow, or what to review before accepting pull request but. All this is left to your discretion, and rightly done, because there are no universal solutions suitable for all teams.
Next I will give a list of recommendations based on my experience.
For the most part (almost exclusively) I write in JavaScript, many of the tools I mentioned are part of the JS ecosystem, but the ideas themselves are applicable in any language.
Prioritize tasks and track progress using Github Projects
In September 2016, the Projects feature appeared. It is a tool to create Kanban-style boards for organizing, prioritizing, and tracking work at the repository and organization level. If you have trouble using Github, I strongly recommend that you master Projects to organize and share information about project priorities and current efforts.
Read moreCategorize tasks with tags
Github has excellent filtering capabilities. If you are working on an open source project, you are probably interested in attracting other participants, as well as in making them comfortable. If you tag your tasks with tags, it will be easier for developers to navigate the list, it will save them time and facilitate the work on the project.
Use Github templates for pull requests and tasks.
Take the time to write Guthub templates for pull requests and report problems. This will force other developers - or at least help them - to send bug reports and request the creation of features in some standard way, putting all the information you need.
Read moreBasic tips on reporting bugs :
Before submitting an issue:
- Make sure you are using the latest version.
- Look for the mention of this bug, perhaps, an account of it was already before.
Bug reports should contain:
- Short description.
- How do you encounter a bug? Instructions for playback.
- What behavior did you expect from the application?
- How did the app really behave?
- Links to all situation-related tickets or informational sources.
- Whenever possible, attach a visual confirmation of the bug. Screenshots, videos and / or animated gifs.
General recommendations for pull requests :
- Check that there are no other pull requests for your problem.
- Check in the bug tracker if there were any problems with your bug.
- Nontrivial changes are better to discuss.
- Let us know what task you are working on.
- Develop in a specific thematic branch, and not in the wizard.
- Write a description of a useful pull request.
- Follow the recommendations on commits in the project.
- Write a good description of your pull request.
- Specify the link to the Github task in the description.
Use command line
The console is your friend. In my experience, mastering Github via the command line is the best waste of time when working with open source technologies. Yes, there are many good graphical interfaces, but they are all less flexible in use. In addition, there are tools only under the command line, which greatly simplify life and increase the efficiency of development:
- hub is a Git wrapper that makes working with GitHub easier. No matter you are a beginner or an experienced open source developer, hub will make it easier to retrieve repositories, navigate through project pages, work with forks, and even send pull requests. And all this from the command line. hub.github.com
- tj / git-extras - a set of Git-utilities, such as a repository summary, a repl, a change log, statistics on commits by authors, and much more. github.com/tj/git-extras
Observe strict standards for commit messages and categorize commits.
Always define and follow clear standards for writing commit messages. Here are some recommendations:
- Commit each fix as a separate change.
- Write useful commit messages.
- Write a short commit message in the first line (50–100 characters). If you look at the output of
gitk
or git log –oneline
, then you will understand why. - Refer to the Git task in the body of the commit message.
In addition, to improve the generation of the change log, I strongly recommend that you distribute the messages into categories (scope). Then your change logs will be more informative. A great example:
commit agreements and generating change logs in AngularJS .
Define code design standards and configure precommit hooks.
To write a maintainable code, it is very important to define the standards for decoration and to comply with them in pre-commits hooks. Standards will help maintain the uniformity of the code regardless of who writes it, as well as help to receive and accompany code written by someone else.
I recommend using Prettier and StandardJS, but this is a matter of taste, there are many other solutions; besides, you can do something of your own. The main thing is to follow the chosen code design standards, this will be beneficial.
typicode / husky is a great tool for configuring pre-commit hooks.
Use automated tests and pull request checks
It is highly desirable to automate functional tests and security checks and code design for each pull request. You hardly want to do all this manually. You can quickly configure a continuous integration server, such as TravisCI, to automatically run a topic branch through tests after sending each pull request. You can also configure Github so that it does not allow the developer to attach pull requests if they have not passed the tests. If the tests fail, Github will show the author a message to correct his pull requests.
More details .
Protect your master branch and ask for a code revision
Github allows you to protect the master branch from direct commits, forced push and relocation. This is very important when working with someone on a project. In addition, be sure to request a revision of the code before combining it with the master branch. This is set in the settings tab of each repository.
By protecting the master branch and turning on the forced revision, you will know that the unwanted code is unlikely to get into the master and that no one in the team substitutes the rest by changing the master's Git history or pushing an unverified code.
Squash your pull requests
There is a lot of controversy about what is right: merge, squash or relocate. I think it's best to squash, because:
- Not all developers know how to correctly relocate pull request over the master branch. Many simply merzh master on top of their changes. Squashing allows you to get rid of merge-messages that are useless for the future formation of a change log and simply make noise in the Git-log.
- Not all project participants will follow the recommendations on making commits, and squash allows you to manage the commit messages that arrive in the master branch.
To successfully build a squash-based workflow, you need to categorize all pull requests by specific features, bug fixes, or routine tasks.
Semantic versioning, github tags, releases, and automated changelogs
Versioning plays a huge role, especially in open source projects, many of which will depend on your software. Semantic versioning will make life easier for everyone, because people, looking only at the version number, will know when critical changes were made, or whether the version contains new features or bug fixes.
Given the template MAJOR.MINOR.PATCH, increase:
- Older (MAJOR) version, if you make changes to the API that are incompatible with previous versions.
- Minor (MINOR) version, if you add backward compatible functionality.
- Patch version (PATCH), if you make backward compatible bug fixes.
As extensions to the template MAJOR.MINOR.PATCH, you can use additional labels for prereleases and assemblies.
In addition to changing the version of package.json, I recommend to generate a git-tag for each version.
More details .
The Conventional Commits specification implies compliance with a simple standardized agreement when writing commit messages. It is linked to the SemVer agreement, which asks developers to describe in commit messages all features, fixes, and breaking changes. Following the agreement, we create a standard language that simplifies debugging in various projects.
More details .
Automate this process will help
TravisCI .
Also note these packages:
dominique-mueller / automatic-release ,
semantic-release / semantic-release .
Automate deployment using tag-hooks
It is not necessary to use release branches, as proposed in Git Flow. You can take deployment artifacts from Git-tags.
Here is a description of how to deploy Git-tags in heroku using TravisCI . This is very simple, you only need to set the tag attribute to true. This behavior can be implemented using any other CI server.
For the development environment, you can configure a hook that deploys the last master commit. And for feature environments, you can use less long-lived branches; If you wish, you can provide a temporary test environment for each PR request, but this approach is more complicated, and it is not mandatory.
Set up streaming Github channel for chat
A very convenient way to track activity in your Github repositories from a place that is perfect for interacting with a team: a simple stream of notifications in one or several chats. By the way, you can do much more in chat rooms, in 2013, the term
ChatOps appeared on Github, more about it is described
here .
Automate dependency updating
We have to spend a lot of time regularly on updating dependencies. This is an ideal task for automation. There are many tools that help keep dependencies “fresh” by automatically creating pull requests with the latest versions in the project. These requests will be driven through automated non-regression tests, and if they pass successfully, then we can hope that the code after merging will work fine. Be careful with changes in the level of older versions, double check everything.
A couple of useful tools:
greenkeeper.io and
david-dm.org .
With the help of extensions, improve work with the Github interface
Open source developers have created many useful extensions that improve the work with the Github interface. For example:
Other extensions:
GitHub Browser Extensions .
At
Kikobeats / awesome-Github, there are more tools to improve your workflow.
Permanent study and self-improvement
Github and open source software development techniques are constantly evolving, so keep abreast of the latest trends and tools, keeping track of Github news and following the standards of your community. A great source of information is the
Youtube channel GitHub Training & Guides .