%3CLINGO-SUB%20id%3D%22lingo-sub-1497221%22%20slang%3D%22en-US%22%3EZero%20to%20Hero%20with%20App%20Service%2C%20Part%202%3A%20Continuous%20Integration%20and%20Delivery%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1497221%22%20slang%3D%22en-US%22%3E%3CP%3E%3CSPAN%3EThis%20is%20the%20second%20article%20in%20our%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22http%3A%2F%2F127.0.0.1%3A4000%2FAppService%2Ftags%2F%23zero-to-hero%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EZero%20to%20Hero%20with%20App%20Service%20series%3C%2FA%3E%3CSPAN%3E.%20This%20article%20assumes%20you%20have%20completed%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22http%3A%2F%2F127.0.0.1%3A4000%2FAppService%2F2020%2F06%2F29%2Fzero_to_hero_pt1.html%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EPart%201%3C%2FA%3E%3CSPAN%3E.%20In%20the%20last%20article%20you%20created%20an%20App%20Service%20Plan%2C%20a%20web%20app%2C%20and%20forked%20one%20of%20the%20sample%20applications.%20In%20this%20article%2C%20you%20will%20set%20up%20a%20Continuous%20Integration%20and%20Delivery%20(CI%2FCD)%20pipeline%20using%20GitHub%20Actions.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22what-is-cicd%22%20class%3D%22active%22%20id%3D%22toc-hId--1322056716%22%20id%3D%22toc-hId--1322056716%22%20id%3D%22toc-hId--1322056716%22%20id%3D%22toc-hId--1322056716%22%20id%3D%22toc-hId--1322056716%22%3EWhat%20is%20CI%2FCD%3F%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EContinuous%20Integration%20and%20Delivery%20is%20not%20specific%20to%20App%20Service%20or%20Azure.%20It%20is%20a%20modern%20software%20development%20best-practice%20to%20automate%20the%20testing%20and%20deployment%20of%20your%20application.%20App%20Service%20integrates%20directly%20with%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Ffeatures%2Factions%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EGitHub%20Actions%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eand%20Azure%20Pipelines%2C%20so%20setting%20up%20CI%2FCD%20with%20App%20Service%20is%20easy.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22continuous-integration%22%20id%3D%22toc-hId--631495242%22%20id%3D%22toc-hId--631495242%22%20id%3D%22toc-hId--631495242%22%20id%3D%22toc-hId--631495242%22%20id%3D%22toc-hId--631495242%22%3EContinuous%20Integration%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EContinuous%20Integration%20is%20the%20first%20step%20of%20a%20CI%2FCD%20pipeline.%20In%20this%20phase%2C%20the%20pipeline%20builds%20and%20tests%20the%20application.%20This%20is%20usually%20run%20for%20any%20new%20pull%20requests%20targeting%20the%20main%20tracking%20branch%20(formerly%20known%20as%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%20class%3D%22highlighter-rouge%22%3Emaster%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Ebranch).%20You%20can%20also%20enforce%20coding%20style%20guides%20or%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FLint_(software)%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Elint%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Ethe%20Pull%20Request%20during%20this%20phase.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22continuous-delivery%22%20id%3D%22toc-hId-1856017591%22%20id%3D%22toc-hId-1856017591%22%20id%3D%22toc-hId-1856017591%22%20id%3D%22toc-hId-1856017591%22%20id%3D%22toc-hId-1856017591%22%3EContinuous%20Delivery%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAssuming%20the%20application%20builds%20correctly%20and%20passes%20the%20tests%2C%20the%20new%20build%20will%20be%20automatically%20deployed%20(or%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CEM%3Edelivered%3C%2FEM%3E)%20to%20a%20staging%20or%20production%20server.%20Advanced%20development%20teams%20may%20deploy%20directly%20to%20production%2C%20but%20that%20requires%20considerable%20investment%20in%20development%20operations%20and%20automated%20testing.%20Teams%20that%20are%20just%20starting%20with%20CI%2FCD%20can%20deploy%20their%20builds%20to%20a%20staging%20environment%20that%20mirrors%20production%2C%20then%20manually%20release%20the%20new%20build%20once%20they%20feel%20confident.%3C%2FP%3E%0A%3CP%3EIn%20the%20next%20article%2C%20you%20will%20learn%20how%20to%20route%20a%20percentage%20of%20your%20production%20traffic%20to%20a%20staging%20environment%20to%20test%20your%20new%20build%20with%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CEM%3E%E2%80%9Creal%E2%80%9D%3C%2FEM%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Etraffic.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22create-a-staging-environment%22%20id%3D%22toc-hId-1845514487%22%20id%3D%22toc-hId-1845514487%22%20id%3D%22toc-hId-1845514487%22%20id%3D%22toc-hId-1845514487%22%20id%3D%22toc-hId-1845514487%22%3ECreate%20a%20Staging%20Environment%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EApp%20Service%20allows%20you%20to%20create%20and%20delete%20independent%20staging%20environments%2C%20known%20as%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fapp-service%2Fdeploy-staging-slots%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Eslots%3C%2FA%3E.%20You%20can%20deploy%20code%20or%20containers%20to%20a%20slot%2C%20validate%20your%20new%20build%2C%20then%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CEM%3Eswap%3C%2FEM%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Ethe%20staging%20slot%20with%20your%20production%20slot.%20The%20swap%20will%20effectively%20release%20the%20new%20build%20to%20your%20users.%20Using%20the%20CLI%20command%20below%2C%20create%20a%20staging%20slot.%20You%20will%20need%20to%20replace%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%20class%3D%22highlighter-rouge%22%3E%3CNAME%3E%3C%2FNAME%3E%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eparameter%20with%20the%20web%20app%E2%80%99s%20name%20from%20the%20previous%20article.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CDIV%20class%3D%22language-bash%20highlighter-rouge%22%3E%0A%3CDIV%20class%3D%22highlight%22%3E%0A%3CPRE%20class%3D%22highlight%22%3E%3CCODE%3Eaz%20webapp%20deployment%20slot%20create%20%3CSPAN%20class%3D%22nt%22%3E--slot%3C%2FSPAN%3E%20staging%20%3CSPAN%20class%3D%22nt%22%3E-n%3C%2FSPAN%3E%20%3CNAME%3E%20%3CSPAN%20class%3D%22nt%22%3E-g%3C%2FSPAN%3E%20zero_to_hero%0A%3C%2FNAME%3E%3C%2FCODE%3E%3C%2FPRE%3E%0A%3C%2FDIV%3E%0A%3C%2FDIV%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EStaging%20slots%20also%20get%20their%20own%20default%20domain%20names.%20The%20domain%20name%20follows%20a%20similar%20pattern%20as%20the%20production%20slot%2C%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CEM%3E%3CA%20href%3D%22http%3A%2F%2Fmycoolapp.azurewebsites.net%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ehttp%3A%2F%2Fmycoolapp.azurewebsites.net%3C%2FA%3E%3C%2FEM%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eexcept%20the%20slot%20name%20is%20appended%20to%20the%20app%E2%80%99s%20name%3A%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CEM%3Ehttp%3A%2F%2Fmycoolapp%3CSTRONG%3E-staging%3C%2FSTRONG%3E.azurewebsites.net%3C%2FEM%3E.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CFONT%20color%3D%22%23808080%22%3E%3CEM%3E%3CSPAN%20style%3D%22font-family%3A%20inherit%3B%22%3ELearn%20more%20about%3C%2FSPAN%3E%3CSPAN%20style%3D%22font-family%3A%20inherit%3B%22%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20style%3D%22font-family%3A%20inherit%3B%20background-color%3A%20%23ffffff%3B%22%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fapp-service%2Fdeploy-best-practices%23use-deployment-slots%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ebest%20practices%20for%20App%20Service%20staging%20slots%3C%2FA%3E%3CSPAN%20style%3D%22font-family%3A%20inherit%3B%22%3E.%3C%2FSPAN%3E%3C%2FEM%3E%3C%2FFONT%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22create-a-cicd-pipeline%22%20id%3D%22toc-hId-38060024%22%20id%3D%22toc-hId-38060024%22%20id%3D%22toc-hId-38060024%22%20id%3D%22toc-hId-38060024%22%20id%3D%22toc-hId-38060024%22%3ECreate%20a%20CI%2FCD%20Pipeline%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENext%2C%20you%20will%20create%20a%20CI%2FCD%20pipeline%20to%20connect%20your%20GitHub%20repository%20to%20the%20staging%20slot.%20App%20Service%20has%20built-in%20integration%20with%20GitHub%20Actions%20and%20Azure%20Pipelines.%20Since%20the%20sample%20apps%20are%20hosted%20in%20GitHub%20repos%2C%20we%20will%20use%20GitHub%20Actions%20for%20our%20pipeline.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22about-github-actions%22%20id%3D%22toc-hId-728621498%22%20id%3D%22toc-hId-728621498%22%20id%3D%22toc-hId-728621498%22%20id%3D%22toc-hId-728621498%22%20id%3D%22toc-hId-728621498%22%3EAbout%20GitHub%20Actions%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Ffeatures%2Factions%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EGitHub%20Actions%3C%2FA%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eis%20an%20automation%20framework%20that%20has%20CI%2FCD%20built%20in.%20You%20can%20run%20automation%20tasks%20whenever%20there%20is%20a%20new%20commit%20in%20the%20repo%2C%20a%20comment%20on%20a%20pull%20request%2C%20when%20a%20pull%20request%20is%20merged%2C%20or%20on%20a%20CRON%20schedule.%20Your%20automation%20tasks%20are%20organized%20into%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fhelp.github.com%2Fen%2Factions%2Fconfiguring-and-managing-workflows%2Fconfiguring-a-workflow%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Eworkflow%20files%3C%2FA%3E%2C%20which%20are%20YAML%20files%20in%20the%20repository%E2%80%99s%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%20class%3D%22highlighter-rouge%22%3E.github%2Fworkflows%2F%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Edirectory.%20This%20keeps%20your%20automation%20tasks%20tracked%20in%20source%20control%20along%20with%20your%20application%20code.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EThe%20workflow%20file%20defines%20when%20the%20automation%20is%20executed.%20Workflows%20consist%20of%20one%20or%20more%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3Ejobs%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%2C%20and%20jobs%20consist%20of%20one%20or%20more%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3Esteps%3C%2FSTRONG%3E.%20The%20jobs%20define%20the%20operating%20system%20that%20the%20steps%20are%20executed%20on.%20If%20you%20are%20publishing%20a%20library%20and%20want%20to%20test%20it%20on%20multiple%20operating%20systems%2C%20you%20can%20use%20multiple%20jobs.%20The%20steps%20are%20the%20individual%20automation%20tasks%2C%20you%20can%20write%20your%20own%20or%20import%20actions%20created%20by%20the%20GitHub%20community.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EAn%20example%20%E2%80%9CHello%20World%E2%80%9D%20workflow%20file%20is%20shown%20below.%20It%20runs%20any%20time%20there%20is%20a%20push%20to%20the%20repository%20and%20prints%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CEM%3E%E2%80%9CHello%20Keanu%20Reeves%E2%80%9D%3C%2FEM%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Ewith%20the%20current%20time.%20If%20you%20read%20the%20YAML%20carefully%2C%20you%20can%20see%20how%20the%20last%20step%20references%20the%20output%20from%20the%20earlier%20%E2%80%9CHello%20world%E2%80%9D%20command%20using%20the%20dotted%20syntax.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CPRE%20class%3D%22highlight%22%3E%3CCODE%3E%3CSPAN%20class%3D%22na%22%3Ename%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3EGreet%20Everyone%3C%2FSPAN%3E%0A%3CSPAN%20class%3D%22na%22%3Eon%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22pi%22%3E%5B%3C%2FSPAN%3E%3CSPAN%20class%3D%22nv%22%3Epush%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%5D%3C%2FSPAN%3E%20%20%3CSPAN%20class%3D%22c1%22%3E%23%20This%20workflow%20is%20triggered%20on%20pushes%20to%20the%20repository.%3C%2FSPAN%3E%0A%0A%3CSPAN%20class%3D%22na%22%3Ejobs%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%0A%20%20%3CSPAN%20class%3D%22na%22%3Ebuild%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22na%22%3Ename%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3EGreeting%3C%2FSPAN%3E%20%20%3CSPAN%20class%3D%22c1%22%3E%23%20Job%20name%20is%20Greeting%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eruns-on%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3Eubuntu-latest%3C%2FSPAN%3E%20%20%3CSPAN%20class%3D%22c1%22%3E%23%20This%20job%20runs%20on%20Linux%3C%2FSPAN%3E%0A%20%20%20%20%3CSPAN%20class%3D%22na%22%3Esteps%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%23%20This%20step%20uses%20GitHub's%20hello-world-javascript-action%3A%20https%3A%2F%2Fgithub.com%2Factions%2Fhello-world-javascript-action%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22pi%22%3E-%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22na%22%3Ename%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3EHello%20world%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Euses%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3Eactions%2Fhello-world-javascript-action%40v1%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Ewith%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Ewho-to-greet%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s1%22%3E'%3C%2FSPAN%3E%3CSPAN%20class%3D%22s%22%3EKeanu%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3EReeves'%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Eid%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3Ehello%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22c1%22%3E%23%20This%20step%20prints%20an%20output%20(time)%20from%20the%20previous%20step's%20action.%3C%2FSPAN%3E%0A%20%20%20%20%20%20%3CSPAN%20class%3D%22pi%22%3E-%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22na%22%3Ename%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3EEcho%20the%20greeting's%20time%3C%2FSPAN%3E%0A%20%20%20%20%20%20%20%20%3CSPAN%20class%3D%22na%22%3Erun%3C%2FSPAN%3E%3CSPAN%20class%3D%22pi%22%3E%3A%3C%2FSPAN%3E%20%3CSPAN%20class%3D%22s%22%3Eecho%20'The%20time%20was%20%24.'%3C%2FSPAN%3E%3C%2FCODE%3E%3C%2FPRE%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CFONT%20color%3D%22%23808080%22%3E%3CEM%3ELearn%20more%20about%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fhelp.github.com%2Fen%2Factions%2Fgetting-started-with-github-actions%2Fcore-concepts-for-github-actions%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3Ethe%20GitHub%20Actions%20terms%20and%20concepts%3C%2FA%3E.%3C%2FEM%3E%3C%2FFONT%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22create-the-pipeline%22%20id%3D%22toc-hId--1078832965%22%20id%3D%22toc-hId--1078832965%22%20id%3D%22toc-hId--1078832965%22%20id%3D%22toc-hId--1078832965%22%20id%3D%22toc-hId--1078832965%22%3ECreate%20the%20Pipeline%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIn%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CA%20href%3D%22https%3A%2F%2Fportal.azure.com%2F%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EAzure%20Portal%3C%2FA%3E%2C%20find%20and%20click%20the%20App%20Service%20you%20created%20in%20the%20previous%20article.%20Once%20you%20have%20the%20App%20Service%20open%20in%20the%20portal%2C%20select%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EDeployment%20Center%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eon%20the%20left%20side%20under%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EDeployment%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eheader.%20This%20will%20open%20the%20App%20Service%20Deployment%20Center.%20The%20deployment%20center%20will%20guide%20you%20through%20the%20CI%2FCD%20setup%20process.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3ENext%2C%20select%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EGitHub%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eand%20click%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EContinue%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eat%20the%20bottom.%20In%20the%20following%20page%2C%20select%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EGitHub%20Actions%20(Preview)%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eand%20click%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EContinue%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Eat%20the%20bottom.%20In%20the%20next%20screen%2C%20select%20your%20repository%20using%20the%20dropdowns.%20(You%20do%20not%20need%20to%20edit%20the%20language%20and%20language%20version%20dropdowns.)%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22GH-actions-portal-Trim.gif%22%20style%3D%22width%3A%20640px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F202014iCA27844E7C94FB6E%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22GH-actions-portal-Trim.gif%22%20alt%3D%22GH-actions-portal-Trim.gif%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%3EOn%20the%20final%20page%20you%20will%20see%20a%20preview%20of%20the%20GitHub%20Actions%20workflow%20file%20that%20will%20be%20committed%20into%20your%20repository.%20Click%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EComplete%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3Bto%20commit%20the%20workflow%20file%20to%20the%20repository.%20This%20commit%20will%20also%20trigger%20the%20workflow.%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CFONT%20color%3D%22%23808080%22%3E%3CEM%3ELearn%20more%20about%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fapp-service%2Fdeploy-github-actions%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EGitHub%20Actions%3C%2FA%3E%26nbsp%3Band%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fazure%2Fapp-service%2Fdeploy-continuous-deployment%23github--azure-pipelines%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EAzure%20Pipelines%3C%2FA%3E%26nbsp%3Bintegration%20with%20App%20Service.%3C%2FEM%3E%3C%2FFONT%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22check-the-pipelines-progress%22%20id%3D%22toc-hId-1408679868%22%20id%3D%22toc-hId-1408679868%22%20id%3D%22toc-hId-1408679868%22%20id%3D%22toc-hId-1408679868%22%20id%3D%22toc-hId-1408679868%22%3ECheck%20the%20Pipeline%E2%80%99s%20Progress%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EIf%20you%20go%20to%20your%20GitHub%20repository%20you%20will%20see%20a%20new%20file%20in%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CCODE%20class%3D%22highlighter-rouge%22%3E.github%2Fworkflows%2F%3C%2FCODE%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Edirectory%20on%20the%20master%20branch.%20Click%20on%20the%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CSTRONG%3EActions%3C%2FSTRONG%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Etab%20in%20the%20GitHub%20repository%20to%20see%20a%20historical%20view%20of%20all%20previous%20GitHub%20Actions%20runs.%20Once%20the%20workflow%20run%20completes%2C%20browse%20to%20your%20staging%20slot%20to%20confirm%20that%20the%20deployment%20was%20successful.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-center%22%20image-alt%3D%22deployment_center_dashboard.png%22%20style%3D%22width%3A%20999px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F202016iE6CE317D2F6A1AC0%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20title%3D%22deployment_center_dashboard.png%22%20alt%3D%22deployment_center_dashboard.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH2%20id%3D%22summary%22%20id%3D%22toc-hId-1398176764%22%20id%3D%22toc-hId-1398176764%22%20id%3D%22toc-hId-1398176764%22%20id%3D%22toc-hId-1398176764%22%20id%3D%22toc-hId-1398176764%22%3ESummary%3C%2FH2%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CEM%3ECongratulations!%3C%2FEM%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3EYou%20now%20have%20a%20CI%2FCD%20pipeline%20to%20continuously%20build%20and%20deploy%20your%20app%20to%20your%20staging%20environment.%20In%20the%20next%20article%20you%20will%20learn%20how%20to%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3E%3CEM%3Eswap%3C%2FEM%3E%3CSPAN%3E%26nbsp%3B%3C%2FSPAN%3Ethe%20staging%20and%20production%20slots%20to%20release%20new%20builds%20to%20your%20production%20users.%20The%20next%20article%20will%20also%20explain%20how%20to%20route%20a%20small%20percentage%20of%20your%20users%20to%20a%20staging%20slot%20so%20you%20can%20validate%20new%20builds%20against%20production%20traffic%20or%20do%20A%2FB%20testing.%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CH3%20id%3D%22helpful-resources%22%20id%3D%22toc-hId-2088738238%22%20id%3D%22toc-hId-2088738238%22%20id%3D%22toc-hId-2088738238%22%20id%3D%22toc-hId-2088738238%22%20id%3D%22toc-hId-2088738238%22%3EHelpful%20resources%3C%2FH3%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3E%3CA%20href%3D%22http%3A%2F%2F127.0.0.1%3A4000%2FAppService%2F2020%2F06%2F09%2FApp-Service-Continuous-Deployment-for-Windows-Containers-with-GitHub-Actions.html%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EUsing%20GitHub%20Actions%20to%20deploy%20a%20Windows%20Container%20to%20App%20Service%3C%2FA%3E%3C%2FLI%3E%0A%3CLI%3E%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2FJasonFreeberg%2Fcreate-and-delete-slots%22%20target%3D%22_blank%22%20rel%3D%22noopener%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%20noopener%20noreferrer%22%3EGitHub%20Workflows%20to%20create%20and%20delete%20a%20slot%20for%20Pull%20Requests%3C%2FA%3E%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-1497221%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3E.NET%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20App%20Service%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EJava%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3ENode.js%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EWeb%20Apps%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1497647%22%20slang%3D%22en-US%22%3ERe%3A%20Zero%20to%20Hero%20with%20App%20Service%2C%20Part%202%3A%20Continuous%20Integration%20and%20Delivery%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1497647%22%20slang%3D%22en-US%22%3E%3CP%3EThanks%20for%20Sharing%20with%20the%20Community%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F673052%22%20target%3D%22_blank%22%3E%40Jason_Freeberg%3C%2FA%3E%26nbsp%3B%3CIMG%20class%3D%22lia-deferred-image%20lia-image-emoji%22%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Fhtml%2Fimages%2Femoticons%2Fcool_40x40.gif%22%20alt%3D%22%3Acool%3A%22%20title%3D%22%3Acool%3A%22%20%2F%3E%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1503651%22%20slang%3D%22en-US%22%3ERe%3A%20Zero%20to%20Hero%20with%20App%20Service%2C%20Part%202%3A%20Continuous%20Integration%20and%20Delivery%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1503651%22%20slang%3D%22en-US%22%3E%3CP%3EThanks%20for%20sharing%2C%20but%20the%20links%20isn't%20working%20properly.%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-1506846%22%20slang%3D%22en-US%22%3ERe%3A%20Zero%20to%20Hero%20with%20App%20Service%2C%20Part%202%3A%20Continuous%20Integration%20and%20Delivery%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-1506846%22%20slang%3D%22en-US%22%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fuser%2Fviewprofilepage%2Fuser-id%2F717697%22%20target%3D%22_blank%22%3E%40mohassan%3C%2FA%3E%26nbsp%3B--%20Fixed%20it!%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft

