Dart + CI with a few lines of code

Dart not only runs in the browser, but also on the server. Just like JavaScript, since the invention of node.js. 

Here are two simple answers for two practical questions:

1. What's keeping my Dart process alive?
2. How can I set up continuous integration?

Keep Yourself Alive - Keep Yourself Aliii-hiive ...

Let's say you wrote a social networking web site in Dart, like this:

 

import 'dart:io';
import 'dart:math';
void main() {
  HttpServer.bind(InternetAddress.ANY_IP_V4, 80)
    .then((HttpServer server) {
      server.listen((HttpRequest request) {
        var n = (new Random()).nextInt(1000);
        request.response.statusCode = 200;
        request.response.write(
           "<html><body><h2>Welcome to THE-BEST-SOCIAL-SITE 2.0!</h2>
            You have $n friends.</body></html>");
        request.response.close();
});});}

Done! Now let's quickly copy the file to your server and spawn a new Dart process:

$ dart social.dart

Your site is live and millions of users have started flocking towards it... until your hosting provider decides to reboot your server and you'll have to restart the process manually. Or, until an uncaught exception kills your Dart process.

Simple fix: let upstart manage your Dart process. First, install it - for example, in Ubuntu:

$ sudo apt-get install upstart

Now, create a new config file in /etc/init. For example, social.conf:

exec /usr/bin/dart social.dart >> /var/log/social/$(date -d "today" +"%Y_%m_%d_%H_%M_%S").log
start on filesystem and static-network-up
stop on runlevel [016]
respawn

You're ready to go! As a test, reboot the server and check if your web site is up and running afterwards. Now that was easy!

Continuous integration - or not integration at all ... ship-rooom-meetings - leave the hall!

Continuous integration (CI) is awesome. No need for painful integrations and deployments, just get your code out there. In fact, if your project is at an early stage, you might wanna just ship to your production server on every check-in. Well, maybe to a staging environment first, and then run a bunch of automated tests before going to prod. But let's keep simple for now.

There are a few CI sites and tools out there supporting Dart natively, such as drone.io. The way they typically work is: check-in triggers a build, which also runs a bunch of tests, and a successful build triggers a deployment.

To get you started, here's a simple CI setup for your Dart server which won't require any of these tools yet - focus on your product and deal with making that technology decision later.

First, create a build&deployment script. Just a simple shell script will do the job for now, something like:

#!/bin/bash
rm -rf social
git clone git://github.com/MyUserName/social.git
stop social
rm -rf /opt/social/*
cp -r social/* /opt/social/
cd /opt/social/
pub get
start social

Second, set up a web hook endpoint on your production server, listening on some obscure port and triggering the deployment script on every POST. Of course, the web hook endpoint is also written in Dart:

 

import 'dart:io';
import 'dart:convert';
void main() {
   HttpServer.bind(InternetAddress.ANY_IP_V4, 8977)
     .then((HttpServer server) {
       server.listen((HttpRequest request) {
         if (request.method=="POST") {
           print('Webhook triggered at ' + new DateTime.now().toString());
           request.response.statusCode = 200;
           Process.start('deploy.sh', []).then((process) {
             process.stdout.transform(new Utf8Decoder())
                        .transform(new LineSplitter())
                        .listen((String line) => request.response.writeln(line));
             process.exitCode.then((exitCode) {
               request.response.writeln('Exit code = $exitCode');
               request.response.close();
             });
           });
         }
 });});}

Latest version of webhook.dart is here.

Lastly - add the web hook to your repository and make sure it gets triggered on every check-in. For example, in GitHub:

webhook

Nothing fancy - no security, no notifications, no build dependencies etc, but took only a few minutes to set up. Now write some server-side Dart code and push it out!

See also dart-upstart on GitHub, and feel free to discuss on HN.

Written on April 12, 2014. Please subscribe to my blog.