Deployment
Last modified on Fri 24 Jun 2022

We use the continuous delivery approach, sometimes also called continuous integration, to deploy new versions of our websites.

This approach includes an automated build service that runs your automated test suite, which can usually also deploy the latest changes to the server if the build passes.

Why?

Mina

Mina is the deploy tool we're currently using. It's being maintained by our very own @d4be4st, so if you run into any issues with it, you can always ping him.

Since Mina shouldn't be used directly for deployment, we won't go into extreme lengths about it in this article. You can read more about the deployment process with Mina in the README.md of the Mina repository.

Semaphore

Semaphore is the build service we're currently using. Semaphore supports notifications through instant messaging software, emails, and other methods. It also supports automated deployments, which have to be configured separately.

Semaphore uses Mina for deployment in the background, and you can check other projects for details on how to set up deployment.

New projects on Semaphore can be created by admin users only so, if you need to create a new project, be sure to contact your team lead.

Git and continuous delivery

Using continuous delivery for deploying our applications requires some care when handling Git branches.

Sources

Mina Workshop

1. Mina is just a wrapper around rake

task :hello do
  puts 'Hello World'
end

task :question do
  puts 'How are you?'
end

task answer: :question do
  puts 'I am fine, thanks.'
end

namespace :db do
  task :migrate do
    puts 'I am migrating database'
  end
end
rake hello          # invocation
rake hello question # chainging invocation
rake answer         # dependencies
rake db:migrate     # namespaces

2. Installing mina

gem install mina

or add it to your Gemfile with require: false

3. Using mina

3.1 initializing

mina init # creates config/deploy.rb -- Also works with ['Minafile', '.deploy.rb', 'deploy.rb', 'config/deploy.rb', minafile]

Least code for mina to work:

# config/deploy.rb

require 'mina/default'

task :deploy do
  puts 'deploying'
end

3.2 variables

require 'mina/default'

set :hello, 'world'                        # setting a variable
set :lambda, -> { "#{fetch(:hello)} world" } # setting as lambda

task :write do
  puts fetch(:hello)                       # using variables
  puts fetch(:world)                       # default is nil
  puts fetch(:world, 'Heja')               # can assign a defualt if nonexisting
  puts fetch(:lambda)
end

Can override varibles with ENV

hello=buja mina write

3.3 commands

require 'mina/default'

set :execution_mode, :pretty  # modes: [:pretty, :system, :exec, :printer](https://github.com/mina-deploy/mina/blob/master/docs/how_mina_works.md#execution-modes-runners)

task :deploy do
  run :local do               # backend: [:local, :remote]
    invoke :predeploy         # invoking other tasks
    command 'echo $PATH'      # running shell commands
  end
end

task :predeploy do
  command 'pwd'
end

3.4 options

mina -AT # list tasks
mina -d  # display configuration
mina -v  # verbose mode
mina -s  # simulate

3.5 running on remote

require 'mina/default'

set :execution_mode, :pretty
set :domain, 'localhost'

task :deploy do
  run :remote do
    invoke :predeploy
    command 'echo $PATH'
  end
end

task :predeploy do
  command 'pwd'
end

4. Deploying with mina

# config/deploy.rb
require 'mina/deploy'
require 'mina/git'

set :application_name, 'mina_test'
set :domain, 'localhost'
set :deploy_to, '/Users/stef/dev/misc/mina_workshop/examples/4_www'
set :repository, '/Users/stef/dev/misc/mina_workshop/examples/4_deploy'
set :branch, 'master'

task :deploy do
  deploy do
    invoke :'git:clone'

    on :launch do
      command 'pwd'
    end
  end
end
mina setup
mina deploy
tree ../4_www
../4_www
├── current -> /Users/stef/dev/misc/mina_workshop/examples/4_www/releases/2
├── releases
│   ├── 1
│   └── 2
│       └── config
│           └── deploy.rb
├── scm
│   ├── HEAD
│   ├── config
│   ├── description
│   ├── hooks
│   │   ├── applypatch-msg.sample
│   │   ├── commit-msg.sample
│   │   ├── post-update.sample
│   │   ├── pre-applypatch.sample
│   │   ├── pre-commit.sample
│   │   ├── pre-push.sample
│   │   ├── pre-rebase.sample
│   │   ├── pre-receive.sample
│   │   ├── prepare-commit-msg.sample
│   │   └── update.sample
│   ├── info
│   │   └── exclude
│   ├── objects
│   │   ├── 03
│   │   │   └── 2ebb0ede1ede2ef44ca2a0ed2182e554e22548
│   │   ├── 55
│   │   │   └── 3506a9a535dbdd64f3e8016a50a4f2bee39bba
│   │   ├── ab
│   │   │   └── 87456cb4f6725a6b39e64e22bfd84650d353c5
│   │   ├── c8
│   │   │   └── d683fbe9cc6ede0e82a360ab01b85f78f00f2c
│   │   ├── info
│   │   └── pack
│   ├── packed-refs
│   └── refs
│       ├── heads
│       └── tags
├── shared
└── tmp

more info at https://github.com/mina-deploy/mina/blob/master/docs/deploying.md and https://github.com/mina-deploy/mina/blob/master/data/deploy.sh.erb

5. Avaliable plugins