This is the second article in our Zero to Hero with App Service series. This article assumes you have completed Part 1. In the last article you created an App Service Plan, a web app, and forked one of the sample applications. In this article, you will set up a Continuous Integration and Delivery (CI/CD) pipeline using GitHub Actions.

 

What is CI/CD?

 

Continuous Integration and Delivery is not specific to App Service or Azure. It is a modern software development best-practice to automate the testing and deployment of your application. App Service integrates directly with GitHub Actions and Azure Pipelines, so setting up CI/CD with App Service is easy.

 

Continuous Integration

 

Continuous Integration is the first step of a CI/CD pipeline. In this phase, the pipeline builds and tests the application. This is usually run for any new pull requests targeting the main tracking branch (formerly known as the master branch). You can also enforce coding style guides or lint the Pull Request during this phase.

 

Continuous Delivery

 

Assuming the application builds correctly and passes the tests, the new build will be automatically deployed (or delivered) to a staging or production server. Advanced development teams may deploy directly to production, but that requires considerable investment in development operations and automated testing. Teams that are just starting with CI/CD can deploy their builds to a staging environment that mirrors production, then manually release the new build once they feel confident.

In the next article, you will learn how to route a percentage of your production traffic to a staging environment to test your new build with “real” traffic.

 

Create a Staging Environment

 

