# ลองทำ Continuous Delivery (CD)

{% hint style="success" %}
**แนะนำให้อ่าน**\
บทความนี้เป็นส่วนหนึ่งของคอร์ส [**👶 Azure DevOps**](https://saladpuk.gitbook.io/learn/cloud/azure-devops) ที่จะมาสอนการใช้งานทุกสิ่งที่ DevOps ควรจะต้องมี เพื่อให้เราสามารถทำ Feedback loop ได้ไวขึ้น ดังนั้นถ้าเพื่อนๆสนใจอยากดูว่ามันทำอะไรได้ก็กดไปอ่านที่บทความหลักได้เลยครัช
{% endhint %}

{% hint style="warning" %}
**คำเตือน**\
ถ้าเพื่อนๆต้องการทำตามบทความนี้ จะต้องมีโปรเจคใน **Azure DevOps** ที่มีการนำทำ Continuous Integration ไว้เรียบร้อยแล้ว แต่ถ้าใครยังไม่มีก็สามารถไปทำตามได้จากบทตัวนี้ก่อน [**ลองทำ Continuous Integration (CI)**](https://saladpuk.gitbook.io/learn/cloud/azure-devops/ci) *\*\**&#xE41;ล้วค่อยกลับมาทำตามบทความนี้ก็ได้ครัช
{% endhint %}

หลังจากที่เรามีระบบ **Automation** ในการตรวจสอบความถูกต้องเวลาที่มีคนส่งงานเข้ามา โดยการใช้ **Continuous Integration** หรือ **CI** เรียบร้อยแล้ว ดังนั้นในรอบนี้เราก็จะลองทำระบบ Automation ให้มันเอางานของเราไปขึ้นบทเซิฟเวอร์ของเราดูบ้าง ดังนั้นไปดูกันเบย

## 🔥 Build Pipeline

ในการทำ Build pipeline ในรอบนี้จะเน้นไปที่เรื่องการเอา source code ของเราไป deploy ที่เซิฟเวอร์กันบ้าง ซึ่งเราเรียกขั้นตอนนี้ว่าการทำ **Continuous Delivery** หรือย่อๆว่า **CD** นั่นเอง ซึ่งเราสามารถเข้าไปจัดการ Build pipeline ได้จากเมนูด้านซ้ายมือในหมวดของ **Pipeline** นั่นเอง ดังนั้นจิ้มมันไปซะ

{% hint style="info" %}
**Continuous Delivery**\
การทำงานของ **CD** ตามปรกติคือเมื่อเรา push งานขึ้นมาที่เซิฟเวอร์แล้ว ระบบก็จะนำมา build test ต่างๆตามสิ่งที่เรากำหนดไว้ใน **Continuous Integration (CI)** ซึ่งถ้ามัน build ผ่านหมดแล้ว เราก็จะให้มันทำการ deploy ลงไปที่เซิฟเวอร์แบบดัตโนมัตินั่นเอง แต่โดยปรกติเราจะ deploy ไปที่ตัว **Test Environment** หรือ **Staging Environment** เพื่อตรวจเช็คความถูกต้องต่างๆก่อน เช่นดูว่า features ใหม่ถูกต้องไหม **UX** ดีพอหรือยัง บลาๆ ซึ่งเมื่อเราทดสอบทุกอย่างจนหนำใจแล้ว เราก็จะทำการสั่ง **CD** ไปยัง **Production Environment** ในขั้นตอนสุดท้ายนั่นเอง
{% endhint %}

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LugLDk8WIsmQg16zyAu%2Fimage.png?generation=1583529158006960\&alt=media)

ในการทำ **Continuous Delivery** นั้นมันจะอยู่ในหมวดย่อยของ **Pipelines** นั่นก็คือเมนู **Releases** นั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LtruxzTMMko2kW3FoLP%2Fimage.png?generation=1583529099931666\&alt=media)

### สร้าง Continuous Delivery

เจ้าโปรเจคของเราพอดีว่ามันพึ่งถูกสร้างขึ้นมาใหม่ มันก็จะยังไม่มี **Release** อะไรเลย ดังนั้นที่ด้านขวามือกดจงกด **`New pipeline`** ลงไปซะ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LusVa70IJKkx6adJeTE%2Fimage.png?generation=1583529151258627\&alt=media)

ถัดมาเขาก็จะโชว์ให้เราดูว่าเราจะตั้งวิธีการ deploy ไปที่ไหนบ้าง โดยเขาจะแบ่งออกเป็น 2 เรื่องคือ **Artifacts** และ **Stages** นั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LnHaAHT-_ZUoBqUv-2n%2Fimage.png?generation=1583529176375129\&alt=media)

