diff --git a/.travis.yml b/.travis.yml index 39e73cc6..e49d9836 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: cpp sudo: false +services: + - docker + env: global: - NODE_VERSION="6.1.0" @@ -18,68 +21,43 @@ os: - linux - osx -# C++11 support -# See https://github.com/PacificBiosciences/pbdagcon/pull/7 - -compiler: - - gcc - -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - upx-ucl - - gcc-4.8 - - gcc-4.8-multilib - - g++-4.8 - - g++-4.8-multilib - - linux-libc-dev:i386 - - libgtk2.0-0:i386 - - libxtst6:i386 - - libnss3:i386 - - libxss1:i386 - - libgconf-2-4:i386 - - libasound2:i386 - - clang - - dpkg - - fakeroot - - jq - before_install: - - rm -rf ~/.nvm - - git clone https://github.com/creationix/nvm.git ~/.nvm - - source ~/.nvm/nvm.sh - - nvm --version - - nvm install $NODE_VERSION - - node --version - - npm --version - - npm config set spin=false - - rvm install $RUBY_VERSION - - rvm use $RUBY_VERSION + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + rm -rf ~/.nvm; + git clone https://github.com/creationix/nvm.git ~/.nvm; + source ~/.nvm/nvm.sh; + nvm --version; + nvm install $NODE_VERSION; + node --version; + npm --version; + npm config set spin=false; + rvm install $RUBY_VERSION; + rvm use $RUBY_VERSION; + fi install: - - if [ "$CXX" = "g++" ] && [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - export CXX="g++-4.8" CC="gcc-4.8"; - fi - - gem install scss_lint - - npm install -g bower - - npm install -g electron-installer-debian - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + gem install scss_lint; + npm install -g bower electron-installer-debian; + npm install -g electron-installer-debian; brew install afsctool; brew install jq; fi - - make info - - make electron-develop - -before_script: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + make info; + make electron-develop; + fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then - export DISPLAY=:99.0; - sh -e /etc/init.d/xvfb start; + ./scripts/build/docker/run-command.sh -r ${TARGET_ARCH} -s ${PWD} -c "make info && make electron-develop"; fi script: - - npm test + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then + npm test; + fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then + ./scripts/build/docker/run-command.sh -r ${TARGET_ARCH} -s ${PWD} -c "xvfb-run --server-args=$XVFB_ARGS npm test"; + fi notifications: email: false diff --git a/scripts/build/docker/Dockerfile-i686 b/scripts/build/docker/Dockerfile-i686 new file mode 100644 index 00000000..f583678f --- /dev/null +++ b/scripts/build/docker/Dockerfile-i686 @@ -0,0 +1,35 @@ +FROM toopher/ubuntu-i386:14.04 + +# Install dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + fuse \ + git \ + jq \ + libasound2 \ + libgconf-2-4 \ + libgtk2.0-0 \ + libnss3 \ + libxss1 \ + libxtst6 \ + python \ + python-software-properties \ + software-properties-common \ + upx \ + unzip \ + wget \ + xvfb \ + zip + +# NodeJS +RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \ + && apt-get install -y nodejs +RUN npm config set spin=false +RUN npm install -g bower asar electron-installer-debian + +# Ruby +RUN add-apt-repository ppa:brightbox/ruby-ng +RUN apt-get update +RUN apt-get install -y ruby2.3 +RUN gem install scss_lint diff --git a/scripts/build/docker/Dockerfile-x86_64 b/scripts/build/docker/Dockerfile-x86_64 new file mode 100644 index 00000000..679dff9b --- /dev/null +++ b/scripts/build/docker/Dockerfile-x86_64 @@ -0,0 +1,35 @@ +FROM ubuntu:14.04 + +# Install dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + fuse \ + git \ + jq \ + libasound2 \ + libgconf-2-4 \ + libgtk2.0-0 \ + libnss3 \ + libxss1 \ + libxtst6 \ + python \ + python-software-properties \ + software-properties-common \ + upx \ + unzip \ + wget \ + xvfb \ + zip + +# NodeJS +RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \ + && apt-get install -y nodejs +RUN npm config set spin=false +RUN npm install -g bower asar electron-installer-debian + +# Ruby +RUN add-apt-repository ppa:brightbox/ruby-ng +RUN apt-get update +RUN apt-get install -y ruby2.3 +RUN gem install scss_lint diff --git a/scripts/build/docker/Dockerfile.template b/scripts/build/docker/Dockerfile.template new file mode 100644 index 00000000..49f3b84a --- /dev/null +++ b/scripts/build/docker/Dockerfile.template @@ -0,0 +1,35 @@ +FROM <%= image %> + +# Install dependencies +RUN apt-get update && apt-get install -y \ + build-essential \ + curl \ + fuse \ + git \ + jq \ + libasound2 \ + libgconf-2-4 \ + libgtk2.0-0 \ + libnss3 \ + libxss1 \ + libxtst6 \ + python \ + python-software-properties \ + software-properties-common \ + upx \ + unzip \ + wget \ + xvfb \ + zip + +# NodeJS +RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - \ + && apt-get install -y nodejs +RUN npm config set spin=false +RUN npm install -g bower asar electron-installer-debian + +# Ruby +RUN add-apt-repository ppa:brightbox/ruby-ng +RUN apt-get update +RUN apt-get install -y ruby2.3 +RUN gem install scss_lint diff --git a/scripts/build/docker/README.md b/scripts/build/docker/README.md new file mode 100644 index 00000000..c7dada70 --- /dev/null +++ b/scripts/build/docker/README.md @@ -0,0 +1,57 @@ +Compile Etcher in Docker +======================== + +This is directory provides the utilities necessary to be able to run GNU/Linux +Etcher (headlessly), compile it, and package it, inside Docker containers. + +This directory provides a set of Dockerfiles for each supported architecture +that are compiled from a base Dockerfile template. The Dockerfiles install +every needed dependency to be able to build and package Etcher for GNU/Linux +targets. + +Running a command inside the Docker images +------------------------------------------ + +We provide a utility script called `run-command.sh` which allows you to run a +command in an environment where you have all the dependencies needed to build +and package Etcher, and in where the Etcher source code is available in the +current working directory. + +For example: + +``` +./run-command.sh \ + -r x64 \ + -s path/to/etcher/repository \ + -c "make info" \ + -b "a/temporary/directory/for/docker/build" +``` + +The above command will build the corresponding Docker file (if needed), and +will run the command on it. + +Architecture dependent Dockerfile steps +--------------------------------------- + +You can declare certain steps to be run for certain architectures by using the +following logic: + +``` +<% if (architecture == 'i686') { %> + ... +<% } %> + +<% if (architecture == 'x86_64') { %> + ... +<% } %> +``` + +Compiling the Dockerfile.template +--------------------------------- + +If you modify the `Dockerfile.template` file, you will need to regenerate the +compiled Dockerfiles by running the `compile-template.js` utility script: + +```sh +node compile-template.js +``` diff --git a/scripts/build/docker/compile-template.js b/scripts/build/docker/compile-template.js new file mode 100644 index 00000000..1dbb4596 --- /dev/null +++ b/scripts/build/docker/compile-template.js @@ -0,0 +1,45 @@ +/* + * Copyright 2016 resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +// This script generates Dockerfiles based on a template containing all +// the necessary dependencies/ to run and build Etcher in multiple platforms. + +const _ = require('lodash'); +const fs = require('fs'); +const path = require('path'); +const currentDirectory = __dirname; + +const template = fs.readFileSync(path.join(currentDirectory, 'Dockerfile.template'), { + encoding: 'utf8' +}); + +_.each([ + { + architecture: 'i686', + image: 'toopher/ubuntu-i386:14.04' + }, + { + architecture: 'x86_64', + image: 'ubuntu:14.04' + } +], (options) => { + const result = _.template(template)(options); + const filename = path.join(currentDirectory, `Dockerfile-${options.architecture}`); + fs.writeFileSync(filename, result); +}); + diff --git a/scripts/build/docker/run-command.sh b/scripts/build/docker/run-command.sh new file mode 100755 index 00000000..b257e3e3 --- /dev/null +++ b/scripts/build/docker/run-command.sh @@ -0,0 +1,86 @@ +#!/bin/bash + +### +# Copyright 2016 resin.io +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +### + +set -u +set -e + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + +"$HERE/../check-dependency.sh" docker + +function usage() { + echo "Usage: $0" + echo "" + echo "Options" + echo "" + echo " -r " + echo " -s " + echo " -c " + exit 1 +} + +ARGV_ARCHITECTURE="" +ARGV_SOURCE_CODE_DIRECTORY="" +ARGV_COMMAND="" + +while getopts ":r:s:c:" option; do + case $option in + r) ARGV_ARCHITECTURE=$OPTARG ;; + s) ARGV_SOURCE_CODE_DIRECTORY=$OPTARG ;; + c) ARGV_COMMAND=$OPTARG ;; + *) usage ;; + esac +done + +if [ -z "$ARGV_ARCHITECTURE" ] \ + || [ -z "$ARGV_SOURCE_CODE_DIRECTORY" ] \ + || [ -z "$ARGV_COMMAND" ] +then + usage +fi + +if [ "$ARGV_ARCHITECTURE" == "x64" ]; then + DOCKERFILE="$HERE/Dockerfile-x86_64" +elif [ "$ARGV_ARCHITECTURE" == "x86" ]; then + DOCKERFILE="$HERE/Dockerfile-i686" +else + echo "Unsupported architecture: $ARGV_ARCHITECTURE" 1>&2 + exit 1 +fi + +IMAGE_ID="etcher-build-$ARGV_ARCHITECTURE" + +docker build -f "$DOCKERFILE" -t "$IMAGE_ID" "$ARGV_SOURCE_CODE_DIRECTORY" + +# Docker complaints with: ". includes invalid characters for a local +# volume name, only [a-zA-Z0-9][a-zA-Z0-9_.-] are allowed" otherwise +if [ "$ARGV_SOURCE_CODE_DIRECTORY" == "." ] || + [ "$ARGV_SOURCE_CODE_DIRECTORY" == "./" ] +then + ARGV_SOURCE_CODE_DIRECTORY="$PWD" +fi + +# The SYS_ADMIN capability and FUSE host device declarations +# are needed to be able to build an AppImage +# The `-t` and TERM setup is needed to display coloured output. +docker run -t \ + --env "TERM=xterm-256color" \ + --cap-add SYS_ADMIN \ + --device /dev/fuse:/dev/fuse:mrw \ + --volume "$ARGV_SOURCE_CODE_DIRECTORY:/etcher" \ + "$IMAGE_ID" /bin/bash -c "cd /etcher && $ARGV_COMMAND"