App Service allows you to create and delete independent staging environments, known as slots. You can deploy code or containers to a slot, validate your new build, then swap the staging slot with your production slot. The swap will effectively release the new build to your users. Using the CLI command below, create a staging slot. You will need to replace the <name> parameter with the web app’s name from the previous article.

 

az webapp deployment slot create --slot staging -n <name> -g zero_to_hero

 

Staging slots also get their own default domain names. The domain name follows a similar pattern as the production slot, http://mycoolapp.azurewebsites.net except the slot name is appended to the app’s name: http://mycoolapp-staging.azurewebsites.net.

 

Learn more about best practices for App Service staging slots.

 

Create a CI/CD Pipeline

 

Next, you will create a CI/CD pipeline to connect your GitHub repository to the staging slot. App Service has built-in integration with GitHub Actions and Azure Pipelines. Since the sample apps are hosted in GitHub repos, we will use GitHub Actions for our pipeline.

 

About GitHub Actions

 

GitHub Actions is an automation framework that has CI/CD built in. You can run automation tasks whenever there is a new commit in the repo, a comment on a pull request, when a pull request is merged, or on a CRON schedule. Your automation tasks are organized into workflow files, which are YAML files in the repository’s .github/workflows/ directory. This keeps your automation tasks tracked in source control along with your application code.

 

