otto/examples/webapp.otto

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