The story of clever-tools 1.0.0
We have some news about our dear clever-tools, the Clever Cloud CLI for humans, robots and others.
Back in January, we released version 0.10.1 which contained some new commands and a few bug fixes. Today we're releasing version 1.0.0!
You can find all the details about the user oriented changes in the CHANGELOG. In this article, we'll cover the structural changes related to the project:
- Improved error handling = better usage in CI/CD pipelines
- ES2015 refactor + ESLint = better contributing experience
- Goodbye nodegit, hello isomorphic-git!
- Improved Jenkins build = more release methods and beta channel (npm, deb, rpm, arch, homebrew and chocolatey)
Now let me tell you the story of this release…
Improved error handling = better usage in CI/CD pipelines
It all started with issue 195. With the previous version, when a user tried to
clever deploy a non existing branch, the error message was a bit too raw. Our colleague Philippe wanted emojis, but we had to decline 😭.
While investigating this error message and how to improve it, we realized that the command was not returning a proper error exit status. This is a very important rule to follow when you're writing a terminal command/script:
- If everything went well: return exit status
- If something went wrong: return exit status
1(or another one more specific)
Our CLI is built for humans AND robots. We want to empower our terminal addicted users. Moreover, we want to empower our users to automate anything related to Clever Cloud in their CI/CD pipeline. In such cases, returning a proper error exit status is crucial to mark a CI/CD job as successful or failed.
We took a quick look at the rest of the codebase and noticed that other commands were concerned by this problem. We reworked the code of
clever deploy and decided to apply the same error handling to all the other commands:
- For humans: Always have an
[ERROR]prefix (colored in red) when we display an error message.
- For robots: Always log error messages to
- For robots: Always return
1as exit status when something goes wrong.
This obviously required some significant work. We had to go through all the 28 commands. Nevertheless, we're sure this will help you to build more robust and automated jobs, interacting with the Clever Cloud platform.
ES2015 refactor + ESLint = better contributing experience
While we went through the codebase, we took the opportunity to do a bit of refactoring.
This big refactoring took some time but it allowed us to reduce the number of lines of code while improving the overall consistency and readability. We hope this will drive more users to customize the clever-tools and propose pull-requests for bug fixes and feature requests.
Looking at how easily the new
clever console was added by an outside contributor, it seems like we're on the right path.
During this refactoring, we updated most of our dependencies but one of them required special attention: NodeGit.
NodeGit is a node.js module which provides bindings over libgit2, a portable and pure C implementation of the git core methods. This is commonly referred to as a "native module" in the node.js ecosystem. Each time you install NodeGit, npm will try to build libgit2 from source (in some situations, it will try to download pre-builds). Because we want our users to have a straightforward installation experience, this native module thing had many drawbacks:
- In our Travis CI config, we had to install some native dependencies so npm could build libgit2 from source.
- Some of our users tried to install the clever-tools via npm and had difficulties because of this.
- Our users don't all use the same version of node.js, this also multiplied the number of weird cases we had to support.
- Each time we wanted to update NodeGit, it was a puzzle to resolve.
All those problems pushed us to stop releasing the clever-tools via npm. ⚠️ SPOILER ALERT: it's back for version 1.0.0.
The second problem is that we use pkg. This tool is great. It lets you compile a node.js project to different portable binaries for MacOS, Windows and GNU/Linux. We've been using it for a while to provide various installation methods. When we dropped installation via npm for 0.10.1, the binaries built with pkg where the only official way to use the clever-tools.
This mix of NodeGit + pkg complicated the situation even more:
- The binaries built with pkg did not include native dependencies. We had to distribute the right
nodegit.nodefile along with our main binary file and users had to have it in their
- On some GNU/Linux distributions, we had problems with native dependencies like
We already looked for a replacement solution but a fairly new one came up to our attention in February…
As I said, we heard about it in February but we only tried to use it for our use-case in July. It does not support all the git feature set (yet) but it has strong foundations and we only need a few things for the clever-tools:
- list and resolve branches
- list and resolve commits
- add/rm remotes
- push to repos (via HTTPS)
We were missing a few features so we reached out to William to see if we could help and/or contribute. In the end, we contributed a few features in the codebase and we sponsored the hosting of the CORS-proxy which is used to demo the project in browsers.
By replacing NodeGit with isomorphic-git, we can say goodbye to most of the problems we described earlier:
- no need to worry about different node.js versions
- no need to have native dependencies on our CI server to build/test the project
- no need to distribute
nodegit.nodewith the pkg binary
- no need for a user to have the right native dependencies on his/her system to use it
- npm releases are back
Improved Jenkins build = more release methods and beta channel
Because we decided to ditch NodeGit, we were able to simplify the packaging (no more
nodegit.node and no native dependencies). This required some rework on our Jenkins builds but it was a good occasion to migrate 5 different jobs to one multibranch pipeline project.
We'll discuss the details of this new build system and how we set it up in another article. For now though, here's what changed:
- All platforms:
- Added: installation via npm is back
- Changed: dedicated homebrew tap for beta versions
- Changed: chocolatey packages are now automatically published (no more manual upload, no more manual review from chocolatey's team)
- Changed: chocolatey packages are no longer published on chocolatey.org
- Changed: chocolatey packages are published (beta & stable) on Bintray but you can still use the
chocoCLI to install them (see chocolatey installation docs for the specifics).
The structural changes of this release will help us to be more reactive on the project. We'll be able to publish new features and bug fixes more easily and more often. Hopefully, this will improve the quality of the clever-tools and push more customers who only use the Web console to try the CLI way of life.
We're looking forward to read your feedbacks on this release through are usual channels: support chat, email, Twitter, GitHub issues…