Chrome Extensions and Continuous Integration

David Domonkos
Slido developers blog
3 min readOct 2, 2019
“Dear QA, please find the newest version attached.” Photo by Matthew Henry from Burst

Let’s set the scene. You are in charge of developing a Chrome extension for your company. You have a colleague (let’s call her a QA expert) who is responsible for testing the extension before it goes live.

In the beginning you would always build the extension on your machine, zip it and send it to her when you finished some unit of work. In time this gets annoying for both you and her. Time to automate.

Does this sound familiar in any way? Read on. :)

The standard approach

There’s this excellent blog post about how to do continuous integration of Chrome extensions written by the guys at CircleCI.

So why bother with another blog post? I had a constraint which prevented me from using that solution. Thing is, if you use the said solution you end up giving the CI process full rights to publish any Chrome extension in the name of the Google account that you use.

I see two problems if I use my own account:

  • I have the right to publish to both staging and production. I do not want a staging CI process to have the rights to publish to production.
  • What if my account is deleted for some reason? The dependency of CI on my account’s existence and access rights is absolutely hidden here.

Okay, there’s an easy fix — create a new Google account that will be dedicated only to this purpose and will only have the rights which it needs. But each account costs something. Is there perhaps another way?

The alternative

You don’t need the Chrome Web Store to distribute extensions. You just pack the extension, send it to the other person (our QA expert) and they drag’n’drop it into Chrome.

The problematic part is, naturally, updating. Luckily for us, there’s a property update_url in the extension’s manifest.json which we can use. In the URL you specify where Chrome expects an XML file with some info about the newest version of the extension. The file looks like this (let’s call it update2.xml):

There are three things in this file:

  • appid — ID of your extension. You can see it when you install it in Chrome. It will stay static.
  • codebase — The location of the newest CRX file.
  • version — The version of the extension in that location.

The CI configuration

Here are the things your CI needs to do:

  1. Generate a new version number so that Chrome knows it needs to update. For the staging environment, I use the 4th version number and bump it by one on each deployment. E.g. 1.0.0.0 , 1.0.0.1 , 1.0.0.2 and so on. I always have a script download the current update2.xml , check the current version and bump it.
  2. Set the correct version in the manifest.xml and pack your code into a CRX file. You can use this amazing crx utility and the command crx pack . For this, you’ll need to generate an RSA private key first. You can use this snippet: openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem . Put the key in some secured environment variable of your CI service.
  3. Upload a new update2.xml (where you updated the version number) and the generated CRX file onto the locations you specified (in manifest.xml and update2.xml respectively).

And that’s all there is to it.

When all these steps are complete, Chrome should automatically update the extension. If you don’t want to wait for Chrome to realize there’s a new version out, you can open the details of the extension in the browser and click the “Update” button.

Was this article helpful? Or did you find it a bit too brief and would like me to go into more detail? Let me know in the comments.

--

--