193 lines
3.9 KiB
Plaintext
193 lines
3.9 KiB
Plaintext
/*
|
|
* This is a description for an Otto-managed continuous delivery process for a
|
|
* "typical" web application. In this case, let us imagine that the application
|
|
* is a simple Rails "Hello World" application, with both unit tests and
|
|
* database migrations. Additionally, imagine there is a pre-production and a
|
|
* production environment defined in Heroku.
|
|
/
|
|
|
|
/*
|
|
* Incorporate some libraries which define useful things
|
|
*/
|
|
use {
|
|
stdlib
|
|
'./common/slack'
|
|
}
|
|
|
|
/*
|
|
* Configure our libraries.
|
|
*/
|
|
configure {
|
|
slack {
|
|
channel = '#otto'
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Declare the environments wherein this application will be delivered to at
|
|
* some point. For our simple Heroku example, we only have two
|
|
*/
|
|
environments {
|
|
preprod {
|
|
settings {
|
|
HOSTNAME = "preprod-ottoapp.herokuapp.com"
|
|
}
|
|
}
|
|
|
|
production {
|
|
settings {
|
|
HOSTNAME = "ottoapp.herokuapp.com"
|
|
RAILS_ENV = "production"
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
pipeline {
|
|
stages {
|
|
stage {
|
|
name = 'Build'
|
|
|
|
runtime {
|
|
docker {
|
|
image = 'ruby'
|
|
}
|
|
}
|
|
|
|
cache {
|
|
// Create a cache named "gems", immutable for the rest of the Pipeline
|
|
gems = ['vendor/']
|
|
assets = ['dist/css/', 'dist/js/']
|
|
}
|
|
|
|
steps {
|
|
sh 'bundle install --path=vendor'
|
|
sh 'bundle exec rake assets:prepare'
|
|
}
|
|
}
|
|
|
|
stage {
|
|
name = 'Test'
|
|
|
|
runtime {
|
|
from 'Build'
|
|
}
|
|
|
|
cache {
|
|
use gems
|
|
}
|
|
|
|
steps {
|
|
sh 'bundle exec rake spec'
|
|
}
|
|
}
|
|
|
|
stage {
|
|
name = 'Deploy'
|
|
|
|
stage {
|
|
name = 'Pre-production'
|
|
/*
|
|
* Indicate that the stage is going to interact with the preprod stage
|
|
* and the preprod environment settings must be made available to steps
|
|
*/
|
|
environment -> preprod
|
|
|
|
/*
|
|
* gates define the criteria for entering and exiting the stage.
|
|
*/
|
|
gates {
|
|
enter {
|
|
branch == 'master'
|
|
}
|
|
|
|
/*
|
|
* The exit block is where external stimuli back into the system
|
|
* should be modeled, providing some means of holding back the pipeline
|
|
* until the condition has been met
|
|
*/
|
|
exit {
|
|
input 'Does staging look good to you?'
|
|
}
|
|
}
|
|
|
|
runtime {
|
|
from 'Build'
|
|
}
|
|
|
|
cache {
|
|
use assets
|
|
}
|
|
|
|
steps {
|
|
// Grab our cached dist directory and commit it for push
|
|
sh 'git ci -am "Latest assets" dist'
|
|
// This is contrived and incorrect, but irrelevant to the example
|
|
sh 'git push heroku staging'
|
|
}
|
|
|
|
notify {
|
|
success {
|
|
slack 'Successfully pushed to preprod'
|
|
}
|
|
failure {
|
|
slack 'Fire on warlock mountain!'
|
|
}
|
|
}
|
|
}
|
|
|
|
stage {
|
|
name = 'Production'
|
|
environment -> production
|
|
|
|
gates {
|
|
from 'Pre-production'
|
|
|
|
enter {
|
|
input 'Are you extra sure that staging looks good to you?'
|
|
}
|
|
|
|
exit {
|
|
/*
|
|
* Ideally the system has some form of tagging of this specific run,
|
|
* to allow an external system to call back and say "this is good and
|
|
* finished"
|
|
*/
|
|
webhook {
|
|
description = 'Pingdom health check'
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
runtime {
|
|
from 'Build'
|
|
}
|
|
|
|
cache {
|
|
use assets
|
|
}
|
|
|
|
steps {
|
|
// Grab our cached dist directory and commit it for push
|
|
sh 'git ci -am "Latest assets" dist'
|
|
// This is contrived and incorrect, but irrelevant to the example
|
|
sh 'git push heroku production'
|
|
}
|
|
|
|
notify {
|
|
failure {
|
|
slack 'Failed to ship it'
|
|
}
|
|
complete {
|
|
slack 'New changes are live in production'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// vim: ts=2 sw=2 et ai
|