·þÎñÆ÷¶ËÓ¦ÓõijÖÐø½»¸¶
±¾ÎĽ«Ê¹ÓÃһЩÃâ·ÑµÄ·þÎñÀ´ÎªÄãµÄÏîÄ¿´î½¨³ÖÐø½»¸¶Æ½Ì¨£¬ÕâЩ·þÎñ°üÀ¨
³ÖÐø¼¯³É»·¾³
³ÖÐø²¿Êð»·¾³
·þÎñ¶ËÓ¦ÓÃÍйÜ
ÒÔ¼°Ò»Ð©¿ÉÒÔÓÃÓÚ±¾µØ¿ª·¢Ê¹ÓõĿªÔ´¹¤¾ßÈ磺
»ùÓÚNodeµÄ¹¹½¨monitor
HerokuµÄÃüÁîÐй¤¾ß
Travis CIµÄÃüÁîÐй¤¾ß
³ý´ËÖ®Í⣬ÎÒÃÇÔÚ¹ý³ÌÖбàдµÄ½Å±¾»¹¿ÉÒÔÓÃÒÔ±¾µØ¹¹½¨£¬Èç¹ûÄãµÄÍŶÓÖÐÕýºÃÒѾÓÐCI¹¤¾ß/CD¹¤¾ß£¬½«ÕâЩ½Å±¾¼¯³É½øÈ¥Ò²ÊÇÒ»¼þ·Ç³£ÈÝÒ×µÄÊÂÇé¡£

