SlideShare a Scribd company logo
1 of 117
UPGRADINGTO RAILS 3
Changing the wheels on the bus at 80mph
(or 128.784 kph for everyone else)
Andrew Bloomgarden Julian Giuca
Andrew introduction
Andrew Bloomgarden
@aughr
2
Julian Giuca
@juliangiuca
3
Julian Giuca
@juliangiuca
3
Julian Giuca
@juliangiuca
3
Julian Giuca
@juliangiuca
3
4
Overview
5
You can dual boot
Rails 2 and Rails 3
Do try this at home!
6
Let’s talk about numbers...
7
Rails versions in the wild
2.x.x 3.x.x
8
Numberofaccounts
2.2.2# 2.2.3# 2.3.2# 2.3.4# 2.3.5# 2.3.8# 2.3.10# 2.3.11# 2.3.12# 2.3.14# 2.3.15# 3.0.1# 3.0.3# 3.0.5# 3.0.11# 3.0.15# 3.0.18# 3.0.19# 3.1.1# 3.2.1# 3.2.8# 3.2.11# 3.2.13#
Rails versions with >1 server
2.x.x 3.x.x
Numberofaccounts
Rails version vs number of server
10
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
11
Putting it off
Rearchitecting the app first
Do it all in a big spike!
Have a ruby_19 branch
STUPID THINGS WE TRIED
12
Rails 3? Why now?
13
Rails 3? Why now?
Someone will make upgrading
easier soon!
13
Rails 3? Why now?
Someone will make upgrading
easier soon!
Oh man, this is going to
be awful.
13
Gems are leaving us behind
14
Gems are leaving us behind
14
Come and work on
our Rails 2.3 app!
15
16
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
17
A bit of history
18
A bit of history
Move to Rails 2.0.1
18
A bit of history
18
A bit of history
Rails 2.3.14
70,000 application LOC
59,000 test LOC
18
Don’t break the world
19
Keep everyone happy
not this
thisthis
this
20
Keep ourselves happy
CONFLICT (content): …
CONFLICT (content): …
CONFLICT (content): …
⋮
CONFLICT (content): …
Automatic merge failed; fix conflicts
and then commit the result.
21
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
22
23
24
I’m looking at you Rails 1.2.2 people
25
I’m looking at you Rails 1.2.2 people
25
Gemfile
platforms :ruby_18 do
gem 'ruby-debug'
end
platforms :ruby_19 do
gem 'debugger'
end
26
27
Monkey patched!
27
In the Gemfile
if ENV.include?("USE_RAILS_3")
class Bundler::Dsl
if !self.method_defined?(:to_definition_without_rails3_lockfile)
alias_method :to_definition_without_rails3_lockfile, :to_definition
end
def to_definition(old_lockfile, unlock)
current = File.expand_path(Dir.pwd)
filename = File.join(current, "Gemfile_rails3.lock")
lockfile = Pathname.new(filename)
to_definition_without_rails3_lockfile(lockfile, unlock)
end
end
module Bundler::SharedHelpers
def default_lockfile
current = File.expand_path(Dir.pwd)
filename = File.join(current, "Gemfile_rails3.lock")
lockfile = Pathname.new(filename)
Pathname.new(lockfile)
end
end
end
28
Two Gemfile.lock files
29
Gemfile
if is_rails3
gem 'rails', '3.0.19'
gem 'lighthouse-api', '~>2.0.0'
gem 'dalli', '~> 2.3.0'
gem 'jquery-rails', '~>2.1'
gem 'active_reload'
else
gem 'rails', '2.3.15'
gem 'lighthouse-api', '~>1.1.0'
gem 'dalli', '~> 1.0.4'
end
30
# Booting in Rails 3 mode
$ export USE_RAILS_3=true
$ bundle install
$ rails server
31
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
32
Upgrading to Rails 3
1. Procrastinate
2. Goals
3. Feature Branch
4. Fix tests
5. Merge
6. Push
7. Cross fingers
8. Fix Production
Improved!
32
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
33
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
34
Make it easy for everyone
# Rails 2
$ script/server
# Rails 3
$ script/server3
35
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
36
Onto master
1. Boot Rails 3
2. Dual boot
3. Unbreak Rails 2
4. Merge upstream
37
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Restore Rails 2
Unbreak Rails 2
BootsRails2RunsRails2BootsRails3RunsRails3
Rails 2
Boot Rails 3
Dual boot
Restore Rails 2
Onto master
1. Boot Rails 3
2. Dual boot
3. Unbreak Rails 2
4. Merge upstream
39
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
40
Dual-booting that works
Rails 2.3 Rails 3
config/boot.rb requires Rails requires Bundler
config/environment.rb
loads, configures,
and initializes the
app
initializes the app
config/application.rb doesn’t exist
loads and
configures the app
41
Dual-booting that works
Rails 2.3 Rails 3
config/boot.rb requires Rails requires Bundler
config/environment.rb
loads, configures,
and initializes the
app
initializes the app
config/application.rb doesn’t exist
loads and
configures the app
41
Just make it work
42
config/boot.rb
if ENV.include?("USE_RAILS_3")
require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||=
File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
43
else
# 123 lines that load Rails
# All that for this:
Rails.boot!
end
config/boot.rb
if ENV.include?("USE_RAILS_3")
require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||=
File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
43
else
# 123 lines that load Rails
# All that for this:
Rails.boot!
end
config/boot.rb
if ENV.include?("USE_RAILS_3")
require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||=
File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup'
43
else
# 123 lines that load Rails
# All that for this:
Rails.boot!
end
config/environment.rb
# Load the rails application
require_relative "application"
if CoreAppConfig.is_rails3?
# Initialize the rails application
RpmSite::Application.initialize!
end
44
config/application.rb
module NewRelicApplicationConfig
def self.rails3_config(config)
# Do Rails 3 stuff
common_config(config)
end
def self.rails2_config(config)
# Do Rails 2 stuff
common_config(config)
end
def self.common_config(config)
# ...
end
end
45
config/application.rb
46
if is_rails3
require 'rails/all'
Bundler.require(:default, Rails.env)
module RpmSite
class Application < Rails::Application
::NewRelicApplicationConfig.rails3_config(config)
end
end
else
Rails::Initializer.run do |config|
::NewRelicApplicationConfig.rails2_config(config)
end
end
config/application.rb
46
if is_rails3
require 'rails/all'
Bundler.require(:default, Rails.env)
module RpmSite
class Application < Rails::Application
::NewRelicApplicationConfig.rails3_config(config)
end
end
else
Rails::Initializer.run do |config|
::NewRelicApplicationConfig.rails2_config(config)
end
end
config/application.rb
46
if is_rails3
require 'rails/all'
Bundler.require(:default, Rails.env)
module RpmSite
class Application < Rails::Application
::NewRelicApplicationConfig.rails3_config(config)
end
end
else
Rails::Initializer.run do |config|
::NewRelicApplicationConfig.rails2_config(config)
end
end
Have tests you trust
47
Use CI
48
Upgrade dependencies on master
49
BackgroundJob to Resque
Bj.submit 'script/background/do_something.rb',
:email => DEV_TEAM
50
Never again
def getopts opts = {}
if RUBY_VERSION.to_f >= 1.9
# In 1.9 this throw/catch/getopts nonsense breaks
lambda do |*args|
keys, default, ignored = args
[keys].flatten.each do |key|
[key, key.to_s, key.to_s.intern].each do |key|
return opts[key] if opts.has_key?(key)
end
end
return default
end
else # In 1.8 you can't return across threads
lambda do |*args|
keys, default, ignored = args
catch('opt') do
[keys].flatten.each do |key|
[key, key.to_s, key.to_s.intern].each do |key|
throw 'opt', opts[key] if opts.has_key?(key)
end
end
default
end
end
end
end
51
Add an abstraction layer
Bj.submit 'script/background/do_something.rb',
:email => DEV_TEAM
52
Add an abstraction layer
Async::Command.new(
'script/background/do_something.rb'
).notify(DEV_TEAM).enqueue
52
Use Resque or BackgroundJob
class Async::Command < Async::Job
if CoreAppConfig.use_resque?
include Async::ResqueJob
extend Resque::Plugins::History
else
include Async::BjJob
end
# ...
end
53
Finally, use Resque
54
Branch by abstraction
55
The problem being with feature
branches is that the current state of
any one of them might be unable to
be deployed for a number of weeks
while the team gets it right.Those
branches just end up running and
running ….
– Paul Hammant
Branch by abstraction
55
Branch by abstraction: a pattern
for making large-scale changes to your
application incrementally on mainline.
– Jez Humble
Punt when you can56
ActiveSupport::Deprecation.silenced = true
57
Your old routes still work
RpmSite::Application.routes.draw do |map|
Jammit::Routes.draw(map)
# ...
end
58
Your old routes still work
RpmSite::Application.routes.draw do |map|
Jammit::Routes.draw(map)
# ...
end
58
Your old mailers still work
class AccountMailer < ApplicationMailer
def new_account(account, user, subscription)
headers['Errors-to'] = BOUNCE_ACCOUNT
from BILLING_ACCOUNT
subject "New Relic invoice account request"
recipients INVOICE_RECIPIENT
@account = account
@user = user
@subscription = subscription
end
end
59
Your old mailers still work
class AccountMailer < ApplicationMailer
def new_account(account, user, subscription)
headers['Errors-to'] = BOUNCE_ACCOUNT
from BILLING_ACCOUNT
subject "New Relic invoice account request"
recipients INVOICE_RECIPIENT
@account = account
@user = user
@subscription = subscription
end
end
59
Your old models (can) still work
self.store_full_sti_class = false
60
Your old views (can) still work
helper PrototypeHelper
clear_helpers
61
Your error handling (can) still work
# included into ApplicationController
def rescue_with_handler(e)
if super # ActiveSupport::Rescuable
true
else
rescue_action_in_public e
true
end
end
62
Temporarily ugly
63
if CoreAppConfig.is_rails3?
# do something
else
# do something else
end
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
64
We wantYOU to test!
65
To run in Rails 3, just run
script/server3
Extensive manual testing
66
DatabaseData collection
UI
Rails 3 UI
Make everyone a tester
67
Turn on Rails 3 by default
-is_rails3 = ENV.include?("USE_RAILS_3")
+is_rails3 = !ENV.include?("USE_RAILS_2")
68
Incompatible sessions
69
ActionDispatch::Session::SessionRestoreError
(Original exception: uninitialized constant
ActionController::Flash::FlashHash)
Incompatible sessions
69
Deploy a canary
70
Pause the world
71
Deploy all the servers
72
Oops
73
74
And we’re done!
75
And we’re done!
75
A few very tiny fires
76
Breaking the audit trail
ActionController::Base.class_eval do
cache_sweeper :audit_sweeper
end
Audit.add_observer(AuditSweeper.instance)
class AuditSweeper < ActionController::Caching::Sweeper
observe Audit
end
77
Rushed Resque rollout
78
Punching ActiveScaffold in the face
.../bundle/ruby/1.9.1/gems/
active_scaffold-3.0.26/lib/
active_scaffold/bridges/date_picker/
lib/datepicker_bridge.rb:127:in
`binread':
No such file or directory - .../public/
javascripts/active_scaffold/default/
date_picker_bridge.js (Errno::ENOENT)
79
Lost BackgroundJob instrumentation
This page left intentionally blank
80
Tagging green build off of Rails 2 tests
81
Lots of cleanup
82
From an idea to production
1. Procrastinate
2. Goals
3. Onto master
4. Getting it to work
5. Rollout
6. Lessons learned
83
Lessons learned
1. Preorder the donuts your on-call engineers like
2. Deprecate ActiveScaffold
3. Schedule lots of time for firefighting and cleanup
84
•Get it into master as early as possible
•Incremental everything
•CI is your bestest childhood friend
(and you secretly have a crush on them)
The special magic pony sauce
85
newrelic.com/rails3_upgrade@aughr | @juliangiuca
86
We’re done (and we’re hiring)

More Related Content

What's hot

What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPANcharsbar
 
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...Puppet
 
SQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersSQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersConnor McDonald
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Guillaume Laforge
 
Exploit techniques - a quick review
Exploit techniques - a quick reviewExploit techniques - a quick review
Exploit techniques - a quick reviewCe.Se.N.A. Security
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterZendCon
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Guillaume Laforge
 
"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In SantosFabio Akita
 
Minimal MVC in JavaScript
Minimal MVC in JavaScriptMinimal MVC in JavaScript
Minimal MVC in JavaScriptMosky Liu
 
Zend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationZend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationRalf Eggert
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015qmmr
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)Robert Swisher
 
20141210 rakuten techtalk
20141210 rakuten techtalk20141210 rakuten techtalk
20141210 rakuten techtalkHiroshi SHIBATA
 

What's hot (20)

What you need to remember when you upload to CPAN
What you need to remember when you upload to CPANWhat you need to remember when you upload to CPAN
What you need to remember when you upload to CPAN
 
test
testtest
test
 
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
The Puppet Debugging Kit: Building Blocks for Exploration and Problem Solving...
 
SQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX DevelopersSQL and PLSQL features for APEX Developers
SQL and PLSQL features for APEX Developers
 
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012Groovy 1.8 and 2.0 at GR8Conf Europe 2012
Groovy 1.8 and 2.0 at GR8Conf Europe 2012
 
Bash 4
Bash 4Bash 4
Bash 4
 
Exploit techniques - a quick review
Exploit techniques - a quick reviewExploit techniques - a quick review
Exploit techniques - a quick review
 
Sdl Basic
Sdl BasicSdl Basic
Sdl Basic
 
PECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life betterPECL Picks - Extensions to make your life better
PECL Picks - Extensions to make your life better
 
Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012Groovy update at SpringOne2GX 2012
Groovy update at SpringOne2GX 2012
 
Mona cheatsheet
Mona cheatsheetMona cheatsheet
Mona cheatsheet
 
"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos"Elixir of Life" - Dev In Santos
"Elixir of Life" - Dev In Santos
 
Minimal MVC in JavaScript
Minimal MVC in JavaScriptMinimal MVC in JavaScript
Minimal MVC in JavaScript
 
Gevent rabbit rpc
Gevent rabbit rpcGevent rabbit rpc
Gevent rabbit rpc
 
Zend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next GenerationZend/Expressive 3 – The Next Generation
Zend/Expressive 3 – The Next Generation
 
Cooking pies with Celery
Cooking pies with CeleryCooking pies with Celery
Cooking pies with Celery
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015
 
SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)SDPHP - Percona Toolkit (It's Basically Magic)
SDPHP - Percona Toolkit (It's Basically Magic)
 
20141210 rakuten techtalk
20141210 rakuten techtalk20141210 rakuten techtalk
20141210 rakuten techtalk
 
Sinatra for REST services
Sinatra for REST servicesSinatra for REST services
Sinatra for REST services
 

Similar to Upgrading to Rails 3: Changing the wheels on the bus at 80mph

Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Clinton Dreisbach
 
DeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latestDeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latestAtifkhilji
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloManageIQ
 
Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)yarry
 
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013Puppet
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends旻琦 潘
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst TipsJay Shirley
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manormartinbtt
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyNikhil Mungel
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...Matt Gauger
 
Intro to React
Intro to ReactIntro to React
Intro to ReactTroy Miles
 
Jedi Mind Tricks for Git
Jedi Mind Tricks for GitJedi Mind Tricks for Git
Jedi Mind Tricks for GitJan Krag
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplosvinibaggio
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725miguel dominguez
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725MortazaJohari
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Yevgeniy Brikman
 

Similar to Upgrading to Rails 3: Changing the wheels on the bus at 80mph (20)

Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3Migrating Legacy Rails Apps to Rails 3
Migrating Legacy Rails Apps to Rails 3
 
DeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latestDeVry GSP 115 Week 3 Assignment latest
DeVry GSP 115 Week 3 Assignment latest
 
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe RafanielloDesign Summit - Migrating to Ruby 2 - Joe Rafaniello
Design Summit - Migrating to Ruby 2 - Joe Rafaniello
 
Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)Rails Hardware (no conclusions!)
Rails Hardware (no conclusions!)
 
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
Testing for Ops: Going Beyond the Manifest - PuppetConf 2013
 
Unit Testing Lots of Perl
Unit Testing Lots of PerlUnit Testing Lots of Perl
Unit Testing Lots of Perl
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
Speedy TDD with Rails
Speedy TDD with RailsSpeedy TDD with Rails
Speedy TDD with Rails
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst Tips
 
Porting to Python 3
Porting to Python 3Porting to Python 3
Porting to Python 3
 
Monkeybars in the Manor
Monkeybars in the ManorMonkeybars in the Manor
Monkeybars in the Manor
 
Crafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in RubyCrafting Beautiful CLI Applications in Ruby
Crafting Beautiful CLI Applications in Ruby
 
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
What's new and great in Rails 3 - Matt Gauger - Milwaukee Ruby Users Group De...
 
Intro to React
Intro to ReactIntro to React
Intro to React
 
Jedi Mind Tricks for Git
Jedi Mind Tricks for GitJedi Mind Tricks for Git
Jedi Mind Tricks for Git
 
Intro to Rails 4
Intro to Rails 4Intro to Rails 4
Intro to Rails 4
 
Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplos
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725Infrastructureascode slideshare-160331143725
Infrastructureascode slideshare-160331143725
 
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...Infrastructure as code: running microservices on AWS using Docker, Terraform,...
Infrastructure as code: running microservices on AWS using Docker, Terraform,...
 

Recently uploaded

Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsHyundai Motor Group
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetEnjoy Anytime
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAndikSusilo4
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 

Recently uploaded (20)

Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your BudgetHyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
Hyderabad Call Girls Khairatabad ✨ 7001305949 ✨ Cheap Price Your Budget
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Azure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & ApplicationAzure Monitor & Application Insight to monitor Infrastructure & Application
Azure Monitor & Application Insight to monitor Infrastructure & Application
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 

Upgrading to Rails 3: Changing the wheels on the bus at 80mph