Recently I decided to write a very simple Chrome Extension in order to learn about browser extension development. Writing the extension was very interesting but in this blog I'm going to be focusing on the continuous integration setup I built via GitHub, Visual Studio Team Services and the Chrome Web Store Publish API.
When submitting an extension to the Chrome Web Store you have the option of going through the developer portal to upload a zip of your extension. This is a tedious process and as a developer I'm always looking to automate a process such as this. Thankfully Google provides the Chrome Web Store Publish API. This API gives developers an endpoint, which allows for submission of their zips programmatically. The API endpoint is perfect for continuous integration and I decided to see if I could utilize Visual Studio Team Services (VSTS) for that very purpose. I'm going to walk though the steps I took to place my code in source control, connect it to the automated build service which VSTS provides, automate the export of the extension code to a zip, and then submit that zip to the Chrome Web Store Publish API.
First was getting my code into source control (GitHub) via git, which I'm going to assume most people are familiar with. If you are unfamiliar with git then you can find helpful resources at this link.
Even though VSTS provides its own git repository I thought it might be helpful to others to make my code publicly available since the purpose of this project was to learn.
Connecting GitHub to Visual Studio Team Services
Next was setting up the Visual Studio Team Services (VSTS) project and hooking it up to GitHub. First, I needed to create a VSTS project and a connection to the GitHub repository. Once I had my project setup in VSTS I went to Manage Project and then clicked the Services tab. On the Services tab screen I clicked "New Service Endpoint" and then selected GitHub. From here I had to enter a personal access token I created in GitHub to allow VSTS to access my GitHub repo. Microsoft provides notes on the service endpoint here. Once the connection is established I should now be able to use it when specifying the build repository.
The next steps involved setting up the build. First, I went to the build tab under my VSTS project and clicked on the plus sign to add a new build configuration. I selected the empty template to start with and then clicked on the repository tab. Here is where I selected repository type as "GitHub" and then selected the connection I created in the previous steps as well as the repo I was connecting to.
Triggering the Build
Next, under the triggers tab I checked the box for "Continuous Integration" and specified the branches I wanted to trigger the build. Note that VSTS does allow for wild card branch builds by using an asterisk in the branch name.
Under the General tab I made sure to specify an acceptable build time out. At this point the build will trigger when code is pushed to the branches specified.
Chrome Web Store Publish API and OAuth
I had the build triggering properly but next I needed to setup the build to zip up the code and then publish via the Chrome Web Store Publish API. Zipping the code up is easy but publishing to the API is a little more complex. The complexity lies in the fact that the Chrome Web Store Publish API uses OAuth tokens to authorize the user's request. Acquiring the token is a bit of an arduous process, the steps of which are outlined on this page from Google. In the link, Google explains how to go about obtaining an access token for the API. The problem is that the access token is only valid for about an hour. Fortunately, when you get this access token there is another token called the refresh token which you can use, along with the client id and client secret, to retrieve additional access tokens.
Once I setup access to the API via my Google account and obtained the refresh token, client id and client secret I was then able to request additional access tokens via the Google OAuth API endpoint. With this ability I could then setup a way to request a new access token each build and pass that token in the request to Chrome Web Store Publish API.
Compress and Publish with PowerShell
I decided to build the zip and publish to the API via a PowerShell script I included in the project. The PowerShell script first zips up the source code of the chrome extension. It then attempts to request a new access token via a Google OAuth 2.0 endpoint using the refresh token, client id and client secret. After successfully retrieving the new access token, the PowerShell script then uses that token in the header of the next two requests. The first request uploads the new zip file to the Chrome Web Store Publish API. This puts the new version of the extension in the Chrome Web Store in a draft state, which requires another call to actually publish the new version. The PowerShell script then calls the publish endpoint which publishes the new version of the extension out to the live web store.To make use of the PowerShell script in the build I simply added a build step on the Build tab and selected the PowerShell template. In the PowerShell build step I then specified the type as "File Path" and then selected the script via the file browser. The file browser allows you to choose a PowerShell script that is in the source control repository configured for the particular build.
It's important to note in the PowerShell code I use several environment variables, which are specified in the build configuration. These environment variables have a two-fold benefit. First, I don't have to put any of my secret API values in source control, which would compromise my account because the repository is public. Second, I can change these values at any time without updating the script in source control.
With all of these pieces in place I am now able to build and deploy the Chrome Extension to the Chrome Web Store by simply pushing new code to the GitHub repository.
As you can see, Visual Studio Team Services offers many features that enable you to easily build continuous integration for almost any application or environment. I have only touched on a few of the basic features in this article but hopefully shown you that even non-Microsoft related applications can make use of the robust services offered by VSTS. Finally, the extension is currently available on the Chrome Web Store and the source code is available via GitHub if you're interested in it.
About the Author
Casey Silver is a Software Engineer in CapTech's Application Development Practice Area, where he specializes in developing .Net and cloud based applications.