±³¾°ÖªÊ¶
Èí¼þµÄ¶ÈÁ¿
´«Í³µÄ¹ÜÀí·½·¨ÂÛ£¬ÔÚÈí¼þ¿ª·¢Õâ¸öÁìÓòÀ´Ëµ»ù±¾ÉÏÊDz»¹¤×÷µÄ¡£Èí¼þÏîÄ¿µÄ²»È·¶¨ÐÔʹµÃÈËÃÇη¾å£¬¹ÜÀíÕßÏ£Íûͨ¹ýһЩÊý×Ö£¬Ö¸±êÀ´ÈÃ×Ô¼º¸Ðµ½Ä³ÖÖÐé»ÃµÄ¡°ÕƿظС±¡£Èí¼þÐÐÊý£¬²âÊÔ¸²¸ÇÂÊ£¬´úÂë¹ÊÕÏÂʵÈÊý×ÖµÄÃûÉù»ù±¾ÉÏÒѾºÜÔãÁË£¬¾³£ÓÐÈËÄÃÀ´·í´ÌÄÇЩ׷ÇóÐé»ÃÕÆ¿Ø¸ÐµÄ¡°Áìµ¼¡±¡£
µ«ÊÇÓÐÒ»¸öÊý×Ö£¬¼´Ê¹×îÍç¹ÌµÄ¡°×ÔÓÉÖ÷ÒåÕß¡±Ò²»áÈÏΪÊÇÓÐÒâÒåµÄ£¬ÄǾÍÊÇÖÜÆÚʱ¼ä£¨cycle time£©¡£¼ò¶øÑÔÖ®£¬¾ÍÊÇÒ»¸öÐèÇó´Ó²úÉúµ½×îÖÕÉÏÏßËùÐèÒªµÄʱ¼ä¡£ÆäÖаüÀ¨ÁËÐèÇó·ÖÎö£¬Éè¼Æ£¬±àÂ룬²âÊÔ£¬²¿Êð£¬ÔËάµÈ»î¶¯£¬¿ÉÄÜ»¹»á°üº¬ºóÐøµÄ¼à¿Ø¡£
Æäʵ²»ÂÛÊÇÆÙ²¼Ä£ÐÍ£¬»¹Êǵü´ú¿ª·¢µÄ·½Ê½£¬»òÕ߯äËûµÄ·½·¨ÂÛ£¬ÖÜÆÚʱ¼äµÄËõ¶Ì¶¼ÊÇÖÁ¹ØÖØÒªµÄ¡£¶ø¾ßÌåµ½ÖÜÆÚÄÚ£¬µ¥´¿µÄ¿ª·¢Ê±¼ä±ä³¤»òÕß²âÊÔʱ¼ä±ä³¤¶¼Î޹ؽôÒª¡£±ÈÈçÏîÄ¿AµÄ¿ª·¢Ê±¼äÊDzâÊÔʱ¼äµÄ2±¶£¬ÏîÄ¿BÔòǡǡ·´¹ýÀ´£¬Õâ²¢²»ÄÜ˵A×öµÄ±ÈBºÃ£¬ÕæÕýÓÐÒâÒåµÄÊÇAµÄÖÜÆÚʱ¼äÊÇ·ñ±ÈB¸ü¶Ì¡£
µ¥´¿¸ÄÉÆÏîÄ¿¹ý³ÌÖеÄijһ¸ö½×¶ÎµÄʱ¼ä£¬¿ÉÄܲ¢²»ÄÜ´ïµ½Ô¤ÆÚµÄÄ¿µÄ¡£¾Ö²¿ÓÅ»¯²¢²»Ò»¶¨»á´øÀ´È«¾ÖµÄÓÅ»¯¡£»»ÑÔÖ®£¬Í¨¹ýijЩ²ßÂÔÀ´Ìá¸ßÈí¼þ²âÊÔµÄЧÂÊδ±ØÄܼõÉÙÖÜÆÚʱ¼ä£¡¡£
³ÖÐø½»¸¶
´«Í³Çé¿öÏ£¬ÆóÒµÒª½øÐÐÈí¼þ¿ª·¢£¬´ÓÓû§Ñо¿µ½²úÆ·ÉÏÏߣ¬ÆäÖлỨ·ÑÊýÔ£¬ÉõÖÁÊýÄ꣨ÎÒµÄһλӡ¶ÈͬʸøÎÒÁÄÆð¹ý£¬ËûµÄÉϼҹ«Ë¾×ö²úÆ·£¬´Ó°æ±¾Æô¶¯µ½°æ±¾ÉÏÏßÐèÒªÕûÕûÁ½Äêʱ¼ä£¡£©¡£¶øÇÒÒ»µ©Èí¼þÐèÇó·¢Éú±ä¸ü£¬ÓÖÓÐÐèÒªÊýÔ²ÅÄܽ«±ä¸ü·¢²¼ÉÏÏß¡£³ýÁËΪ±ä¸üÌá½»´úÂëÍ⣬»¹Óкܶà¶îÍâµÄ»Ø¹é²âÊÔ£¬·¢²¼¼Æ»®£¬ÔËά²¿ÃŵĽø¶ÈµÈµÈ¡£¶øÊг¡»ú»áǧ±äÍò»¯£¬ÔÚÌØ¶¨µÄʱ¼ä´°¿ÚÖУ¬ÆóÒµµÄ¾ºÕùÕß¿ÉÄÜÔçÒÑ·¢²¼²¢Õ¼ÁìÁËÏ൱´óµÄÊг¡·Ý¶î¡£
ÔÚÈí¼þ¹¤³ÌÁìÓò£¬ÈËÃÇÌá³öÁ˳ÖÐø½»¸¶£¨continuous delivery£©µÄ¸ÅÄËüÖ¼ÔÚ¼õÉÙÖÜÆÚʱ¼ä£¬Ç¿µ÷ÔÚÈκÎʱ¿ÌÈí¼þ¶¼´¦ÓÚ¿É·¢²¼×´Ì¬¡£²ÉÓÃÕâÖÖʵ¼ù£¬ÎÒÃÇ¿ÉÒÔÆµ·±£¬¿ìËÙ£¬°²È«µÄ½«ÐèÇóµÄ±ä»¯·¢²¼³öÀ´£¬½»ÓÉÕæÊµÊÀ½çµÄÓû§À´Ê¹Óã¬ÔÚΪÓû§´øÀ´¼ÛÖµµÄͬʱ£¬ÎÒÃÇÒ²¿ÉÒÔ¿ìËÙ£¬³ÖÐøµÄµÃµ½·´À¡£¬²¢¼¤ÀøÐµı仯²úÉú£¨ÐµÄÉÌÒµ´´Ð£¬ÐµÄģʽµÈ£©¡£
³ÖÐø½»¸¶°üº¬ÁË×Ô¶¯»¯¹¹½¨£¬×Ô¶¯»¯²âÊÔÒÔ¼°×Ô¶¯»¯²¿ÊðµÈ¹ý³Ì£¬³ÖÐø¸Ä½ø¿ª·¢Á÷³ÌÖеÄÎÊÌ⣬²¢´Ù½ø¿ª·¢ÈËÔ±£¬²âÊÔÈËÔ±£¬ÔËάÈËÔ±Ö®¼äµÄÐ×÷£¬ÍŶӿÉÒÔÔÚ·ÖÖÓ¼¶±ð½«±ä¸ü·¢²¼ÉÏÏß¡£
³ÖÐø½»¸¶Ïà¹Ø¼¼Êõ¼°Êµ¼ù
°æ±¾¿ØÖÆ£¨ÅäÖùÜÀí£©
³ÖÐø¼¯³ÉCI
×Ô¶¯»¯²âÊÔ
¹¹½¨¹¤¾ß¼°¹¹½¨½Å±¾
²¿ÊðÁ÷Ë®Ïß
ÍŶÓͨ¹ý°æ±¾¿ØÖÆÀ´½øÐÐÐ×÷£¬ËùÓеĴúÂë»áÔÚ³ÖÐø¼¯³É»·¾³ÖбàÒ룬´úÂ뾲̬¼ì²é/·ÖÎö£¬×Ô¶¯»¯²âÊÔ£¨»¹¿ÉÄܲúÉú±¨¸æµÈ£©¡£³ý´ËÖ®Í⣬CI»¹»¹ÐèÒªÓÐ×Ô¶¯»¯ÑéÊÕ²âÊÔ£¬×Ô¶¯»¯»Ø¹é²âÊԵȡ£
³ÖÐø½»¸¶Ôò¸ü½øÒ»²½£¬Ëü½«»·¾³×¼±¸£¬³ÖÐø¼¯³É£¬×Ô¶¯»¯²¿ÊðµÈ·ÅÔÚÁËÒ»Æð¡£Í¨¹ýÈ«×Ô¶¯£¨ÓÐЩ¹ý³Ì¿ÉÒÔÉèÖÃΪÊÖ¶¯£¬±ÈÈç·¢²¼µ½²úÆ·»·¾³£©µÄ·½Ê½£¬Ê¹µÃÈí¼þ¿ÉÒÔÒ»¼ü·¢²¼¡£Èç¹ûÉÏÏߺó·¢ÏÖÑÏÖØdefect£¬»¹Ö§³ÖÒ»¼ü»Ø¹öµÄ»úÖÆ£¨Æäʵ¾ÍÊǽ«Ö®Ç°µÄÒ»¸öÎȶ¨°æ±¾×öÒ»´Î·¢²¼£¬ÓÉÓÚ·¢²¼Á÷³ÌÒѾ¾¹ýǧ´¸°ÙÁ¶£¬ËùÒÔ·¢²¼±¾Éí¾Í±äµÃ·Ç³£ÇáËÉ£¬°²È«£©
ÕâÆªÎÄÕÂÖУ¬ÎÒÃÇ»áʹÓÃgit+github×÷Ϊ°æ±¾¿ØÖƹ¤¾ß£¬travis-ci×÷Ϊ³ÖÐø¼¯³É»·¾³£¬gradle×÷Ϊ¹¹½¨¹¤¾ß£¬Heroku×÷ΪӦÓõIJ¿Êð»·¾³¡£ÕâЩ¹¤¾ß¶¼ÊÇÃâ·Ñ·þÎñ£¬Èç¹ûÄãÐèÒª¸ü¸ß¼¶µÄ¹¦ÄÜ£¨±ÈÈç¸ü¶àµÄ²¢·¢Êý£¬¸ü´óµÄÊý¾Ý¿â£©£¬Ôò¿ÉÒÔÑ¡Ôñ¸¶·ÑÌײ͡£²»¹ý¶ÔÓÚÎÒÃÇÆ½Ê±µÄ´ó²¿·Öside
projectÀ´Ëµ£¬Ãâ·Ñ·þÎñÒѾ×ã¹»¡£
ʵÀý
ÎÒÔÚ¡¶Ç°ºó¶Ë·ÖÀëÁË£¬È»ºóÄØ£¿¡·ÕâÆªÎÄÕÂÖУ¬Ìáµ½ÁËÒ»¸ö½Ð×öbookmarksµÄÓ¦Óã¬Õâ¸öÓ¦ÓÃÊÇÒ»¸öǰºó¶Ë·ÖÀëµÄ·Ç³£³¹µ×µÄÓ¦Óá£
ÎÒÃÇÕâÀï»áÔÙ´ÎʹÓÃÕâ¸öÓ¦ÓÃ×÷ΪʵÀý£¬²¢²ÉÓò»Í¬µÄÁ½¸öÃâ·Ñ·þÎñ£¨travis-ciºÍsnap-ci£©À´Íê³É³ÖÐø²¿Êð»·¾³µÄ´î½¨¡£
bookmarks·þÎñÆ÷
bookmarks-serverÊÇÒ»¸ö»ùÓÚspring-bootµÄ´¿´âµÄAPI£¬Ëü¿ÉÒÔ±»´ò°ü³ÉÒ»¸öjar°ü£¬È»ºóͨ¹ýÃüÁîÐÐÆô¶¯ÔËÐС£ÔÚ±¾ÎÄÖУ¬ÎÒÃÇÎÒÃǽ«»á½«Õâ¸öserver²¿Êðµ½herokuƽ̨ÉÏ¡£
Ê×ÏÈÐèÒª¶¨ÒåÒ»¸öProcfile£¬Õâ¸öÊÇÎÒÃÇÓ¦ÓõÄÈë¿Ú£¬heroku¸ù¾ÝÕâ¸öÎļþÀ´Ã÷È·ÒÔºÎÖÖ·½Ê½À´Æô¶¯ÎÒÃǵÄÓ¦Óãº
web: java -Dserver.port=$PORT -jar build/libs/bookmarks-server-0.1.0.jar --spring.profiles.active=staging |
ÓÉÓÚÎÒÃÇÔÚ±¾µØÊ¹ÓõÄʹÓÃmysql£¬¶øherokuĬÈϵÄÊÇpostgresÊý¾Ý¿â£¬Òò´ËÐèÒªÔÚapplication.ymlÖжîÍâÅäÖÃ
<code>spring: profiles: staging datasource: driverClassName: org.postgresql.Driver url: ${JDBC_DATABASE_URL} username: ${DATABASE_USER} password: ${DATABASE_PASS} jpa: database_platform: org.hibernate.dialect.PostgreSQLDialect hibernate: ddl-auto: update </code> |
ÓÐÁËÕâЩÅäÖúó£¬ÎÒÃÇÐèÒª´´½¨Ò»¸öherokuÓ¦Óãº
$ heroku create Created http://quiet-atoll-8237.herokuapp.com/ | git@heroku.com:quiet-atoll-8237.git |
´´½¨Ö®ºó£¬ÎÒÃÇ¿ÉÒÔÔÚ½çÃæÉ϶ÔÕâ¸öÓ¦ÓýøÐÐһЩÅäÖ㨵±È»£¬Ò²¿ÉÒÔͨ¹ýÃüÁîÐУ¬¾ßÌå²Î¿´heroku help£©¡£ÎªÁËÖ§³ÖÊý¾Ý¿â£¬ÐèҪΪÎÒÃǵÄÓ¦ÓÃÌí¼ÓÒ»¸öpostgresµÄAddOn¡£Ìí¼ÓÖ®ºó£¬heroku»áΪÎÒÃÇÌṩһ¸öpostgresµÄÁ¬½ÓµØÖ·£¬¸ñʽ´ó¸ÅÊÇÕâÑù£º
postgres://username:password@host:port/database |
È»ºóÎÒÃÇÐèÒªÔÚHerokuµÄÅäÖýçÃæÖÐÅäÖÃһЩ»·¾³±äÁ¿£º

