From 7d85d78774eaf6a5d41c1cd98a4be4ce7497c054 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Sun, 19 Jan 2014 20:45:53 +0100 Subject: [PATCH] Adding ruby to travis strategy --- docs/strategies/TravisCiStrategy.md | 6 +- resources/travisci/Dockerfile | 27 +++++- resources/travisci/php/5.3/Dockerfile | 1 + resources/travisci/php/5.4/Dockerfile | 1 + resources/travisci/php/5.5/Dockerfile | 1 + resources/travisci/php/Dockerfile.post | 4 +- resources/travisci/ruby/1.9.2/Dockerfile | 1 + resources/travisci/ruby/1.9.3/Dockerfile | 1 + resources/travisci/ruby/2.0.0/Dockerfile | 1 + resources/travisci/ruby/2.1.0/Dockerfile | 1 + resources/travisci/ruby/Dockerfile.post | 3 + resources/travisci/ruby/Dockerfile.pre | 5 + src/Joli/JoliCi/Build.php | 15 +++ .../BuildStrategy/BuildStrategyInterface.php | 2 + .../BuildStrategy/TravisCiBuildStrategy.php | 96 +++++++++++++++---- src/Joli/JoliCi/Command/RunCommand.php | 4 +- 16 files changed, 147 insertions(+), 22 deletions(-) create mode 100644 resources/travisci/ruby/1.9.2/Dockerfile create mode 100644 resources/travisci/ruby/1.9.3/Dockerfile create mode 100644 resources/travisci/ruby/2.0.0/Dockerfile create mode 100644 resources/travisci/ruby/2.1.0/Dockerfile create mode 100644 resources/travisci/ruby/Dockerfile.post create mode 100644 resources/travisci/ruby/Dockerfile.pre diff --git a/docs/strategies/TravisCiStrategy.md b/docs/strategies/TravisCiStrategy.md index 88ef081..7bc5b69 100644 --- a/docs/strategies/TravisCiStrategy.md +++ b/docs/strategies/TravisCiStrategy.md @@ -10,4 +10,8 @@ For the moment only the following language / version list is supported, goal is * 5.3 * 5.4 * 5.5 - \ No newline at end of file +* ruby + * 1.9.2 + * 1.9.3 + * 2.0.0 + * 2.1.0 \ No newline at end of file diff --git a/resources/travisci/Dockerfile b/resources/travisci/Dockerfile index 3bea318..ef682e3 100644 --- a/resources/travisci/Dockerfile +++ b/resources/travisci/Dockerfile @@ -1,6 +1,30 @@ FROM ubuntu MAINTAINER Joel Wurtz +# Default ENV for TravisCi +ENV CI true +ENV TRAVIS false +ENV DEBIAN_FRONTEND noninteractive +ENV USER root +ENV HOME /root +ENV LANG C.UTF-8 +ENV LC_ALL C.UTF-8 +ENV RAILS_ENV test +ENV RACK_ENV test +ENV MERB_ENV test +ENV JRUBY_OPTS "--server -Dcext.enabled=false -Xcompile.invokedynamic=false" +ENV TRAVIS_BRANCH local +ENV TRAVIS_BUILD_DIR $HOME/project +ENV TRAVIS_BUILD_ID 0 +ENV TRAVIS_BUILD_NUMBER 0 +ENV TRAVIS_COMMIT "" +ENV TRAVIS_COMMIT_RANGE "" +ENV TRAVIS_JOB_ID 0 +ENV TRAVIS_JOB_NUMBER 0 +ENV TRAVIS_PULL_REQUEST false +ENV TRAVIS_SECURE_ENV_VARS false +ENV TRAVIS_REPO_SLUG "" + # Add apt repository needed RUN echo 'deb http://archive.ubuntu.com/ubuntu precise main universe' > /etc/apt/sources.list RUN echo 'deb http://archive.ubuntu.com/ubuntu precise-security main universe' >> /etc/apt/sources.list @@ -9,4 +33,5 @@ RUN echo 'deb http://archive.ubuntu.com/ubuntu precise-backports main restricted RUN apt-get update && apt-get install -y python-software-properties && add-apt-repository ppa:pdoes/ppa && apt-get update # Common for all -RUN apt-get install -y subversion mercurial build-essential openssl rsync git sudo curl wget golang-go \ No newline at end of file +RUN apt-get install -y git sudo curl wget +RUN mkdir -p $HOME \ No newline at end of file diff --git a/resources/travisci/php/5.3/Dockerfile b/resources/travisci/php/5.3/Dockerfile index e69de29..59482d0 100644 --- a/resources/travisci/php/5.3/Dockerfile +++ b/resources/travisci/php/5.3/Dockerfile @@ -0,0 +1 @@ +ENV TRAVIS_PHP_VERSION "5.3" \ No newline at end of file diff --git a/resources/travisci/php/5.4/Dockerfile b/resources/travisci/php/5.4/Dockerfile index ba24543..0640953 100644 --- a/resources/travisci/php/5.4/Dockerfile +++ b/resources/travisci/php/5.4/Dockerfile @@ -1 +1,2 @@ +ENV TRAVIS_PHP_VERSION "5.4" RUN add-apt-repository ppa:ondrej/php5-oldstable && apt-get update \ No newline at end of file diff --git a/resources/travisci/php/5.5/Dockerfile b/resources/travisci/php/5.5/Dockerfile index 5de66ed..5bcad22 100644 --- a/resources/travisci/php/5.5/Dockerfile +++ b/resources/travisci/php/5.5/Dockerfile @@ -1 +1,2 @@ +ENV TRAVIS_PHP_VERSION "5.5" RUN add-apt-repository ppa:ondrej/php5 && apt-get update \ No newline at end of file diff --git a/resources/travisci/php/Dockerfile.post b/resources/travisci/php/Dockerfile.post index ae64c7f..dbedf6b 100644 --- a/resources/travisci/php/Dockerfile.post +++ b/resources/travisci/php/Dockerfile.post @@ -9,5 +9,5 @@ RUN ln -s /etc/php5 ~/.phpenv/versions/php/etc RUN ls -l ~/.phpenv/versions/php/etc/conf.d # Add project at the end -ADD . /project -WORKDIR /project \ No newline at end of file +ADD . /home/project +WORKDIR /home/project \ No newline at end of file diff --git a/resources/travisci/ruby/1.9.2/Dockerfile b/resources/travisci/ruby/1.9.2/Dockerfile new file mode 100644 index 0000000..224e5e6 --- /dev/null +++ b/resources/travisci/ruby/1.9.2/Dockerfile @@ -0,0 +1 @@ +RUN rvm install 1.9.2 && rvm alias create default 1.9.2 \ No newline at end of file diff --git a/resources/travisci/ruby/1.9.3/Dockerfile b/resources/travisci/ruby/1.9.3/Dockerfile new file mode 100644 index 0000000..0214710 --- /dev/null +++ b/resources/travisci/ruby/1.9.3/Dockerfile @@ -0,0 +1 @@ +RUN rvm install 1.9.3 && rvm alias create default 1.9.3 \ No newline at end of file diff --git a/resources/travisci/ruby/2.0.0/Dockerfile b/resources/travisci/ruby/2.0.0/Dockerfile new file mode 100644 index 0000000..ff46af6 --- /dev/null +++ b/resources/travisci/ruby/2.0.0/Dockerfile @@ -0,0 +1 @@ +RUN rvm install 2.0.0 && rvm alias create default 2.0.0 \ No newline at end of file diff --git a/resources/travisci/ruby/2.1.0/Dockerfile b/resources/travisci/ruby/2.1.0/Dockerfile new file mode 100644 index 0000000..4f70422 --- /dev/null +++ b/resources/travisci/ruby/2.1.0/Dockerfile @@ -0,0 +1 @@ +RUN rvm install 2.1.0 && rvm alias create default 2.1.0 \ No newline at end of file diff --git a/resources/travisci/ruby/Dockerfile.post b/resources/travisci/ruby/Dockerfile.post new file mode 100644 index 0000000..59556aa --- /dev/null +++ b/resources/travisci/ruby/Dockerfile.post @@ -0,0 +1,3 @@ +# Add project at the end +ADD . /home/project +WORKDIR /home/project \ No newline at end of file diff --git a/resources/travisci/ruby/Dockerfile.pre b/resources/travisci/ruby/Dockerfile.pre new file mode 100644 index 0000000..8f0e67d --- /dev/null +++ b/resources/travisci/ruby/Dockerfile.pre @@ -0,0 +1,5 @@ +RUN apt-get -y install expect-dev gawk libyaml-dev libsqlite3-dev sqlite3 autoconf libgdbm-dev libncurses5-dev automake libtool bison pkg-config libffi-dev +RUN curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer -o /tmp/rvm-installer +RUN bash /tmp/rvm-installer latest-1.25 && rm /tmp/rvm-installer + +ENV PATH /usr/local/rvm/bin/:$PATH \ No newline at end of file diff --git a/src/Joli/JoliCi/Build.php b/src/Joli/JoliCi/Build.php index af2526a..acc8aa8 100644 --- a/src/Joli/JoliCi/Build.php +++ b/src/Joli/JoliCi/Build.php @@ -37,16 +37,31 @@ public function __construct($name, $directory) $this->dockername = sprintf("%s-%s", uniqid(), $name); } + /** + * Get name of this build + * + * @return string + */ public function getName() { return $this->name; } + /** + * Return directory of build + * + * @return string + */ public function getDirectory() { return $this->directory; } + /** + * Return the docker name use for image name + * + * @return string + */ public function getDockerName() { return $this->dockername; diff --git a/src/Joli/JoliCi/BuildStrategy/BuildStrategyInterface.php b/src/Joli/JoliCi/BuildStrategy/BuildStrategyInterface.php index 665b263..97bd293 100644 --- a/src/Joli/JoliCi/BuildStrategy/BuildStrategyInterface.php +++ b/src/Joli/JoliCi/BuildStrategy/BuildStrategyInterface.php @@ -17,6 +17,8 @@ */ interface BuildStrategyInterface { + const WORKDIR = "/home/project"; + /** * Create builds for a project * diff --git a/src/Joli/JoliCi/BuildStrategy/TravisCiBuildStrategy.php b/src/Joli/JoliCi/BuildStrategy/TravisCiBuildStrategy.php index 22a6e62..f60bcd7 100644 --- a/src/Joli/JoliCi/BuildStrategy/TravisCiBuildStrategy.php +++ b/src/Joli/JoliCi/BuildStrategy/TravisCiBuildStrategy.php @@ -24,7 +24,24 @@ class TravisCiBuildStrategy implements BuildStrategyInterface { private $defaultTestCommand = array( - 'php' => 'phpunit' + 'php' => 'phpunit', + 'node_js' => 'npm test', + 'ruby' => 'bundle install && bundle exec rake' + ); + + private $languageVersionKeyMapping = array( + 'php' => 'php', + 'ruby' => 'rvm' + ); + + private $encapsulation = array( + 'php' => '%s', + 'ruby' => '/bin/bash -l -c "rvm use default && %s"' + ); + + private $installMapping = array( + 'php' => '', + 'ruby' => 'bundle install' ); /** @@ -61,25 +78,30 @@ public function createBuilds($directory) $config = Yaml::parse($directory.DIRECTORY_SEPARATOR.".travis.yml"); $language = $config['language']; - $additionalRunContent = $this->parseBeforeScript($config); + $versionKey = isset($this->languageVersionKeyMapping[$language]) ? $this->languageVersionKeyMapping[$language] : $language; + $beforeScriptContent = $this->parseBeforeScript($config); $cmdContent = $this->parseScript($config); $buildRoot = $this->buildPath.DIRECTORY_SEPARATOR.uniqid(); $commonContent = file_get_contents($this->resourcesPath."/Dockerfile"); + $installContent = $this->parseInstall($config); + $beforeInstallContent = $this->parseBeforeInstall($config); - if (isset($config[$language]) && file_exists($this->resourcesPath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR."Dockerfile.pre")) { + if (isset($config[$versionKey]) && file_exists($this->resourcesPath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR."Dockerfile.pre")) { $languageContentPre = file_get_contents($this->resourcesPath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR."Dockerfile.pre"); $languageContentPost = file_get_contents($this->resourcesPath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR."Dockerfile.post"); - foreach ($config[$language] as $version) { + foreach ($config[$versionKey] as $version) { if (file_exists($this->resourcesPath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$version.DIRECTORY_SEPARATOR."Dockerfile")) { $versionContent = file_get_contents($this->resourcesPath.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.$version.DIRECTORY_SEPARATOR."Dockerfile"); - $dockerFileContent = sprintf("%s\n%s\n%s\n%s\n%s\n%s", + $dockerFileContent = sprintf("%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s", $commonContent, $languageContentPre, $versionContent, $languageContentPost, - $additionalRunContent, + $beforeInstallContent, + $installContent, + $beforeScriptContent, $cmdContent ); @@ -130,13 +152,10 @@ private function parseBeforeScript($config) } if (is_array($config['before_script'])) { - $config['before_script'] = array_map(function ($value) { - return sprintf("(%s || echo -n '')", $value); - }, $config['before_script']); - return sprintf("RUN cd /project && %s", implode(" && ", $config['before_script'])); - } else { - return sprintf("RUN cd /project && (%s || exit 0)", $config['before_script']); + $config['before_script'] = sprintf("%s", implode(" && ", $config['before_script'])); } + + return sprintf("RUN cd %s && %s", self::WORKDIR, $this->encapsulateCmd($config['before_script'])); } /** @@ -149,13 +168,58 @@ private function parseBeforeScript($config) private function parseScript($config) { if (!isset($config['script'])) { - return sprintf("CMD %s", $this->defaultTestCommand[$config['language']]); + $config['script'] = sprintf("%s", $this->defaultTestCommand[$config['language']]); } if (is_array($config['script'])) { - return sprintf("CMD %s", implode(" && ", $config['script'])); - } else { - return sprintf("CMD %s", $config['script']); + $config['script'] = sprintf("%s", implode(" && ", $config['script'])); + } + + return sprintf("CMD %s", $this->encapsulateCmd($config, $config['script'])); + } + + /** + * Return content for task before install + * + * @param array $config TravisCi Configuration parsed + * + * @return string Content to add to Dockerfile + */ + private function parseBeforeInstall($config) + { + if (!isset($config['before_install'])) { + return ""; } + + if (is_array($config['before_install'])) { + $config['before_install'] = sprintf("%s", implode(" && ", $config['before_install'])); + } + + return sprintf("RUN cd %s && %s", self::WORKDIR, $this->encapsulateCmd($config, $config['before_install'])); + } + + /** + * Return command for task install + * + * @param array $config TravisCi Configuration parsed + * + * @return string Content to add to Dockerfile + */ + private function parseInstall($config) + { + return sprintf("RUN cd %s && %s", self::WORKDIR, $this->encapsulateCmd($config, $this->installMapping[$config['language']])); + } + + /** + * Encapsulate command for given language + * + * @param array $config TravisCi Configuration parsed + * @param string $cmd Command to encapsulate + * + * @return string Content to add to Dockerfile + */ + private function encapsulateCmd($config, $cmd) + { + return sprintf($this->encapsulation[$config['language']], $cmd); } } diff --git a/src/Joli/JoliCi/Command/RunCommand.php b/src/Joli/JoliCi/Command/RunCommand.php index 3daff38..96c9a36 100644 --- a/src/Joli/JoliCi/Command/RunCommand.php +++ b/src/Joli/JoliCi/Command/RunCommand.php @@ -12,8 +12,10 @@ use Docker\Docker; use Docker\Http\Client; +use Joli\JoliCi\Builder; use Joli\JoliCi\Executor; use Joli\JoliCi\BuildStrategy\JoliCiBuildStrategy; +use Joli\JoliCi\BuildStrategy\TravisCiBuildStrategy; use Joli\JoliCi\Log\SimpleFormatter; use Monolog\Logger; use Monolog\Handler\StreamHandler; @@ -23,8 +25,6 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Filesystem\Filesystem; -use Joli\JoliCi\Builder; -use Joli\JoliCi\BuildStrategy\TravisCiBuildStrategy; class RunCommand extends Command