I maintain about a dozen plugins in the Moodle plugins repository. I use Moodlerooms’ moodle-plugin-ci project to test all of them on Travis CI. It’s a fantastic tool and rely heavily on it.
This fall I’ve been working on a plugin which, because of various hooks into Lafayette’s internal infrastructure, I’m not releasing publicly. I’d still like to test it in the usual way, so I decided to run the tests on our internal GitLab infrastructure.
Building a container
Dagefoerde pitched a usable .gitlab-ci.yml some time ago. This could be run on our existing docker-based CI infrastructure with basically no tweaks. Adding those packages on each run took several minutes, so I crafted a custom container (based on PHP 5.6, which is what we’re running) to eliminate the overhead. The package part is pretty simple:
RUN apt-get clean RUN apt-get update RUN apt-get install -y \ git \ libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libpng12-dev \ libicu-dev \ g++ \ mysql-client \ php5-mysql \ npm RUN ln -s "$(which nodejs)" /usr/bin/node RUN docker-php-ext-install -j$(nproc) iconv mcrypt intl zip mysqli RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ RUN docker-php-ext-install -j$(nproc) gd
A few lines add the PHPUnit and Composer support:
ADD https://phar.phpunit.de/phpunit.phar /usr/local/bin/phpunit RUN chmod +x /usr/local/bin/phpunit RUN curl -sS https://getcomposer.org/installer | php RUN mv composer.phar /usr/local/bin/composer RUN chmod +x /usr/local/bin/composer
Confident, I deployed this container instead of the stock php:7.0
and it promptly died:
[Symfony\Component\Process\Exception\ProcessFailedException] The command "phpenv config-add /builds/ci/res/template/moodle.ini" failed. Exit Code: 127(Command not found) Working directory: /builds Output: ================ Error Output: ================ sh: 1: phpenv: not found
Huh?
phpenv
Getting this working was tricky. There are several different phpenv projects floating around. Travis CI uses CHH/phpenv. The installation notes are a bit sparse, and didn’t spell out that you needed to install php-build as well to use the phpenv config-add
and phpenv config-rm
commands. I adapted most of this block from jolicode/phpenv, with some tweaks to reflect that I was running everything under root:
RUN git clone https://github.com/CHH/phpenv.git /tmp/phpenv && \ /tmp/phpenv/bin/phpenv-install.sh && \ /bin/bash -c "echo 'eval \"\$(phpenv init -)\"' >> /etc/profile.d/phpenv.sh" && \ echo 'eval "$(phpenv init -)"' >> /root/.bashrc ENV PATH /root/.phpenv/bin:$PATH RUN git clone https://github.com/CHH/php-build /root/.phpenv/plugins/php-build && \ cp /tmp/phpenv/extensions/rbenv-config-* /root/.phpenv/plugins/php-build/bin/ RUN mkdir -p /root/.phpenv/versions/system/etc/conf.d
Directory collisions
Our internal Moodle projects in GitLab are organized into a “Moodle” group. When GitLab clones a project during a CI run it puts it into the /builds/moodle/<project name>
directory. This causes a problem, because by default moodle-plugin-ci will try cloning core Moodle into /builds/moodle
. The directory isn’t empty in our case, so this clone fails.
The first way I solved this was by proposing a feature request to moodle-plugin-ci: allow a customized installation path for Moodle. A second way, I realized later, was to create such a directory myself in the .gitlab-ci.yml
file, and then create the ci project and core installation one level deep. The build path for the project ($CI_PROJECT_DIR
) is absolute anyway. It looks a little clunkier than the default, but it works:
- mkdir moodle-ci - cd moodle-ci - composer create-project -n --no-dev moodlerooms/moodle-plugin-ci ci ^1 - export PATH="$(cd ci/bin; pwd):$(cd ci/vendor/bin; pwd):$PATH" - chmod u+x /builds/moodle-ci/ci/bin/moodle-plugin-ci - chmod u+x /builds/moodle-ci/ci/bin/*
In this revised setup, builds
looks like this:
builds/ moodle-ci/ ci/ moodle/ your-moodle-plugin/
Multiple versions
GitLab doesn’t have the same concept of the Travis build matrix, but you can approximate it using a job template:
.job_template: &job_definition script: - moodle-plugin-ci phplint - moodle-plugin-ci phpcpd - moodle-plugin-ci phpmd - moodle-plugin-ci codechecker - moodle-plugin-ci csslint - moodle-plugin-ci shifter - moodle-plugin-ci jshint - moodle-plugin-ci validate - moodle-plugin-ci phpunit - moodle-plugin-ci behat job1: <<: *job_definition image: lafayette/php56-moodle:latest variables: MOODLE_BRANCH: "MOODLE_33_STABLE" job2: <<: *job_definition image: lafayette/php70-moodle:latest variables: MOODLE_BRANCH: "MOODLE_33_STABLE"
This works well enough for my purposes. For an internal project, I’m only interested in testing my current environment, and the next likely environment. I don’t need to test postgresql, or myriad Moodle versions that we don’t run.
Featured image by Slambo at en.wikipedia (Transferred from en.wikipedia.) [CC BY-SA 2.0], via Wikimedia Commons
Hello,
Moodle now offers an official docker image with php7 and apache (https://github.com/moodlehq/moodle-php-apache) that simplifies the setup for ci on gitlab.
Take a look at https://gist.github.com/danielneis/5c6140ec8150c6151a54bccd26950278