ÕâÑù£¬µ±Ó¦Óò¿Êðµ½HerokuÉÏÖ®ºó£¬ÎÒÃǵÄÓ¦ÓþͿÉÒÔ¶Áµ½ÕâЩÅäÖÃÁË£¨×¢Òâapplication.ymlÖеĻ·¾³±äÁ¿JDBC_DATABASE_URL£©¡£
´î½¨³ÖÐø¼¯³É»·¾³
³ÖÐø¼¯³É»·¾³£¬ÕâÀïÎÒÃÇÑ¡ÓÃ×î¼òµ¥µÄtravis-ci£¬Ëü¿ÉÒÔºÜÈÝÒ×µÄÓëgithub¼¯³É¡£
ÔÚÏîÄ¿XÖж¨ÒåÒ»¸ö.travis.ymlµÄÎļþ
½«ÄãµÄ´úÂëpushµ½githubÉÏ
°ó¶¨githubÕʺŵ½travis
ÔÚtravisÖÐÆôÓÃÏîÄ¿X
Õâ¸ö.travis.ymlÒòÏîÄ¿¶øÒ죬ÎÒÃÇÕâÀïµÄÏîÄ¿ÊÇspring-boot£¬ËùÒÔÖ»ÐèÒªÖ¸¶¨java¼´¿É£º
Èç¹ûÊÇjavaÏîÄ¿£¬²¢ÇÒÏîÄ¿ÖÐÓÐbuild.gradle£¬travis-ci»á×Ô¶¯Ö´ÐÐgradle checkÈÎÎñ¡£
×Ô¶¯»¯²¿Êð
µ±CIÔËÐгɹ¦Ö®ºó£¬ÎÒÃÇÐèÒªtravis-ci°ïÎÒÃǽ«Ó¦ÓóÌÐò·¢²¼µ½herokuÉÏ£¬ÕâʱºòÐèÒª×öһЩÐ޸ġ£×î¼òµ¥µÄ·½Ê½ÊÇÖ±½Ó°²×°travis-ciµÄÃüÁîÐй¤¾ßµ½±¾µØ£º
$ gem install travis -v 1.8.0 --no-rdoc --no-ri |
È»ºóͨ¹ýherokuµÄauth:tokenÃüÁî»ñµÃherokuµÄtoken£¬ÔÚ¼ÓÃܲ¢Ð´Èë.travis.yml£º
$ heroku auth:token 00xxxxxxxxxxxxx55d11dbd0cxxxxxxxxxxfe067 $ travis encrypt 00xxxxxxxxxxxxx55d11dbd0cxxxxxxxxxxfe067 --add |
µ±È»¿ÉÒԺϲ¢ÎªÒ»ÌõÃüÁ
$ travis encrypt $(heroku auth:token) --add |
½«¼ÓÃܹýµÄtoken´æÈë.travis.ymlÎļþ¡£×îºóµÄ½á¹û´óÖÂÈçÏ£º
language: java deploy: provider: heroku api_key: secure: ... app: quiet-atoll-8237 |
×¢Òâ´Ë´¦µÄapp£¬ÕýÊÇÎÒÃǵÄAppµÄÃû×Ö¡£ÁíÍ⣬»¹ÐèÒª¸øbuild.gradleÌí¼ÓÒ»¸öÃû½ÐstageµÄtask£¬travisÔÚdeployʱÐèÒªÕâ¸ötask£º
task stage { dependsOn build } |