### การตั้งค่า Stages

ในส่วนของ **Stages** คือการกำหนดว่า เราจะเอางานของเราไปทำการ deploy ไปที่เซิฟเวอร์ หรือ Environment ไหนบ้าง โดยในขั้นตอนนี้ที่ด้านขวาสุดเขาจะมี **Template** ในการ deploy ให้เราเลือกหลายแบบเลย ซึ่งในตัวอย่างนี้ผมจะ deploy ตัวเว็บไปบนคลาว์ของ Microsoft ละกัน ดังนั้นก็เลือก template เป็น **Azure App Service deployment** ได้เบย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Lp1PT8DIT1qXk_y0dry%2Fimage.png?generation=1583529114864709\&alt=media)

หลังจากที่เลือก template เรียบร้อยแล้ว ถัดไปเราก็จะต้องไปกำหนดค่าต่างๆว่าเราจะ deploy ไปที service ตัวไหนนั่นเอง โดยการกดที่ **Task** ตามรูปได้เลย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LngW6soVTQYJQa2KFa2%2Fimage.png?generation=1583529176327515\&alt=media)

ในขั้นตอนตั้งค่านี้ เราจะต้องเลือก subscription ที่เราจะทำงานด้วยเสียก่อน โดยการเลือก **Subscription** ตามรูปด้านล่างเลย

{% hint style="info" %}
**แนะนำให้อ่าน**\
สำหรับเพื่อนๆที่ยังไม่เคยสมัครคลาว์ของ Microsoft ก็สามารถไปสมัครได้ตามบทความด้านล่างนี้เลยครัช (ฟรี + ได้สิทธิ์ประโยชน์เยอะม๊วกๆ รายละเอียดอ่านได้ในลิงค์เลย) [**สมัคร Microsoft Azure**](https://saladpuk.gitbook.io/learn/cloud/azure101/register)\*\*\*\*
{% endhint %}

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Lngdplb9JJXgVoB9w5V%2Fimage.png?generation=1583529175098323\&alt=media)

หลังจากที่เลือก subscription ไปเรียบร้อยแล้วถัดไปเราก็จะต้องให้สิทธิ์ในการเข้าใช้งาน โดยการกดที่ปุ่ม **`Authorize`** ตามรูปเบย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LofVMrfVpAdhY42Whpa%2Fimage.png?generation=1583529156844643\&alt=media)

ทำการ Login เพื่อมอบสิทธิ์โลด

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LrnaBh5WC_gVeP1sLmk%2Fimage.png?generation=1583529112700167\&alt=media)

ถัดไปก็เลือก Service ที่เราจะ deploy ขึ้นไป ซึ่งในตัวอย่างผมได้ web service ไว้บนคลาว์ของผมแล้วชื่อว่า *saladpuk-cd* ดังนั้นในช่อง **App service name** ผมก็จะเลือกใช้ตัวนี้นั่นเอง

{% hint style="info" %}
**แนะนำให้อ่าน**\
สำหรับเพื่อนๆที่ยังไม่ได้สร้าง **Web App** บนคลาว์ สามารถเข้าไปดูวิธีการสร้างได้จากบทความด้านล่างนี้ได้เลยครับ [**สร้างเว็บตัวแรกบนคลาว์กัน**](https://saladpuk.gitbook.io/learn/cloud/azure101/website)\*\*\*\*
{% endhint %}

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-M1VAR5eBWV9nLmS4krm%2Fimage.png?generation=1583529163482608\&alt=media)

เรียบร้อยครับสำหรับการตั้งค่าว่าเราจะเอางานไปขึ้นที่เซิฟเวอร์ตัวไหน ตามรูปเลย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Lp1DFjmvifYJLntlJAQ%2Fimage.png?generation=1583529104387477\&alt=media)

### การตั้งค่า Artifacts

ในส่วนของ **Artifacts** คือการเลือกว่าเราจะเอาไฟล์ไหนไปขึ้นเซิฟเวอร์บ้าง โดยเราสามารถกดได้จากเมนูด้านบนที่ชื่อว่า **Pipeline** แล้วเลือก **Artifacts** ตามรูปเลยครัช

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Lq68IsC7PdjLfCoJtWS%2Fimage.png?generation=1583529153456381\&alt=media)

