gitlab CI for PHP & Laravel

Continuous Integration with Laravel 5.6+

29th June 2018

I've worked this together from several other examples, and separated build from deployment so that if anything goes pear-shaped, you can build the project locally with 1 command and end-up with the same configuration as gitlab CI would create.
Makefile
This builds the code but doesn't handle any deployment steps. Intended so you can get a copy of the code running locally by simply running make
.gitlab-ci.yml
Handles deployment, can be extended with test stages and additional deploment environments

Makefile


# vi: set noexpandtab

## variables
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
# SASS & JS to autodetect if css/js compile needs a rebuild
SASS := $(shell find resources/assets/sass -type f -name '*.scss')
JS := $(shell find resources/assets/js -type f -name '*.js')

## build - this runs every time
all: .env vendor node_modules public/css/app.css public/js/app.js clean

## build dependencies
.env:
    cp .env.example .env

composer.phar:
    php7.2 -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
    php7.2 composer-setup.php

vendor: composer.phar composer.json composer.lock
    php7.2 composer.phar install
    ./artisan key:generate

node_modules: package.json package-lock.json
    npm install

public/css/app.css: $(SASS)
    npm run dev

public/css/app.js: $(JS)
    npm run dev

## end build dependencies


## cleanup after build, removes files that don't need deploying
clean:
    rm -rf node_modules composer.phar composer-setup.php
You can add these lines to Makefile to make some things a bit easier for local dev, though they're not used on deployment.

    ## full cleanup - return to "just cloned" state
    distclean:
        make clean
        rm -rf vendor .env public/css/app.css public/js/app.js

    ## serve with artisan
    serve:
        ./artisan serve --host=0.0.0.0
With these, you can run make clean to clean up your working copy, or make serve to quickly serve a local copy with artisan.

.gitlab-ci.yml

This file uses several environment variables that can be set on the in repository in gitlab, under settings -> CI/CD. This lets you change the destination without editing the code, and keeps the deployment key safe, in case you share the repository later.
SSH_PRIVATE_KEY
Private key for deployment, this is in the DEPLOYMENT_USER's ~/.ssh/authorized_keys
DEPLOYMENT_USER
Username on deplyment server
DEPLOYMENT_HOST
Server to deploy to
DEPLOYMENT_PATH
Site path on deployment server

# name of the (public) docker image we're using to build
# this particular one has php5.6, 7.0, 7.1 & 7.2 available
image: stevepatter/php-builder

cache:
  paths:
    - vendor

# prepare the image
before_script:
  - apt-get update
  - apt-get -y install rsync make unzip build-essential libpng-dev
  - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
  - make

# deploy the dev branch
deploy_dev:
  only:
    - dev
  environment:
    name: dev
    url: https://dev.patter.me.uk
  script:
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
    - rsync -e "ssh -oStrictHostKeyChecking=no" -a --delete . "$DEPLOYMENT_USER"@"$DEPLOYMENT_HOST":"$DEPLOYMENT_PATH"