DEV Community

Cover image for Run Git commands from Node.js application using JavaScript! 🚀
Jakub Skoneczny
Jakub Skoneczny

Posted on • Originally published at blog.jskoneczny.pl

Run Git commands from Node.js application using JavaScript! 🚀

When dealing with large applications and with complex, CI/CD pipelines with multiple staging environments, it might be useful for you to have some way to automate applying the latest changes from one environment to the other.

Consistency between multiple environments

At my work, we have three environments - one is the production environment (PROD), and two others are for fixing critical errors (HOTFIX) and developing new stuff (STAGING) with the possibility of introducing breaking changes.

While creating a pull request with a quick fix of some bug and merging it to the HOTFIX environment (with future deployment to production), it is also necessary to have this code in the STAGING environment, so the future deployment of STAGING into PROD would not cause conflicts.

The easiest way for having this cross-environment consistency is to make cherry-pick of the commit to STAGING after it is merged into HOTFIX. Easy, but manual, and since it's manual, someone can forget to do this. 😅 Plus, we need to know the specific identifier of a commit, so it's rather tricky for automatization.

Another way to achieving this is to rebase STAGING on top of HOTFIX periodically. By doing it, we will have all of our feature changes as well as fixes of bugs. And also, it is somewhat manual work, but this time it is easy for automatization.

For this automatization, we will use a simple-git library.

A lightweight interface for running git commands

Simple-git is a tool for running git commands in any Node.js application.
It gives us access to make all kinds of permutations on top of your commits and branches. With that library, we can easily create a script responsible for releasing our latest changes and running it from the command line.

All we need to do in order to start using simple-git is to include into our JavaScript app and create a git instance:

const simpleGit = require("simple-git");
const git = simpleGit.default();
Enter fullscreen mode Exit fullscreen mode

Then, we have access to any git command as well as for options supported by that command. You can later visit the public API of the library to see the full list of available methods.

For now, simply try to checkout on some test branch:

await git.checkout("test-branch");
const branch = await git.branch();

// logs "test-branch"
console.log(branch.current)
Enter fullscreen mode Exit fullscreen mode

It works, and it's plain and simple like standard git commands! 🙂

Note: Remember that from within your script, any git command is like a side-effect, and it is not synchronous.

Let's imagine having a script like one below, which executes all the commands needed for rebase one branch into another:

async function main() {
  try {
    const status = await git.status();

    if (!status.isClean()) {
      return;
    }

    await git.checkout("HOTFIX");
    await git.reset("hard", ["origin/HOTFIX"]);
    await git.pull();

    await git.checkout("STAGING");
    await git.reset("hard", ["origin/STAGING"]);
    await git.pull();

    await git.rebase(["HOTFIX"]);
    await git.push("origin", "STAGING", ["--force"]);
  } catch (error) {
    const status = await git.status();

    if (status.conflicted.length > 0) {
      return;
    }

    console.log(error);
  }
}
Enter fullscreen mode Exit fullscreen mode

Our script fetches the latest changes on every branch, then it rebases STAGING branch on top of HOTFIX. Before executing anything, we check for not committed files since a hard reset will discard any changes made in development. Unfortunately in case of an error or merge conflicts, we must continue manually.

So we have an automated way of rebasing branches to date with the latest HOTFIX environment. And with chalk, we can make it a beautiful command-line script:

Now with this script, which takes care of rebasing for us, the whole process of making your environments consistent is encapsulated in one single file, which can be executed from the command-line.

node update-branches.js

// or we can specify a command in package.json
yarn update:branches
npm run update:branches
Enter fullscreen mode Exit fullscreen mode

I guess it is even possible to hook up this script in the deployment pipeline, for example, with Github Actions or Husky. I will explore this topic in the future. 😃

I really recommend you to inspect this awesome library for yourselves!

Thanks for reading! If you are interested in the latest tech news, you can follow my account since I plan to post here regularly. I also tweet on a regular basis so that you can follow My Twitter account as well!

Discussion (1)

Collapse
kalashin1 profile image
Kinanee Samson

Work, thank you for this.