เมื่อเลือกแล้วเขาจะเปิดเมนูด้านขวาขึ้นมาให้เราเลือกว่า ไฟล์ที่จะเอาไป deploy นั้นอยู่ที่ไหน ซึ่งในตัวอย่างนี้ผมจะใช้ไฟล์ที่ได้จากการทำ **Continuous Integration (CI)** มาใช้นั่นเอง ดังนั้นเลือกตามรูปได้เลย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Lpr8DMyJk4MXrgUQH2C%2Fimage.png?generation=1583529112338928\&alt=media)

ซึ่งเมื่อเลือกเสร็จเรียบร้อยเราก็กดปุ่ม `Add` ที่ด้านล่างสุดท้ายได้เลย

{% hint style="info" %}
**Default Version**\
เราสามารถเลือกได้ว่าเราจะเอาไฟล์จากการทำ **Continuous Integration (CI)** ในรูปแบบไหน ซึ่งแบบมาตรฐานคือเขาจะเลือกตัวล่าสุดไว้ให้เสมอ ซึ่งในจุดนี้เราสามารถปรับเลือก version ของเราได้เองตามที่ชอบใจเลย (รายละเอียดขอแยกไปไว้บทอื่นนะฮั๊ฟ)
{% endhint %}

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LqlCJpIZqE5XmWmjXDz%2Fimage.png?generation=1583529154975503\&alt=media)

### สั่ง Save การตั้งค่า

ถ้าเราตั้งค่าทุกอย่างจนพอใจแล้ว หรืออยากบันทึกการตั้งค่านี้ไว้แล้วค่อยกลับมาแก้ไขภายในก็สามารถทำได้โดยการกดปุ่ม **`Save`** ที่มุมบนขวาได้เลย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Lpr2CACUMBa4pRGIcWA%2Fimage.png?generation=1583529095230009\&alt=media)

สุดท้ายเขาก็จะให้เรา commit นิดหน่อย ซึ่งจะใส่ comment ว่าเราทำอะไรลงไปเพื่อเตือนความจำตอนที่เราจะย้อน state กลับได้ง่ายๆเอาไว้ก็ดี สุดท้ายก็กด **`OK`** ไปครับ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LoEcbsOkBeTiUyH43uC%2Fimage.png?generation=1583529178290244\&alt=media)

### สั่ง Deploy

เมื่อเราตั้งค่าครบทุกอย่างจนพอใจแล้ว ที่ปุ่มมุมบนขวา `...` เมื่อกดเข้าไปให้เลือก **`Release`** เพื่อให้ระบบทำการเริ่มกระบวนการ Deploy งานไปขึ้นเซิฟเวอร์ได้เลย ตามรูปด้านล่าง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LoBcWOofA3mJWP1r7uq%2Fimage.png?generation=1583529140149511\&alt=media)

คราวนี้เราก็เลือก State ที่เราอยากจะทำการ Release ได้เลย ซึ่งในตัวอย่างเราสร้างไว้ชื่อว่า `State 1` ก็เลือกมันไปแล้วก็กดปุ่ม **`Create`** ได้เลย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LoQVikNBCO0CB85ORxU%2Fimage.png?generation=1583529164889207\&alt=media)

การตั้ง Deploy ของเราก็เสร็จเรียบร้อยแล้วครับ ซึ่งการตั้งค่าตัวนี้จะเป็นการทำ Manual Approve นั่นหมายความว่า ถ้าจะทำการ deploy เราจะต้องมานั่งกด Approve เพื่อสั่งให้มันเริ่ม deploy ลงไปนั่นเอง โดยเราสามารถเข้าไปกด Manual Approve ได้โดยการกดที่ชื่อ Deployment ตามรูปเลย

{% hint style="info" %}
**Manual Approve**\
เป็นมาตรฐานที่ดีสำหรับการ Deploy งานไปยัง Environments ที่ค่อนข้าง sensitive เช่น Production Environment เพราะเราควรจะต้องมีการตรวจสอบงานพวกนี้มาแล้วในระดับหนึ่ง ไม่ใช่เขียนโค้ดเสร็จก็เอาโค้ดตัวนั้นมา deploy เลยนั่นเอง
{% endhint %}

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LvACvgcQo8JSzU6qP4C%2Fimage.png?generation=1583529179073750\&alt=media)

เมื่อกดเข้ามาแล้วเราก็จะเจอปุ่ม Deploy เพื่อเป็นการยืนยันว่าเราจะเอางานไปใช้บนเซิฟเวอร์นั้นจริงๆ ซึ่งในตัวอย่างผมไม่มีอะไรที่ต้องกังวลอยู่แล้วเลยสามารถกด Deploy ได้เลยครับ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LnrDKco1E3RvXQ9anFy%2Fimage.png?generation=1583529168806151\&alt=media)