ÕâÑù£¬ÎÒÃÇÖ»ÐèÒªÔÚ±¾µØµÄÒ»¸öÌá½»£¬Ò»Çж¼»á×Ô¶¯»¯ÆðÀ´£º
travis»áÖ´ÐÐgradle check
gradle check»á±àÒë²¢ÔËÐÐ×Ô¶¯»¯²âÊÔ
travis»á²¿ÊðÓ¦Óõ½herokuÉÏ
heroku»á×Ô¶¯ÖØÆô·þÎñ
ÎÒÃÇ¿ÉÒÔÔÚ±¾µØ½øÐмòµ¥µÄ²âÊÔ£¨×¢Òâ´Ë´¦ÎÒÃǵÄstaging»·¾³µÄURL£©£º
$ curl https://quiet-atoll-8237.herokuapp.com/api/feeds -s | jq . [ { "id": 1, "url": "http://icodeit.org/2016/01/how-to-summarize-privious-project/", "title": "ÈçºÎ³Ö¾Ã»¯ÄãµÄÏîÄ¿¾Àú", "author": "icodit.org", "summary": "ͨ³£À´Ëµ£¬ÏÂÏîÄ¿×ÜÊÇÒ»¼þ±È½Ï¸ßÐ˵ÄÊ£¨´ó²¿·ÖÍŶӻ¹»áÒ»Æð³Ô¸ö·¹Çìףһϣ©¡£", "publishDate": "2016-01-07" }, { "id": 2, "url": "http://icodeit.org/2015/11/get-started-with-reflux/", "title": "ÄãΪʲôӦ¸ÃÊÔÒ»ÊÔReflux£¿", "author": "icodit.org", "summary": "ReactÔÚÉè¼ÆÖ®³õ¾ÍÖ»¹Ø×¢ÔÚView±¾ÉíÉÏ£¬
ÆäÓಿ·ÖÈçÊý¾ÝµÄ»ñÈ¡£¬Ê¼þ´¦ÀíµÈ£¬È«È»²»ÔÚ¿¼ÂÇÖ®ÄÚ¡£", "publishDate": "2016-01-09" } ] |
ÍêÕûµÄ´úÂëÔÚÕâÀï¡£
ÆäËû
CI monitor
node-build-monitorÊÇÒ»¸ö·Ç³£ÈÝÒ×ÅäÖã¬Ê¹ÓõÄCI monitor£¬ÎÒÃÇÖ»ÐèÒª½øÐмòµ¥µØÅäÖ㬾ͿÉÒÔ½«travisµÄ״̬¿ÉÊÓ»¯³öÀ´
{ "monitor": { "interval": 2000, "numberOfBuilds": 12, "debug": true }, "services": [ { "name": "Travis", "configuration": { "slug": "abruzzi/bookmarks-server" } } ] } |
²»¹ýÕâ¸ö¹¤¾ß»áÔÚÓÐÍøÂçÒ쳣ʱ×Ô¶¯ÖÕÖ¹£¬ÎÒÃÇ¿ÉÒÔͨ¹ýÒ»¸ö¼òµ¥µÄ½Å±¾À´ÔÚËüÖÕֹʱ×Ô¶¯ÖØÆô£º
#!/bin/bash until node app/app.js do echo "restarting..." done |