The workflow file defines when the automation is executed. Workflows consist of one or more jobs , and jobs consist of one or more steps. The jobs define the operating system that the steps are executed on. If you are publishing a library and want to test it on multiple operating systems, you can use multiple jobs. The steps are the individual automation tasks, you can write your own or import actions created by the GitHub community.

 

An example “Hello World” workflow file is shown below. It runs any time there is a push to the repository and prints “Hello Keanu Reeves” with the current time. If you read the YAML carefully, you can see how the last step references the output from the earlier “Hello world” command using the dotted syntax.

 

name: Greet Everyone
on: [push]  # This workflow is triggered on pushes to the repository.

jobs:
  build:
    name: Greeting  # Job name is Greeting
    runs-on: ubuntu-latest  # This job runs on Linux
    steps:
      # This step uses GitHub's hello-world-javascript-action: https://github.com/actions/hello-world-javascript-action
      - name: Hello world
        uses: actions/hello-world-javascript-action@v1
        with:
          who-to-greet: 'Keanu Reeves'
        id: hello
      # This step prints an output (time) from the previous step's action.
      - name: Echo the greeting's time
        run: echo 'The time was $.'

 

Learn more about the GitHub Actions terms and concepts.

 

Create the Pipeline

 

In the Azure Portal, find and click the App Service you created in the previous article. Once you have the App Service open in the portal, select Deployment Center on the left side under the Deployment header. This will open the App Service Deployment Center. The deployment center will guide you through the CI/CD setup process.

 