อย่าลืมกด commit + comment ให้เรียบร้อยด้วย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-M-wDzaUyOcxV7Hv3Izu%2Fimage.png?generation=1583529179441741\&alt=media)

เรียบร้อยครับตอนนี้ก็แค่ไปดื่มกาแฟสักแก้รอมันเอางานขึ้นจนเสร็จนั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LnKWgZgqx_G3TX8MMyQ%2Fimage.png?generation=1583529100715711\&alt=media)

{% hint style="warning" %}
**ทำตามแล้วไม่ได้**\
สำหรับใครที่ทำตามทุกอย่างแล้วมันไม่ผ่านแล้วเขาแจ้งเตือนประมาณด้านล่างนี้ ก็ไม่ต้องตกใจนะครับ วิธีแก้อยู่ในหัวข้อ **แก้ Build Pipeline** ด้านล่างครับ

Error: No package found with specified pattern: D:\a\r1\a\**\\*.zip
{% endhint %}

เรียบร้อยครับเว็บของผมก็พร้อมใช้งานได้ตามปรกติแล้ว เย่

![https://saladpuk-cd.azurewebsites.net](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LnIAcvhDmIV4QpaTcWU%2Fimage.png?generation=1583529179187374\&alt=media)

ถ้าเรากลับไปดูที่ **Build > Summary** ที่เราทำไว้ ก็จะเห็นว่าตัว Build ของเราถูกส่งขึ้นไป Deploy ทั้งหมดกี่ครั้งแล้ว สำหรับหรือล้มเหลวยังไงบ้าง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LpP64QWIa44t4w1qnda%2Fimage.png?generation=1583529154007795\&alt=media)

### แก้ไข Continuous Delivery

เมื่อทำการตั้งค่าทุกอย่างเสร็จแล้ว แต่เราอยากแก้ไขเพิ่มเติมก็สามารถทำได้โดยการกดที่ **Release** เหมือนเดิม

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LtruxzTMMko2kW3FoLP%2Fimage.png?generation=1583529099931666\&alt=media)

แล้วก็เลือกที่ปุ่ม `Edit` ที่ด้านบนขวาเพื่อทำการแก้ไขได้เลยครัช

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LnrR0yg-imBFaF_Z8XD%2Fimage.png?generation=1583529177660040\&alt=media)

## 🔥 แก้ Build Pipeline

สำหรับเพื่อนๆที่ทำตามผมมาตั้งแต่ทำ Continuous Integration (CI) จนถึง Continuous Delivery (CD) ในบทนี้แล้วก็ยังไม่ได้ ก็ไม่ต้องตกใจนะครับ เพราะในตัวอย่างการทำ CI มันจะต้องใส่ขั้นตอนเพิ่มเข้าไปอีกนิดหน่อยเพื่อให้มันทำงานได้ครับ โดยให้เรากลับไปที่ **Pipeline > Build** ครับ (ส่วนสาเหตุจะอธิบายไว้ในขั้นตอนด้านล่างนะจ๊ะ)

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Ln6ACpYxv6SJC_Dsrhs%2Fimage.png?generation=1583529168710041\&alt=media)

แล้วทำการกด **`Edit`** ที่มุมบนขวาได้เลย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-Ln_wVDWGjO_qAyPNd7w%2Fimage.png?generation=1583529159764817\&alt=media)

เราจะเห็นโค้ด .yaml ที่เอาไว้กำหนดขั้นตอนการทำงานต่างๆ ซึ่งภายในนั้นมันจะมีแค่สั่งให้เราใช้คำสั่งมาตรฐานอย่างเดียวเท่านั้น ซึ่งตามปรกติถ้าเราจะเอางานไป deploy เราจะต้องใช้คำสั่งในการ publish เพิ่มเข้าไปด้วย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LpxF9mOaJgi6glW09ab%2Fimage.png?generation=1583529148785846\&alt=media)

ดังนั้นในส่วน steps ที่วงไว้สีแดงๆ เราจะลบมันทิ้งทั้งหมด แล้วลองเขียนใหม่ให้เข้าใจง่ายๆดูนะครับ โดยเอาโค้ดแต่ละขั้นตอนด้านล่างไปค่อยๆวางลงโซนที่เราลบไป ตามขั้นตอนด้านล่างนี้เลย

### 1.สั่ง Restore Packages ต่างๆ

