CircleCI Version 2 Build and Deploy with Workflows
Let's presume the following very basic PHP application. Apache config points to /web
. Files and folders ending with *
are ignored by Git.
__repo
|__.circleci
| |__config.yml
|__.git
|__tests
| |__features
| |__behat.yml
|__scripts
| |__deploy.sh
|__web
| |__node_modules*
| |__index.php
| |__styles.scss
| |__gulpfile.js
| |__styles.css*
|__.gitignore
On the server create a new user and add it to the www-data
group. Make it own the whole repo recursively. Let's presume this user is called repo-boss
.
$ chown -R repo-boss:www-data repo/
- On your local machine create a new SSH key pair. Add the private key to CircleCI's back-end and have a look at resulting fingerprint we'll need later. Add the public key to
/home/repo-boss/.ssh/authorized_keys
.
Now let's presume the deploy.sh
script holds the following very basic commands.
#!/usr/bin/env bash
# Set script to exit on errors.
set -e
# Get script's absolute location.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Change to repo root.
cd ${DIR};
cd ..
# Git pull.
git status
git pull
# Run Gulp.
cd web/
gulp sass
And now comes CircleCI's config.yml
that makes that whole thing work (after you at least once pulled the necessary stuff onto the server, of course). deploy
will only run when the tests finished successfully.
version: 2
jobs:
build:
docker:
- image: circleci/php:7.1-apache-node-browsers
working_directory: ~/repo-name
steps:
- checkout
- run:
name: Whatever you need to get your app up and running.
command: |
command1 # Have a look at https://github.com/leymannx/drupal-circleci-behat/blob/develop/.circleci/config.yml for a more detailed example.
command3
command4
- run:
name: Run Tests.
command: |
behat --no-snippets -f pretty -o std
deploy:
machine:
enabled: true
working_directory: ~/repo-name
steps:
- checkout
- run:
name: Fix ssh Could not resolve hostname
command: |
ssh-keyscan 123.45.67.89 >> ~/.ssh/known_hosts # Add live server IP to known hosts.
ssh-keyscan 555.45.67.89 >> ~/.ssh/known_hosts # Dev server, too.
- add_ssh_keys: # add private SSH key from CircleCI account based on fingerprint.
fingerprints:
- "14:09:a1:b2:b3:c4:d5:e6:f7:g8:h9:81:"
- run:
name: Deploy master.
command: if [ "${CIRCLE_BRANCH}" == "master" ]; then ssh repo-boss@123.45.67.89 'cd /var/www/repo/scripts && . deploy.sh'; else echo "Skipped"; fi
- run:
name: Deploy develop.
command: if [ "${CIRCLE_BRANCH}" == "develop" ]; then ssh repo-boss@555.45.67.89 'cd /var/www/repo/scripts && . deploy.sh'; else echo "Skipped"; fi
workflows:
version: 2
build-and-deploy:
jobs:
- build:
filters:
branches:
only:
- develop
- master
- deploy:
requires:
- build
filters:
branches:
only:
- develop
- master
Of course, you don't need to use workflows. You also can achieve this in a basic waterfall. But I liked it much better to split the two parts build and deploy up into different concerted jobs.