Monday, September 8, 2014

Jenkins for Testing Dart and JavaScript Polymer

It is entirely possible that I am too cheap. It is also possible that there is nothing out there that does exactly what I need it to do. So tonight, I set out to see how easy it is to roll my own.

What I need is a continuous integration server for my books. I need a solution for all of my books, but if I can find something for Patterns in Polymer which is written in both Dart and JavaScript, then I will likely have everything that I need.

Some of the key features that I need:

  • Needs to update Dart when new releases are available
  • Needs to update specific libraries (e.g. Polymer.dart and Polymer) when new releases are available
  • Needs to run tests when code is updated or new code is added
  • Needs to run dart analyzer (ignoring code intentionally broken for demonstration purposes)

I do not necessarily need to be told immediately if the code in my books has broken. I like to write as much as possible then go back and fix words and code as needed. I will typically run the tests specific to the current chapter locally, so it is not imperative that I get quick feedback (daily will be fine).

I happen to have been messing around with Jenkins a bit recently. I also happen to have a Linode that is not doing too much. Perhaps these two can be a match made in JavaScript & Dart heaven?

I have Debian 6 installed on my Linode, which is old, but still in LTS. Hopefully that will be sufficient. I start by following the instructions for adding Jenkins packages to a Debian system. This boils down to: add the alternate package server's key to my Linode, add the package source to the list of sources, update, and sudo apt-get install jenkins.

I do not care for the server being publicly available:
$ sudo netstat -nlp  | grep 8080
tcp6       0      0 :::8080                 :::*                    LISTEN      29489/java
I am very happy with it binding to localhost and then using SSH port forward to access it as needed. Never expose services that you do not need, after all.

The /etc/default/jenkins file configures Jenkins on Debian. It does not include the listen address by default, just the port:
# port for HTTP connector (default 8080; disable with -1)

JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT"
So I update the file to include that information:
# address to which to bind the HTTP connector

# port for HTTP connector (default 8080; disable with -1)

JENKINS_ARGS="--webroot=/var/cache/jenkins/war --httpListenAddress=$HTTP_HOST --httpPort=$HTTP_PORT --ajp13Port=$AJP_PORT"
After a sudo /etc/init.d/jenkins restart I am happier:
$ sudo netstat -nlp  | grep 8080
tcp6       0      0          :::*                    LISTEN      29709/java
I disconnect my SSH session, and reconect, port forwarding 8080 from my local machine to 8080 on localhost of my Linode:
$ ssh -L 8080:localhost:8080 linode
With that, I have a Jenkins server that only I can access:

I start by removing plugins that I am never going to need (mostly the myriad Java ones) from Manage Jenkins → Manage Plugins → Installed:

Then I install the GitHub plugin from the Available tab so that I can grab my private repositories:

Configuring SSH Hosts for GitHub

Once that is complete, I create an ssh key for Jenkins to use:
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/var/lib/jenkins/.ssh/id_rsa): /var/lib/jenkins/.ssh/patterns_in_polymer_id_rsa
Your identification has been saved in /var/lib/jenkins/.ssh/patterns_in_polymer_id_rsa.
Your public key has been saved in /var/lib/jenkins/.ssh/

Next, I create an ssh alias that will use this ssh key:
$ pwd
$ cat .ssh/config 
Host patterns_in_polymer_github
  IdentityFile /var/lib/jenkins/.ssh/patterns_in_polymer_id_rsa
  PreferredAuthentications publickey
The benefit of this is that I can create as many keys as I like here without getting key-already-in-use messages from Github when I try to add another project to my Linode. I add the deploy key to my private book repo:

With that, I can access the repository using that SSH alias:
$ git ls-remote -h git@patterns_in_polymer_github:eee-c/polymer-patterns HEAD
The authenticity of host ' (' can't be established.
RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ',' (RSA) to the list of known hosts.
It is important to run that step from the command-line otherwise Jenkins, unable to prompt for a yes/no answer, will fail to connect.

I am now ready to create the Jenkins project:

To that project, I add the SSH-aliased Github URL:

I configure the project to run daily at 0430:

And last, but not least, I define the tests to run:

And that works. Well, it checks out the code and executes the test script. I still need a bit more setup on my Linode (Xvfb-run, a recent Node.js, Dart, Chrome, etc). But hopefully the hard part is out of the way. I will find out just how hard the remaining configuration is tomorrow.

Day #177

No comments:

Post a Comment