```yaml
- task: DotNetCoreCLI@2
  displayName: Restore
  inputs:
    command: 'restore'
    feedsToUse: 'select'
```

### 2.สั่ง Build projects

```yaml
- task: DotNetCoreCLI@2
  displayName: Build
  inputs:
    command: build
    projects: '**/*.csproj'
    arguments: '--configuration Release'
```

### 3.สั่งรันเทส

```yaml
- task: DotNetCoreCLI@2
  displayName: Test
  inputs:
    command: test
    projects: '**/*Tests/*.csproj'
    arguments: '--configuration $(buildConfiguration)'
```

### 4.สั่ง Publish และสร้างไฟล์

```yaml
- task: DotNetCoreCLI@2
  displayName: Publish
  inputs:
    command: publish
    publishWebProjects: True
    arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: True

# this code takes all the files in $(Build.ArtifactStagingDirectory) and uploads them as an artifact of your build.
- task: PublishBuildArtifacts@1
  inputs:
    pathtoPublish: '$(Build.ArtifactStagingDirectory)' 
    artifactName: 'myWebsiteName'
```

เรียบร้อยละครับ สุดท้ายเราจะได้โค้ดทั้งหมดออกมาหน้าตาประมาณนี้

```yaml
# ASP.NET Core
# Build and test ASP.NET Core projects targeting .NET Core.
# Add steps that run tests, create a NuGet package, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

variables:
  buildConfiguration: 'Release'

steps:
- task: DotNetCoreCLI@2
  displayName: Restore
  inputs:
    command: 'restore'
    feedsToUse: 'select'
- task: DotNetCoreCLI@2
  displayName: Build
  inputs:
    command: build
    projects: '**/*.csproj'
    arguments: '--configuration Release'
- task: DotNetCoreCLI@2
  displayName: Test
  inputs:
    command: test
    projects: '**/*Tests/*.csproj'
    arguments: '--configuration $(buildConfiguration)'
- task: DotNetCoreCLI@2
  displayName: Publish
  inputs:
    command: publish
    publishWebProjects: True
    arguments: '--configuration $(BuildConfiguration) --output $(Build.ArtifactStagingDirectory)'
    zipAfterPublish: True
# this code takes all the files in $(Build.ArtifactStagingDirectory) and uploads them as an artifact of your build.
- task: PublishBuildArtifacts@1
  inputs:
    pathtoPublish: '$(Build.ArtifactStagingDirectory)' 
    artifactName: 'myWebsiteName'
```

ถ้าทุกอย่างพร้อมแล้วก็กดปุ่ม **`Save`** ที่ด้านบนขวาได้เลย

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LpK6eQ2EclmshTzqAVj%2Fimage.png?generation=1583529134935959\&alt=media)

หลังจากนั้นก็กด **`Run`** ตามปรกติครับ

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-M-_Wvu4ijGG5nzg2UiG%2Fimage.png?generation=1583529171338654\&alt=media)

ขั้นตอนจะเพิ่มขึ้นมาหน่อยนึง แต่ถ้าอ่านแล้วก็จะเข้าใจได้ว่ามันทำอะไร เมื่อมองกลับไปที่ไฟล์ .yaml นั่นเอง

![](https://479516123-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Lm0_idNbY6k1lwp6hm4%2F-M1lfqlFTvI3gmheTI_q%2F-LqvvQn-GVUca_-FdLOg%2Fimage.png?generation=1583529158460341\&alt=media)

{% hint style="info" %}
**แนะนำให้อ่าน**\
สำหรับรายละเอียดการสร้าง yaml เพื่อทำ run steps นั้นสามารถอ่านได้จากลิงค์หลักของ Microsoft ได้เลย ส่วนถ้าเพื่อนๆใช้ภาษาอื่นในการเขียนเว็บก็สามารถเลือกภาษาที่ตัวเองใช้ได้จากเมนูด้านซ้ายมือเลย\
[Microsoft document - Build, test, and deploy .NET Core apps](https://docs.microsoft.com/en-us/azure/devops/pipelines/ecosystems/dotnet-core?view=azure-devops)
{% endhint %}

หลังจากที่ได้ลอง **CI/CD** ไปเรียบร้อยแล้ว คราวนี้ในเรื่องของการวางแผนงานต่างๆเช่น Product Backlog หรืองานในแต่ละ **Iteration/Sprint** ใครจะต้องทำอะไรยังไงบ้าง ดังนั้นกด **`Next`** เพื่อไปดูเรื่อง **Kanban Board** กันเลยครัช