С½á
ͨ¹ýtravisºÍherokuÕâÑùµÄÃâ·Ñ·þÎñ£¬ÎÒÃǾͿÉÒÔÇáËɵĽ«×Ô¼ºµÄÏîÄ¿×öµ½³ÖÐø¼¯³É+³ÖÐø½»¸¶¡£ÎÒÃǺó¶ËµÄ·þÎñÏà¶ÔÀ´ËµÊDZȽÏÈÝÒ׵쬵«ÊÇÉæ¼°µ½Ò»¸öǰºó¶Ë·ÖÀëµÄ¼Ü¹¹£¬ÈçºÎ×öµ½¾²Ì¬ÄÚÈݵÄÍйܣ¬´ò°ü£¬²¿Ê𣬲¢ºÍºó¶ËAPI¼¯³ÉÆðÀ´£¬ÎÒ»áÔÚÏÂһƪÎÄÕÂÖÐÏêϸ½âÊÍ¡£
¿Í»§¶Ë³ÌÐòµÄµÄ³ÖÐø½»¸¶
ÉÏÆªÎÄÕ½éÉÜÁËÈçºÎʹÓÃһЩÃâ·ÑµÄ·þÎñÀ´ÊµÏÖ·þÎñÆ÷¶ËAPIµÄ³ÖÐø¼¯³É¡¢³ÖÐø½»¸¶»·¾³µÄ´î½¨¡£ÓÐÁË·þÎñ¶Ë£¬×ÔÈ»ÐèÒªÓÐÏû·ÑÕߣ¬ÔÚ±¾ÎÄÖÐÎÒÃǽ«Ê¹ÓÃÁíÍâÒ»¸ö¹¤¾ßÀ´ÊµÏÖ´¿Ç°¶ËµÄÕ¾µãµÄ²¿Êð¡£
ÆäÖаüÀ¨£º
³ÖÐø¼¯³É£¨µ¥Ôª²âÊÔ£¬¼¯³É²âÊԵȣ©
³ÖÐø²¿Êð/³ÖÐø½»¸¶
¾²Ì¬Õ¾µãÍйÜ
³ý´ËÖ®Í⣬ÎÒÃÇ»¹»áÉæ¼°µ½£º
×Ô¶¯»¯UI²âÊÔsite_prism
¾²Ì¬Õ¾µãµÄ·¢²¼½Å±¾
awsµÄÃüÁîÐй¤¾ß
ÎÒÃǵÄÓ¦ÓÃ×îºó¿´ÆðÀ´ÊÇÕâÑù×ӵġ£

