Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
ÇîÈ˵ijÖÐø¼¯³ÉÓë³ÖÐø½»¸¶
 
×÷ÕߣºÉ÷¶ÀÉ÷ÐÐ À´Ô´£ºCSDN ·¢²¼ÓÚ 2016-2-23
  4499  次浏览      30
 

·þÎñÆ÷¶ËÓ¦Óõ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¼´¿É£º

language: 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']);

ÕâÑù£¬ÎÒÃÇÔÚ±¾µØ¿ª·¢Ê±£¬Ö»ÐèÒª¼òµ¥µÄÖ´ÐУº

$ gulp

¼´¿É¡£¶øÔÚ·¢²¼½×¶Î£¬Ö»ÐèÒªÖ´ÐУº

$ gulp release

µ¥Ôª²âÊÔ

ÎÒÃÇÔÚSnap CIÉϽ«githubÉϵĴúÂë¿â¹ØÁªÆðÀ´£¬È»ºóÌí¼ÓÒ»¸öÃû½Ðunit-testµÄstage£¬Ö¸¶¨Õâ¸östage¶ÔÓ¦µÄÃüÁîΪ£º

npm install
gulp

ÕâÑù£¬Ã¿µ±ÎÒÃÇÓÐеÄÌá½»Ö®ºó£¬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¾Í¿ÉÒÔÏíÊÜÕâЩÃâ·Ñ·þÎñÌṩµÄ×Ô¶¯¹¹½¨£¬×Ô¶¯»¯²âÊÔÒÔ¼°×Ô¶¯²¿ÊðµÄ¹¦ÄÜ¡£

   
4499 ´Îä¯ÀÀ       30
Ïà¹ØÎÄÕÂ

ΪʲôҪ×ö³ÖÐø²¿Êð£¿
ÆÊÎö¡°³ÖÐø½»¸¶¡±£ºÎå¸öºËÐÄʵ¼ù
¼¯³ÉÓë¹¹½¨Ö¸ÄÏ
³ÖÐø¼¯³É¹¤¾ßµÄÑ¡Ôñ-×°ÔØ
Ïà¹ØÎĵµ

³ÖÐø¼¯³É½éÉÜ
ʹÓÃHudson³ÖÐø¼¯³É
³ÖÐø¼¯³ÉÖ®-ÒÀÀµ¹ÜÀí
IPD¼¯³É²úÆ·¿ª·¢¹ÜÀí
Ïà¹Ø¿Î³Ì

ÅäÖùÜÀí¡¢ÈÕ¹¹½¨Óë³ÖÐø¼¯³É
Èí¼þ¼Ü¹¹Éè¼Æ·½·¨¡¢°¸ÀýÓëʵ¼ù
µ¥Ôª²âÊÔ¡¢Öع¹¼°³ÖÐø¼¯³É
»ùÓÚAndroidµÄµ¥Ôª¡¢ÐÔÄܲâÊÔ
×îл¼Æ»®
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢ 6-12[ÏÃÃÅ]
È˹¤ÖÇÄÜ.»úÆ÷ѧϰTensorFlow 6-22[Ö±²¥]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 6-30[±±¾©]
ǶÈëʽÈí¼þ¼Ü¹¹-¸ß¼¶Êµ¼ù 7-9[±±¾©]
Óû§ÌåÑé¡¢Ò×ÓÃÐÔ²âÊÔÓëÆÀ¹À 7-25[Î÷°²]
ͼÊý¾Ý¿âÓë֪ʶͼÆ× 8-23[±±¾©]

¼¯³ÉÓë¹¹½¨Ö¸ÄÏ
ÏîÄ¿¹ÜÀí:MavenÈÃÊÂÇé±äµÃ¼òµ¥
³ÖÐø¼¯³É¹¤¾ßhudson
³ÖÐø¼¯³É
MavenȨÍþÖ¸ÄÏ
³ÌÐò¼¯(UMLÖеİü)Ö®¼äÑ­»·


²úÆ··¢²¼¹ÜÀí
ÅäÖùÜÀí·½·¨¡¢Êµ¼ù¡¢¹¤¾ß
¶à²ã´Î¼¯³ÉÅäÖùÜÀí
ʹÓÃCCÓëCQ½øÐÐÏîĿʵ¼ù
CVSÓëÅäÖùÜÀí
Subversion¹ÜÀíÔ±


º£º½¹É·Ý ÖØ¹¹¼°³ÖÐø¼¯³É
µçÑлªÔ´ Éè¼ÆÔ­Àí¡¢½¨Ä£ÓëÖØ¹¹
Èí¼þÅäÖùÜÀíÈÕ¹¹½¨¼°³ÖÐø¼¯³É
µ¥Ôª²âÊÔ¡¢Öع¹¼°³ÖÐø¼¯³É
ÖйúÈí¼þÑз¢ÖÐÐÄ µ¥Ôª²âÊÔÓëÖØ¹¹
µ¥Ôª²âÊÔ¡¢Öع¹ºÍ³ÖÐø¼¯³Éʵ¼ù
ÂÞ¿ËΤ¶û C++µ¥Ôª²âÊÔ+ÖØ¹¹+Gtest