Next, select GitHub and click Continue at the bottom. In the following page, select GitHub Actions (Preview) and click Continue at the bottom. In the next screen, select your repository using the dropdowns. (You do not need to edit the language and language version dropdowns.)

GH-actions-portal-Trim.gif

 

On the final page you will see a preview of the GitHub Actions workflow file that will be committed into your repository. Click Complete to commit the workflow file to the repository. This commit will also trigger the workflow.

 

Learn more about GitHub Actions and Azure Pipelines integration with App Service.

 

Check the Pipeline’s Progress

 

If you go to your GitHub repository you will see a new file in the .github/workflows/ directory on the master branch. Click on the Actions tab in the GitHub repository to see a historical view of all previous GitHub Actions runs. Once the workflow run completes, browse to your staging slot to confirm that the deployment was successful.

 

deployment_center_dashboard.png

 

Summary

 

Congratulations! You now have a CI/CD pipeline to continuously build and deploy your app to your staging environment. In the next article you will learn how to swap the staging and production slots to release new builds to your production users. The next article will also explain how to route a small percentage of your users to a staging slot so you can validate new builds against production traffic or do A/B testing.

 

Helpful resources

 

  1. Using GitHub Actions to deploy a Windows Container to App Service
  2. GitHub Workflows to create and delete a slot for Pull Requests

 

3 Comments

Thanks for Sharing with the Community @Jason_Freeberg :cool:

Occasional Visitor

Thanks for sharing, but the links isn't working properly.

Microsoft

@mohassan -- Fixed it!