35
Trying Con*nuous Delivery Toru Furukawa @torufurukawa

Trying Continuous Delivery - pyconjp 2012

Embed Size (px)

Citation preview

Page 1: Trying Continuous Delivery - pyconjp 2012

Trying'Con*nuous'Delivery�

Toru Furukawa!@torufurukawa!

Page 2: Trying Continuous Delivery - pyconjp 2012

Keep service running before and after releasing�

Page 3: Trying Continuous Delivery - pyconjp 2012

Change,'Change,'Change�

Page 4: Trying Continuous Delivery - pyconjp 2012

Ship it as soon as it is ready�

Page 5: Trying Continuous Delivery - pyconjp 2012

Con*nuous'delivery�

#"Update"the"site"every"5"minutes"*/5"*"*"*"*"cd"/www/example.com"\"""""""""&&"git"pull"\"""""""""&&"service"apache"restart"

h5ps://speakerdeck.com/u/zeeg/p/prac*cing>con*nuous>deployment>disqus>pycon>2012�

Page 6: Trying Continuous Delivery - pyconjp 2012

Business value�

Page 7: Trying Continuous Delivery - pyconjp 2012

5 Problems�

Page 8: Trying Continuous Delivery - pyconjp 2012

1. Manual operation is expensive and unpredictable�

Page 9: Trying Continuous Delivery - pyconjp 2012

Prefer'scripts'over'opera*ons�

$"make"env".............."build"dev"environment"unittest"........."run"unit"tests"acceptancetest"..."run"acceptance"tests"inspect".........."inspect"codes"deploy"..........."deploy"to"App"Engine"�

Page 10: Trying Continuous Delivery - pyconjp 2012

Automate'acceptance'tests�

Page 11: Trying Continuous Delivery - pyconjp 2012

Have'Jenkins'run'tests�

Push!

Acceptance test!Unit tests�Write codes

Unit tests!

Notify!

Pull!

Deploy!

Page 12: Trying Continuous Delivery - pyconjp 2012

2. Requirements will never be fixed�

Page 13: Trying Continuous Delivery - pyconjp 2012

Design product to ship incrementally�

Page 14: Trying Continuous Delivery - pyconjp 2012

Schema change�

class"User(Model):"""name"="StringProperty()"""birthday"=\"""""DateProperty()"

class"User(Model):"""name"="StringProperty()"""birthday"=\"""""StringProperty()"""email"=\"""""StringProperty()"

Page 15: Trying Continuous Delivery - pyconjp 2012

Add'new'property�

1.  Add property with required=False!2.  Deploy!3.  Add app code to read and write new

property!4.  Update index!5.  Deploy!�

Page 16: Trying Continuous Delivery - pyconjp 2012

Change property�

1.  “Add” property with required=False!2.  Deploy!3.  Add app code to access old and new

model!4.  Update index!5.  Deploy!6.  Fill new property (if necessary)!7.  Remove old property!

Page 17: Trying Continuous Delivery - pyconjp 2012

class"User(Model):"""name"="StringProperty()"""birthday"="DateProperty()"

Page 18: Trying Continuous Delivery - pyconjp 2012

class"User(Model):"""name"="StringProperty()"""date_birthday"=\"""""DateProperty(name='birthday')"""str_birthday"=\"""""StringProperty(name='str_birthday’)"

Page 19: Trying Continuous Delivery - pyconjp 2012

class"User(Model):"""name"="StringProperty()"""date_birthday"="…"""str_birthday"="…""""def"get_birthday(self):"""""return"self.date_birthday""""def"set_birthday(self,"val):"""""self.date_birthday"="val""""birthday"="property(get_birthday,"""""""""""""""""""""""set_birthday)"

Page 20: Trying Continuous Delivery - pyconjp 2012

class"User(Model):"""name"="StringProperty()"""date_birthday"="…"""str_birthday"="…""""def"get_birthday(self):"""""if"self.date_birthday:"""""""return"self.date_birthday.strftime(…)"""""else:"""""""return"self.str_birthday"

Page 21: Trying Continuous Delivery - pyconjp 2012

class"User(Model):"""name"="db.StringProperty()"""date_birthday"="…"""str_birthday"="…""""def"get_birthday(self):"…""""def"set_birthday(self,"val):"""""if"isinstance(val,"datetime.date):"""""""val"="val.strftime(…)"""""""self.date_birthday"="None"""""self.str_birthday"="val"

Page 22: Trying Continuous Delivery - pyconjp 2012

class"User(Model):"""name"="db.StringProperty()"""date_birthday"="…"""str_birthday"="…""""def"get_birthday(self):"…""""def"set_birthday(self,"val):"…""""birthday"="property(get_birthday,"""""""""""""""""""""""set_birthday)"

Page 23: Trying Continuous Delivery - pyconjp 2012

3. Building and changing environment is expensive�

Page 24: Trying Continuous Delivery - pyconjp 2012

Google App Engine lets us focus on app�

Page 25: Trying Continuous Delivery - pyconjp 2012

Make dev and production environments almost identical�

app.yaml�

Local dev server�

$ dev_appserver.py src�

Dev Server�$ appcfg.py update src�

$ appcfg.py update –A myproduction src�Production

Server�

Page 26: Trying Continuous Delivery - pyconjp 2012

Have multiple versions deployed to switch code quickly�

$"appcfg.py"–V"v11"update"src"..."(v11.myapp.appspot.com)"$"appcfg.py"–V"v11"set_default_version"src"..."(myapp.appspot.com)""

Page 27: Trying Continuous Delivery - pyconjp 2012

4. We still have problems�

Page 28: Trying Continuous Delivery - pyconjp 2012

Hg-flow for hotfix branches�

develop�

master�

feature�

release� hotfix�

Deploy� Deploy�

Page 29: Trying Continuous Delivery - pyconjp 2012

Rollback by changing default version�

$"appcfg.py"–V"v11"update"src"..."(v11.myapp.appspot.com)"$"appcfg.py"–V"v11"set_default_version"src""$"appcfg.py"–V"v10"set_default_version"src"

Page 30: Trying Continuous Delivery - pyconjp 2012

5. It does not happen overnight�

Page 31: Trying Continuous Delivery - pyconjp 2012

Start with what makes sense to you�

Page 32: Trying Continuous Delivery - pyconjp 2012

Allocate time for improvement�

Page 33: Trying Continuous Delivery - pyconjp 2012

TODOs�•  Review!•  Faster feedback!•  Automate capacity tests!•  Manage libraries!•  Test client side app�

Page 34: Trying Continuous Delivery - pyconjp 2012

Things got better and are getting even better�

Page 35: Trying Continuous Delivery - pyconjp 2012

Share OUR experiences�

@torufurukawa!http://about.me/torufurukawa!

http://facebook.com/toru.furukawa!