How to Share and Sync Modules Between Repos with Git Hooks and Bit

Learn how to automate your Bit/Git workflow with Git Hooks

Disclaimer: This article in not an official Bit document but only my own personal recommendations for automating some of the steps to keep your component’s code in-sync between the repository where it resides and Bit’s registry. If you don’t know what Bit is or how it works, I’d recommend checking my previous article on the subject: “A Better Way to Share Code Between Your Node.js Projects”.

With that out of the way, let’s get started, shall we?

If you’re familiar with Bit, you’ve probably noticed how you need to add extra steps to your Git workflow in order to keep track of the changes done and keep the central registry (the one on the bit.dev platform) updated with the latest version of your code.

The current workflow

Currently, the suggested full workflow for an existing project that is both, already set up in Git and in Bit, states what has to happen when someone wants to edit one of the shared components:

Assuming you’ve updated your component on a different branch, you’ll start by merging your changes into your master branch. Once this is done, you’ll have to update your component’s code, but before doing that, you need to make sure the latest version has been downloaded to your local computer. You can do that by running bit import (you can think of it as doing a git pull before merging). The import should take care of synching your local and remote codes, making sure you have the latest version. This means you’re ready to continue with the versioning of your component. You can check the status of the pending changes by running bit status . This step is optional, and it’ll give you the confirmation that everything’s looking right (i.e the changes you’ve done are being recognized). By updating the version of your components you’re essentially cementing those changes in the new version. This is easily done with a simple command: bit tag --all --patch --message 'your tagging message' . The --patch parameter takes care of only updating the patch section of the version on your component. You can also specify --minor for changes that don’t break backward compatibility and --major for extreme version changes. I’d recommend checking the full documentation for this command here. Finally, once the tagging is done, you need to upload the new version, which with Bit this is known as exporting. You can do this with: bit export <account-name>.<collection-name> . And as the last step, you also need to remember to commit the .bitmap file to your Git repo, since that file is the one needed to keep both Git and Bit in-sync.

That is a lot of work to commit changes, especially if those changes are minor updates. So what if instead, you could automate all those steps into a single hook?

Git Hooks galore

As you may or may not know, Git provides you with the ability to write your own hooks for a series of events. In fact, this is the full list of hooks you can create:

Feel free to read more about git hooks over here. As a rule of thumb, any hook prefixed with “pre” can stop the action by exiting with a non-zero exit code.

Every .git folder out there has a hooks folder inside, where you can find a lot of .sample files. They’re simply bash scripts with examples of useful hooks. Of course, they don’t really have anything like what we need, but we can easily automate the above steps into a simple bash script.

Finally, a small note: these files are all bash scripts, but there is nothing out there stating that you need to write your hooks in bash. You can use any language. For instance, here is a JavaScript “commit-msg” hook that checks the length of your commit message and makes sure it’s long enough:

It’s a silly script, but it’s enough to show you the flexibility. Remember to add execution permissions to that file if you want it to be executed by Git!

Putting it all together

To put everything together, we’ll simply create a new “post-merge” hook, this will make sure that once we merge code into one particular branch (I’ll use master for the example, but you can pick the one you like), we’ll trigger all the six steps from before.

The steps from the script are:

Getting the current branch name to check against it later on. Getting the last commit message and extracting the first word for it. With it, we’ll grab the type of version update we’re requesting (i.e your commit message needs to start with either MAJOR, MINOR or PATCH) and use it down the line for the tag command. Checking for two environment variables: BIT_ACCOUNT_NAME and BIT_COLLECTION_NAME . These variables are meant to be configured by you (or your CI script) and should contain your account name and the collection’s name. You could also have some sort of configuration file (like a JSON or a properties file) with these values inside and read it to get these values from it. Finally, run the set of commands we covered already.

Here is the output from the merge operation once the hook is ready:

You can see there how we’ve merged the code, then extracted the message (i.e it’s a minor upgrade) then we tag and export the new component. We finish with the commit of the modified .bitmap file. You could add a last line to perform the actual push of that change, but it’s up to you.

Disclaimer

It is true that the above workflow might end-up yielding unwanted component exports, since this script will run every-time you merge (which includes doing pulls making sure you have the latest version of master in your local).

That being said, remember that for an unwanted merge to happen, the following conditions need to be met:

The branch needs to be the master branch, otherwise, the script will end.

The commit message needs to start with one of the following words: minor, major, patch.

And the environment variables BIT_ACCOUNT_NAME and BIT_COLLECTION_NAME need to be defined.

If one of these three points isn’t met during your normal pulling or otherwise non-component related workflow, no unwanted side-effects will occur.

Finally, you’re free to add extra conditions to the above bash script to make sure it gets executed only during the correct conditions.

Conclusion

Bit is a great tool to share components between modules or even projects with minimum impact on your code structure. But at the same time, the extra steps required to make it work with Git can become a problem if your team isn’t proficient with command-line tools.

Now, thanks to a simple bash script, you’re able to automate the entire Bit interaction, essentially gaining the benefits of the tool without even having to use it on your daily basis.

Leave a comment if you can think of an easier way to automate these steps, remember any scripting language is just as valid as bash!

Otherwise, I’ll see you at the next one!

Learn More