ContribKanban.com on Platform.sh

Published on Sunday 2, August 2015

I've been a fan of Platform.sh since it came out, even before I started at Commerce Guys. I'm a fan of using builder tools for constructing projects - Composer or Drush make (latter for Drupal) - instead of putting extra code into version control. However, this post is not about a PHP project, but one of my AngularJS projects.

Since I first uploaded it way back in January 2015 it has lived on a personal server. After all, it's just a JavaScript site with static resources and loading data from Parse.com. There was one issue I disliked, and that was deploying my changes. I really didn't want to install all of these build tools on my server. So with each commit I would rebuild and rsync my changes. Enter Platform.sh which automated by deployment and development work (while still using GitHub to keep the project open source.)

So, what is Platform.sh?

Platform.sh is a groundbreaking, award-winning hosting and development tool for web applications. It extends a branch-merge workflow to infrastructure so that every branch can be tested as if it were in production, and it scales up to the largest sites.

That last feature is why I love it. An environment for every branch and automatic deployment on commit. I get to think less about publishing changes and focus on doing more to improve my application.

It is best to note that Platform.sh is biased on supporting Drupal, but serves any PHP application. Right now Platform.sh only supports PHP environments with Node.js, Python, and Ruby coming soon. Luckily AngularJS applications are static files, so the underlying platform doesn't matter so long as it can serve HTML. Since I use Parse.com to handle my data I don't need to worry about Platform.sh not supporting MongoDB in its current services. I'm sure that's to come with full Node.js support so you can go MEAN and lean.

Configuring Platform.sh

Platform.sh uses a few configuration files stored in YAML format to control your project and environments. I'm not going to walk through these, just how to set them up properly for a static based project. If you are not familiar with Platform.sh and its configuration files, jump over to the Configuration Files documentation.

Web server settings

Most JavaScript applications have some sort of "source" folder and then a compiled "dist/prod" folder that their task tool of choice (Grunt/Gulp/etc) compiles. In my case, ContribKanban outputs production code into "dist". In order for Platform.sh to serve my app, I need to specify this as the document root for the web server.

web: document_root: "/dist"

Platform.sh, under the PHP environment, doesn't automatically serve static files nor treat them as an index file. You will need to add index.html as an index file along with some whitelist rules to ensure your template partials, any JSON, and other items can be properly loaded. The following snippet will allow Platform.sh to serve your static files. Why would I need to do this? The PHP default whitelist doesn't include HTML files (which is why you can skip this in typical setups.)

web: ... index_files: - "index.html" whitelist: - "\\.html?$" - "\\.css$" - "\\.js$" - "\\.json$"

If you're using a custom font or font icons (FontAwesome) be sure to add

- \.ttf$ - \.eot$ - \.woff$ - \.otf$

More about document_root, index_files and whitelist at the .platform.app.yaml documentation.

Project dependencies

Before jumping into hooks that run on build and deploy, you are going to need to know and define your project dependencies. This is straight forward and supported decently, as there are examples of Drupal projects running grunt and npm install inside of a theme. I needed Bower to download front end libraries, Grunt, and Sass for grunt-sass.

dependencies: ruby: sass: "3.4.7" nodejs: grunt-cli: "~0.1.13" bower: "~1.3.3"

I made bower a global dependency instead of a package one because it was just easier to have it global. Also, some people keep bower components in version control and can skip that.

Building your app on each commit

Now it's time to tell Platform.sh how to build our project before it beams it into our environment. I hit a few snags, but it might be because I'm not a front end developer and NPM gives me headaches on the regular. The NPM installed on the PHP environment is version 1.4.28; however, I did not notice issues when building my project (running 2.6.0 locally.)

This is as about as simple as it gets. In the build hook run the specified commands! If your package.json, Gruntfile.js, and bower.json are in your repository's root just call the proper install commands. Otherwise cd into the proper directory. Your initial position will be the repository's root.

hooks: build: | npm --version npm install bower install grunt build

There you go! Now every commit will automatically build your application when it is deployed. Any branch created will make a new environment for testing that builds itself. Code more, manage deployment less.

There is one gotcha: you can't use imagemin! I used a Yeoman generator which bundled the package and just left it. However trying to use it on Platform.sh will result in

⚠ pre-build test failed, compiling from source... ✖ pngquant failed to build, make sure that libpng-dev is installed { [Error: Command failed: make: *** No rule to make target `config.mk', needed by `lib/libimagequant.a'. Stop. ] killed: false, code: 2, signal: null }

Result!

Here's what the ContribKanban .platform.app.yaml looks like (source.) Again, note, the tool stack is php:symfony because it is a misnomer for anything non-Drupal.

name: frontend toolstack: "php:symfony" web: document_root: "/dist" index_files: - "index.html" whitelist: - "\\.html?$" - "\\.css$" - "\\.js$" - "\\.json$" - \.ttf$ - \.eot$ - \.woff$ - \.otf$ disk: 2048 hooks: build: | npm --version npm install bower install grunt build deploy: dependencies: ruby: sass: "3.4.7" nodejs: grunt-cli: "~0.1.13" bower: "~1.3.3"

Running tests

I don't have any tests for ContribKanban, even though support is stubbed in. It's on my backlog of things to learn, so I'm not sure what'd happen if you ran tests. I can say that if tests fail it will cancel the build and prevent it from going out! Same with other build errors.