This will be a running list of things that I found useful while working on enterprise projects. These can be good tips for other projects too but since there are usually a lot of developers working across enterprise codebases, it is a good idea to establish and enforce some Github (GH) practices in a timely fashion (when new repositories are created).
Use Trunk based development
Find more info here. This basically means using a main
branch for all development work. Doing this helps you move your code fast to production.
The alternative is something like Gitflow which is a pain to work since you usually have to keep multiple branches in sync with this.
To achieve true trunk-based development, developers should have the necessary tools to fully test each PR in an integration environment. This can be achieved with a preview environment per PR. You might be familiar with how Vercel does this per PR but otherwise, your company might need to set up some in-house infra to provide this support.
Set up branch protection for main
Enable branch protection to ensure developers follow proper processes before merging code to main
. This also ensures devs cannot directly push commits to main
, unless you want that for certain developers, which is generally a bad idea. Any changes should go through a PR.
See Github docs on how to set this up.
Enable Squash and merge
only for all GH repos
Github provides 3 different options to merge:
On larger projects, where you have a lot of developers working on a common repo, using any of these other options generally means you'll have a bunch of commits on main
branch that don't make sense. I know some projects/developers tend to argue that each commit should be a semantic commit, sometimes this just adds too much pain for devs and hinders the ability to move fast.
Since developers should generally be advised to make smaller commits for quicker prototypes and better developer experience (DX), a PR with 50+ commits shouldn't land on the main
branch the same way. With Squash merging, you only create 1 commit for 1 PR on main
.
This is super valuable when you have a production issue and you have no idea where it came from and you have to now git bisect to find the root cause. With squash merges, you can pinpoint which PR introduced a bug much quicker!
Enable semantic PR checks
Prefer to use conventional commits on any commits to main
branch. This extra piece of information on every commit can be super valuable if your repo is publishing packages to npm/Artifactory and you want to automate bumping major/minor/patch versions of packages. But even on a feature repo with web applications, this provides a nice overview of main
branch commits indicating features, bug fixes, chores, etc.
Since you now have only squash merge enabled, you can enable every PR title to have the conventional commit prefix with a Github action PR check.
Have a CONTRIBUTING.md file for your repos
Create this file as a guide to provide newcomers with onboarding documentation. If you would rather have a common Onboarding document for a larger group with something like Docusaurus, link to that site from this file.
Create smaller GH teams and make them CODEOWNERS
When working in a polyrepo setup with multiple teams owning different repos, having a smaller GH team is nice since you can easily identify ownership. If you have a group of 100 people owning a functionality, it usually means no one owns it. A smaller group, who can be held accountable for an area, is better for quicker feedback cycles.
Add this GH team to the CODEOWNERS file to ensure any PR creations on the GH repo would need the code owner group approvals.
Use Renovate to automate dependency upgrades
In larger projects, keeping dependencies up to date is critical in the long term. Renovate makes this easy by creating PRs for you. It comes with a lot of baked-in defaults as well to make your life easy. For example, dependencies next
and eslint-config-next
should be upgraded together in NextJS projects. Hence Renovate creates a single PR for both of these updates and makes the necessary lock file updates for you. It also supports pnpm
which is my go-to package manager for all new projects. Check their docs [here](https://docs.renovatebot.com/).
Enforce PR checks
Create PR checks for build
, lint
, test
, format
, typecheck
etc. to make sure any commits going into the main
branch are safe. Also, GitHub lets you mark these PR checks as Required
so that developers cannot merge their PRs until these checks pass. You can find this under the branch protection setting for main