¼¼ÊõÑ¡ÐÍ
ÎÒÃÇÔÚ±¾ÎÄÖУ¬½«²ÉÈ¡ÁíÍâÒ»Ì×Ãâ·Ñ·þÎñÀ´Íê³É»·¾³µÄ´î½¨
1.ThoughtWorks³öÆ·µÄSnap CI×÷Ϊ³ÖÐø¼¯³É/³ÖÐø½»¸¶»·¾³
2.AWSµÄS3×÷ΪӦÓ÷¢²¼µÄµØ·½
Snap CIÊÇÒ»¸ö·Ç³£Ò×ÓÚʹÓõijÖÐø½»¸¶»·¾³£¬ÓÉÓÚºÜ¶à¹ØÓÚ³ÖÐø¼¯³É£¬³ÖÐø½»¸¶µÄ¸ÅÄîºÍʵ¼ù¶¼¸úThoughtWorksÓйأ¬ËùÒÔÕâ¸ö²úÆ·¶ÔÓÚ¹¹½¨£¬Á÷Ë®Ïߣ¬²¿ÊðµÈµÈµÄÖ§³ÖÒ²¶¼×öµÄ·Ç³£ºÃ¡£
S3ÊÇÑÇÂíÑ·µÄÔÆ´æ´¢Æ½Ì¨£¬ÎÒÃÇ¿ÉÒÔ½«¾²Ì¬×ÊÔ´ÍêÈ«ÍйÜÔÚÆäÉÏ¡£S3µÄÁíÒ»¸öºÃ´¦ÊÇËü¿ÉÒÔ½«ÄãµÄÎļþ±ä³ÉÒ»¸öWeb
Site£¬±ÈÈçÄãµÄĿ¼ÖÐÓÐindex.html£¬Õâ¸öÎļþ¾Í¿ÉÒÔ×÷ΪÄãµÄÕ¾µãÊ×Ò³±»ÆäËûÈË·ÃÎÊ¡£Õâ¸ö¶ÔÓÚÎÒÃÇÕâ¸öǰºó¶Ë·ÖÀëÏîÄ¿À´Ëµ·Ç³£ÓÐÓã¬ÎÒÃǵÄcss£¬js£¬fontÎļþ£¬»¹ÓÐÈë¿ÚÎļþindex.html¶¼¿ÉÒÔÍйÜÓÚÆäÉÏ¡£
ʵÀý
ÔÚ±¾ÎĵÄÀý×ÓÖУ¬ÎÒÃǽ«¶¨Òå3¸östage¡£Snap CI½«Ò»´Î·¢²¼·ÖΪÈô¸É¸östage£¬Ã¿¸östageÖ»×öÒ»¼þÊÂÇ飬Èç¹ûÒ»¸östageʧ°ÜÁË£¬ºó±ßµÄ¾Í²»»á½Ó×ÅÖ´ÐС£
ÎÒÃǵÄ3¸östage·Ö±ðΪ£º
µ¥Ôª²âÊÔ
¼¯³É²âÊÔ
²¿Êð
×¼±¸¹¤×÷
bookmarks-frontendÊÇÒ»¸ö´¿Ç°¶ËµÄÓ¦Óã¬Ëü»áÏû·Ñºó¶ËÌṩµÄAPI£¬µ«ÊÇÆäʵËü²¢²»ÖªµÀ£¨Ò²²»Ó¦¸ÃÖªµÀ£©ºó¶ËµÄAPI²¿ÊðÔÚʲôµØ·½£º
$(function() { var feeds = $.get(config.backend+'/api/feeds'); var favorite = $.get(config.backend+'/api/fav-feeds/1'); $.when(feeds, favorite).then(function(feeds, favorite) { //... }); }); |
ÓÉÓÚÎÒÃÇÔÚ±¾µØ¿ª·¢Ê±£¬ÐèÒªbackendÖ¸Ïò±¾µØµÄ·þÎñÆ÷£¬¶ø·¢²¼Ö®ºó£¬ÔòÏ£ÍûËüÖ¸ÏòÉÏһƪÎÄÕÂÖÐÌáµ½µÄ·þÎñÆ÷£¬Òò´ËÎÒÃÇÐèÒª±àдһµã¹¹½¨½Å±¾À´Íê³ÉÕâ¼þʶù£º
var backend = 'http://quiet-atoll-8237.herokuapp.com'; gulp.task('prepareConfig', function() { gulp.src(['assets/templates/config.js']) .pipe(replace(/#backend#/g, 'http://localhost:8100')) .pipe(gulp.dest('assets/script/')); }); gulp.task('prepareRelease', function() { gulp.src(['assets/templates/config.js']) .pipe(replace(/#backend#/g, backend)) .pipe(gulp.dest('assets/script/')); }); |
ÎÒÃǶ¨ÒåÁËÁ½¸ögulpµÄtask£¬±¾µØ¿ª·¢Ê±£¬Ê¹ÓÃprepareConfig£¬Òª·¢²¼Ê±£¬Ê¹ÓÃprepareRelease£¬È»ºó¶¨ÒåÒ»¸ö¼òµ¥µÄÄ£°åÎļþconfig.js£º
module.exports = { backend: '#backend#' } |
È»ºó¿ÉÒԺܼòµ¥µÄ°üװһϣ¬·½±ã±¾µØ¿ª·¢ºÍ·¢²¼£º
gulp.task('dev', ['prepareConfig', 'browserify', 'concatcss']); gulp.task('build', ['prepareConfig', 'script', 'css']); gulp.task('release', ['prepareRelease', 'script', 'css']); |
ÕâÑù£¬ÎÒÃÇÔÚ±¾µØ¿ª·¢Ê±£¬Ö»ÐèÒª¼òµ¥µÄÖ´ÐУº
¼´¿É¡£¶øÔÚ·¢²¼½×¶Î£¬Ö»ÐèÒªÖ´ÐУº
µ¥Ôª²âÊÔ
ÎÒÃÇÔÚSnap CIÉϽ«githubÉϵĴúÂë¿â¹ØÁªÆðÀ´£¬È»ºóÌí¼ÓÒ»¸öÃû½Ðunit-testµÄstage£¬Ö¸¶¨Õâ¸östage¶ÔÓ¦µÄÃüÁîΪ£º

ÕâÑù£¬Ã¿µ±ÎÒÃÇÓÐеÄÌá½»Ö®ºó£¬Snap CI¶¼»áÄõ½Ð´úÂ룬²¢Ö´ÐÐÉÏÊöÃüÁÈç¹ûÖ´Ðгɹ¦£¬Ôò±¾µØ¹¹½¨³É¹¦¡£
¼¯³É²âÊÔ
ÓÉÓÚ²ÉÈ¡µÄÊÇǰºó¶Ë·ÖÀëµÄ²ßÂÔ£¬ÎÒÃǵÄÓ¦ÓÿÉÒÔÍêÈ«¶ÀÁ¢Óëºó¶Ë½øÐпª·¢£¬Òò´ËÎÒÃÇÉèÖÃÁËÒ»¸öfake server£¬¾ßÌåϸ½Ú¿ÉÒԲο¼ÎÒ֮ǰµÄ²©¿Í£¬Ò²¿ÉÒÔ¿´Ô´Âë¡£²»¹ýÕâÀïÎÒÃÇҪΪ¼¯³É²âÊÔ±àдһ¸ö½Å±¾£¬²¢ÔÚSnap
CIÉÏÖ´ÐС£
#!/bin/bash export PORT=8100 bundle install # launch the application echo "launch the application" ruby app.rb 2>&1 & PID=$! # wait for it to start up sleep 3 # run the rspec tests and record the status rspec RES=$? # terminate after rspec echo "terminate the application" kill -9 $PID # now we know whether the rspec success or not exit $RES |
Õâ¸ö½Å±¾ÖУ¬Ê×ÏȰ²×°ËùÓеÄgems£¬È»ºóÆô¶¯fake server²¢½«Õâ¸öserver·ÅÖÃÔÚºǫ́ÔËÐУ¬È»ºóÖ´ÐÐrspec¡£µ±rspec²âÊÔÖ´ÐÐÍê³ÉÖ®ºó£¬ÎÒÃÇÖÕÖ¹·þÎñ½øÐУ¬È»ºó·µ»Ø½á¹û״̬Âë¡£
ÕâÀïʹÓÃÁËcapybaraºÍpoltergeistÀ´×öUI²âÊÔ£¬capybara»áÇý¶¯phantomjsÀ´ÔÚÄÚ´æÖÐÔËÐÐä¯ÀÀÆ÷£¬²¢Ö´Ðж¨ÒåºÃµÄUI²âÊÔ£¬±ÈÈç´Ë´¦£¬ÎÒÃǵÄUI²âÊÔ£º
require 'spec_helper' describe 'Feeds List Page' do let(:list_page) {FeedListPage.new} before do list_page.load end it 'user can see a banner and some feeds' do expect(list_page).to have_banner expect(list_page).to have_feeds end ##... end |

²¿Êð
Ê×ÏÈÐèÒªÔÚS3ÉÏ´´½¨Ò»¸öbucket£¬ÃüÃûΪbookmarks-frontend¡£È»ºóΪÆäÉèÖÃstatic
website hosting£¬ÕâʱºòAWS»áassignÒ»¸öеÄÓòÃû¸øÄ㣬±ÈÈçhttp://bookmarks-frontend.s3-website-us-west-2.amazonaws.com/¡£
È»ºóÄãÐèÒª½«Õâ¸öbucketÉèÖóÉpublic£¬ÕâÑùÆäËûÈ˲ſÉÒÔ·ÃÎÊÄãµÄbucket¡£

ÓÐÁËÕâ¸öÖ®ºó£¬ÎÒÃÇÀ´±àдһ¸öС½Å±¾£¬Õâ¸ö½Å±¾¿ÉÒÔ½«±¾µØµÄÎļþÉÏ´«ÖÁS3¡£
#!/bin/bash # install gulp and its dependencies npm install # package stuff, and point the server to the right place gulp release # upload the whold folder aws s3 cp public/ s3://bookmarks-frontend \ --recursive \ --region us-west-2 \ --acl public-read |
awsÃüÁîÊÇaws command lineÌṩµÄ£¬ÁíÍâÎÒÃÇÐèÒªÔÚ»·¾³±äÁ¿ÖÐÉèÖÃAWSÌṩ¸øÄãµÄtoken£º
AWS_ACCESS_KEY_ID=xxxxxxxxxx AWS_SECRET_ACCESS_KEY=xxxxxxxxxx |
È»ºóÎÒÃǾͿÉÒÔ½«±¾µØµÄpublicĿ¼µÝ¹éµÄÉÏ´«µ½S3µÄ¶ÔӦĿ¼ÁË£¡

ÍêÕûµÄ´úÂë¿ÉÒÔÔÚ´Ë´¦ÏÂÔØ¡£
×ܽá
ÎÒÃÇǰ¶ËµÄ³ÖÐø½»¸¶Ò²½éÉÜÍêÁË¡£ÏÖÔÚǰºó¶ËÓ¦ÓÃÍêÈ«¶ÀÁ¢£¬·¢²¼Ò²»¥²»Ó°Ïì¡£²»ÂÛÊÇ·þÎñÆ÷¶ËÐÂÔö¼ÓÁËAPI£¬»¹ÊÇÌí¼ÓÁËÐÂÊý¾Ý£¬¿Í»§¶ËµÄ·¢²¼¶¼²»ÊÜÓ°Ï죻ͬÑù£¬ÐÞ¸ÄÑùʽ£¬Ìí¼ÓеÄJavaScriptÒ²ÍêÈ«²»»áÓ°Ïìºó¶Ë¡£¸üÖØÒªµÄÊÇ£¬ËùÓеķ¢²¼¶¼ÊÇÒ»¼üʽµÄ£¬¿ª·¢ÕßÖ»ÐèÒªÒ»¸ögit
push¾Í¿ÉÒÔÏíÊÜÕâЩÃâ·Ñ·þÎñÌṩµÄ×Ô¶¯¹¹½¨£¬×Ô¶¯»¯²âÊÔÒÔ¼°×Ô¶¯²¿ÊðµÄ¹¦ÄÜ¡£
|