คำแนะนำเชิงลึกสำหรับการสร้างไปป์ไลน์ PowerShell ใน Azure DevOps
คุณรู้ไหมว่าคุณสามารถเรียกใช้สคริปต์เช่น PowerShell ในไปป์ไลน์ Azure DevOps (AzDo) เพื่อสร้างไปป์ไลน์ PowerShell ได้ การใช้เคล็ดลับและเทคนิคที่คุณจะได้เรียนรู้ในบทความนี้ จะช่วยให้คุณเขียนสคริปต์ไปสู่ความยิ่งใหญ่ของระบบอัตโนมัติได้เป็นอย่างดี
หากคุณกำลังสร้างไปป์ไลน์ด้วย Azure Pipelines คุณจะคุ้นเคยกับงานต่างๆ งานคือองค์ประกอบสำคัญของไปป์ไลน์ Azure DevOps (AzDo) AzDo มีงานในตัวมากมายและยังให้คุณดาวน์โหลดงานอื่น ๆ ผ่านส่วนขยายในตลาดส่วนขยายได้ แต่คงถึงเวลาที่คุณต้องดำเนินการบางอย่างที่ไม่มีงานทำอย่างหลีกเลี่ยงไม่ได้
ถึงเวลาแยกสคริปต์แล้ว
AzDo สามารถรันสคริปต์ได้สามประเภท - PowerShell, Bash และไฟล์แบตช์ การใช้ภาษา/เทคนิคการเขียนสคริปต์เหล่านี้ตั้งแต่หนึ่งภาษาขึ้นไป จะทำให้คุณทำทุกอย่างได้สำเร็จ
ในบทช่วยสอนเชิงลึกนี้ คุณจะได้เรียนรู้วิธีการทำงานของสคริปต์ PowerShell ในไปป์ไลน์ AzDo ที่สร้างไปป์ไลน์ PowerShell คุณจะได้เรียนรู้ทั้งหมดเกี่ยวกับวิธีการเรียกใช้โค้ด สคริปต์ที่บันทึกไว้ในคลังควบคุมแหล่งที่มาของคุณ และวิธีการทำงานกับตัวแปรไปป์ไลน์ในสคริปต์
สคริปต์ทำงานอย่างไรใน AzDo Pipelines
ภายในไปป์ไลน์ AzDo แต่ละอันจะมีชุดงานต่างๆ งานถูกกำหนดให้เป็นขั้นตอน งานเหล่านี้แสดงถึงการดำเนินการเฉพาะ เช่น การรันบิลด์ .NET, การปรับใช้เว็บแอปพลิเคชัน, การรันการทดสอบ ฯลฯ งานคือองค์ประกอบหลักสำหรับไปป์ไลน์
AzDo ใช้แนวคิดของงานเพื่อเรียกใช้สคริปต์หรือโค้ดที่มีอยู่ในไปป์ไลน์ YAML โดยเฉพาะอย่างยิ่ง งานสามารถเรียกใช้สคริปต์ PowerShell, Bash หรือแบตช์ไฟล์บนเอเจนต์ไปป์ไลน์ เช่น Windows, Linux และ macOS เมื่อเรียกใช้งาน คุณสามารถระบุเอเจนต์ (OS) ที่จะรันสคริปต์และพารามิเตอร์ใดๆ ที่โค้ด/สคริปต์มี
คุณสามารถหางานสคริปต์ PowerShell หรือ Bash ได้ในตัวเลือกงานในอินเทอร์เฟซบนเว็บ เช่นเดียวกับงานอื่นๆ
คุณสามารถรันงาน PowerShell บน Windows ด้วย Windows PowerShell, Linux และ macOS ด้วย PowerShell (Core)
งานเขียนสคริปต์แต่ละงานถูกกำหนดให้เป็นขั้นตอนในไปป์ไลน์ และคุณมีหลายวิธีในการมอบหมายงานเพื่อรันสคริปต์ เช่น การส่งพารามิเตอร์ การล้มเหลวเนื่องจากข้อผิดพลาด การรับโค้ดทางออกสุดท้าย และอื่นๆ คุณจะได้เรียนรู้โดยละเอียดเกี่ยวกับวิธีสร้างงานเหล่านี้ในส่วนต่อไปนี้
แนวคิดสำคัญอีกประการหนึ่งในการเรียนรู้คือวิธีที่ตัวแปรไปป์ไลน์ผสานรวมกับสคริปต์ คุณยังคงสามารถกำหนดและจัดการ “ตัวแปรสคริปต์” เช่น $var=123 ใน PowerShell และรักษาตัวแปรสภาพแวดล้อมโดยไม่ต้องเกี่ยวข้องกับ AzDo อย่างไรก็ตาม AzDo ช่วยให้คุณสามารถตั้งค่าและอ้างอิงตัวแปรไปป์ไลน์ในสคริปต์ได้เช่นกัน
รหัสอินไลน์กับสคริปต์
ตลอดบทความนี้ คุณจะเห็นการอ้างอิงถึงการเรียกใช้ “สคริปต์ ” แม้ว่าจะแม่นยำ แต่ก็ดูเหมือนว่าคุณต้องสร้างไฟล์ข้อความของคุณเอง ใส่โค้ดที่คุณต้องการดำเนินการ จากนั้นไปป์ไลน์เท่านั้นที่จะเรียกใช้สคริปต์นั้น ที่ไม่เป็นความจริง.
คุณยังสามารถเรียกใช้ โค้ดอินไลน์ ได้อีกด้วย โค้ดอินไลน์ทำงานโดยตรงในไปป์ไลน์ YAML คุณไม่จำเป็นต้องสร้างสคริปต์ล่วงหน้าเพื่อเรียกใช้โค้ด PowerShell หรือ Bash คุณสามารถแทรกโค้ดโดยตรงใน YAML แทนได้ ไม่มีการอ้างอิงถึงไฟล์ PS1 AzDo สร้างสคริปต์ชั่วคราวเมื่อไปป์ไลน์ทำงาน
หนึ่งบรรทัด
คุณสามารถเรียกใช้โค้ดอินไลน์ได้ 1 ใน 2 วิธีในไปป์ไลน์ผ่านบรรทัดเดียวหรือหลายบรรทัด หากคุณมีข้อมูลโค้ดแบบสั้นเป็นบรรทัดเดียว คุณสามารถระบุประเภทงานตามด้วยโค้ดในเครื่องหมายคำพูดได้ ดังที่แสดงด้านล่าง
- powershell: "I'm running PowerShell on a pipeline agent. Woohoo!!"รหัสหลายบรรทัด
หากคุณมีข้อมูลโค้ดที่มีความยาวไม่กี่บรรทัดหรือบางทีคุณอาจไม่ต้องการใช้เครื่องหมายคำพูด คุณสามารถกำหนดข้อมูลโค้ดแบบหลายบรรทัดได้โดยใช้สัญลักษณ์ไปป์ (|) ตามด้วยสัญลักษณ์หนึ่งหรือ มีบรรทัดเพิ่มเติมด้านล่างดังที่แสดงด้านล่าง
- powershell: |
This is script line 1
This is script line 2โดยทั่วไป วิธีที่ดีที่สุดคือใช้โค้ดอินไลน์สำหรับงานเล็กๆ ที่มีบรรทัดน้อยกว่าห้าบรรทัดเท่านั้น งานอื่นๆ ที่ต้องการมากกว่านั้นน่าจะอยู่ในสคริปต์ในพื้นที่เก็บข้อมูลการควบคุมต้นทางของคุณ
ข้อดีของการใช้โค้ดแบบอินไลน์คือการรวมฟังก์ชันทั้งหมดไว้ในที่เดียว ทำให้ง่ายต่อการดูทุกสิ่งที่เกิดขึ้น แต่แนวทางนี้อาจทำให้เกิดความสับสนได้หากคุณมีไปป์ไลน์ขนาดใหญ่
จะเก็บสคริปต์ของคุณไว้ที่ไหน
หากคุณไม่ได้ใช้งานโค้ดอินไลน์เพื่อเรียกใช้สคริปต์ คุณจะต้องบันทึกสคริปต์ไว้ที่ใดที่หนึ่ง คุณมีทางเลือกไม่กี่ทางที่จะจัดเก็บสคริปต์ที่ดำเนินการผ่านไปป์ไลน์
พื้นที่เก็บข้อมูลการควบคุมแหล่งที่มา
หากคุณใช้ทริกเกอร์ไปป์ไลน์จากพื้นที่เก็บข้อมูลควบคุมแหล่งที่มา GitHub หรือ AzDo ที่ใช้งานไปป์ไลน์ CI ให้ลองจัดเก็บสคริปต์ของคุณใน Repo เดียวกัน ง่ายกว่าในการจัดการไฟล์ทั้งหมดที่เกี่ยวข้องกับโปรเจ็กต์ด้วยวิธีนี้ ตามค่าเริ่มต้น AzDo จะตรวจสอบโค้ดทั้งหมดใน repo แหล่งที่มา การตรวจสอบโค้ดจะดาวน์โหลดไฟล์ทั้งหมดจาก repo ไปยังเอเจนต์ไปป์ไลน์ ทำให้พร้อมสำหรับการดำเนินการได้ทันที
หากคุณมีสคริปต์อยู่ใน repo GitHub อื่น คุณสามารถตรวจสอบ repos หลายรายการเพื่อดาวน์โหลดและเรียกใช้สคริปต์ที่จัดเก็บไว้ใน repos อื่นได้เช่นกัน
เมื่อดาวน์โหลดสคริปต์ไปยัง Pipeline Agent แล้ว คุณสามารถอ้างอิงสคริปต์เหล่านั้นในงานผ่านตัวแปร [System.DefaultWorkingDirectory ที่กำหนดไว้ล่วงหน้าได้
ตัวอย่างเช่น หากคุณมีสคริปต์ PowerShell ชื่อ script.ps1 เก็บไว้ในรูทของ repo ต้นทางของคุณ AzDo จะตรวจสอบไฟล์ที่วางไว้ในโฟลเดอร์ System.DefaultWorkingDirectory เส้นทาง. จากนั้นสามารถอ้างอิงได้โดยใช้งาน PowerShell ดังที่แสดงด้านล่าง
- task: PowerShell@2
inputs:
filePath: "$(System.DefaultWorkingDirectory)\script.ps1"ที่อื่น
หากสคริปต์ไม่ได้อยู่ใน repo การควบคุมแหล่งที่มา คุณยังคงสามารถเรียกใช้สคริปต์ในไปป์ไลน์ได้ อย่างไรก็ตาม วิธีที่คุณทำเช่นนี้นั้นขึ้นอยู่กับสถานการณ์เป็นอย่างมาก ตัวอย่างเช่น คุณสามารถใช้งาน PowerShell เพื่อดาวน์โหลดสคริปต์อื่นและเรียกใช้งานได้
steps:
- powershell: |
Invoke-WebRequest -Uri <https://somesite.com/script.ps1> -OutFile script.ps1
.\script.ps1ไม่สำคัญว่าสคริปต์จะถูกเก็บไว้ที่ไหน ตราบใดที่คุณสามารถใช้งานหรือเรียกใช้สคริปต์เพื่อตรวจสอบสิทธิ์ (หากจำเป็น) และดาวน์โหลดสคริปต์ งาน PowerShell จะเรียกใช้งานให้คุณ
ตัวแปรไปป์ไลน์ในไปป์ไลน์ PowerShell CI/CD
เช่นเดียวกับที่คุณมีตัวแปรในสคริปต์ คุณก็มีตัวแปรในไปป์ไลน์ด้วย ตัวแปรถูกกำหนดด้วยวิธีที่แตกต่างกันสองสามวิธี และค่าของตัวแปรนั้นสามารถเข้าถึงได้แตกต่างกันไปขึ้นอยู่กับบริบท
ไม่เพียงแต่คุณสามารถกำหนดและอ่านค่าตัวแปรในไปป์ไลน์ YAML เท่านั้น คุณยังสามารถดำเนินการภายในสคริปต์ได้อีกด้วย
การอ่านตัวแปรไปป์ไลน์
เมื่อสคริปต์ทำงานผ่านไปป์ไลน์ ไปป์ไลน์จะแสดงตัวแปรที่กำหนดไว้ในปัจจุบันทั้งหมดเป็นตัวแปรสภาพแวดล้อมในเอเจนต์ไปป์ไลน์แต่ละตัว ซึ่งหมายความว่าคุณสามารถอ่านตัวแปรไปป์ไลน์ในสคริปต์ได้เช่นเดียวกับตัวแปรสภาพแวดล้อมอื่นๆ
ตัวอย่างเช่น คุณอาจกำหนดตัวแปรชื่อ foo ไว้ใต้ส่วน variables ของไปป์ไลน์
variables:
- name: foo
value: 'bar'เนื่องจากไปป์ไลน์เปิดเผยตัวแปรนี้เป็นตัวแปรสภาพแวดล้อม คุณจึงสามารถอ้างอิงค่าของตัวแปรนั้นในสคริปต์ของคุณได้เหมือนปกติ เช่น <รหัส>$env:foo.
สำหรับตัวแปรไปป์ไลน์ที่กำหนดด้วยจุด (
.) AzDo จะแปลงจุดเหล่านี้เป็นขีดล่างเป็นตัวแปรสภาพแวดล้อมโดยอัตโนมัติ ตัวอย่างเช่น หากตัวแปรไปป์ไลน์ถูกกำหนดเป็นfoo.barตัวแปรสภาพแวดล้อมจะเป็นfoo_bar
การตั้งค่าตัวแปรไปป์ไลน์
การตั้งค่าตัวแปรไปป์ไลน์ไม่ได้ค่อนข้างตรงไปตรงมาเหมือนกับการอ่าน หากต้องการตั้งค่าตัวแปรไปป์ไลน์ผ่านสคริปต์ คุณต้องใช้คำสั่งการบันทึก คำสั่งการบันทึกคือวิธีที่สคริปต์สื่อสารกับตัวแทนไปป์ไลน์
หากต้องการตั้งค่าตัวแปรไปป์ไลน์ผ่านสคริปต์ คุณต้องส่งออกสตริงที่จัดทำขึ้นเป็นพิเศษให้เป็นมาตรฐานในสคริปต์ สตริงต้องมีรูปแบบของ "##vso[task.setvariable Variable=[variable_name];][variable_value]"
ตัวอย่างเช่น หากต้องการตั้งค่าตัวแปรไปป์ไลน์ foo เป็นค่า bar สคริปต์ PowerShell หรือ Bash จะต้องส่งออกสตริงตามด้านล่าง
echo "##vso[task.setvariable variable=foo;]bar"ส่วนขยายสคริปต์ที่กำหนดเอง
AzDo จัดเตรียมงานสคริปต์ PowerShell และ Bash ตามค่าเริ่มต้น แต่คุณยังสามารถดาวน์โหลดหรือสร้างงานตามสคริปต์ของคุณเองในรูปแบบของส่วนขยายที่ทำให้ไปป์ไลน์ PowerShell CI/CD ของคุณสามารถปรับแต่งได้
เมื่อใช้งานสคริปต์มาตรฐาน คุณจะเขียนโค้ดทั้งหมดด้วยตัวเองและเรียกใช้งานได้ในช็อตเดียว ไม่มี "อินเทอร์เฟซ" ที่แท้จริงในโค้ด AzDo ให้กล่องข้อความว่า "ใส่โค้ดที่นี่" คุณใส่โค้ด จากนั้นไปป์ไลน์จะดำเนินการ ไม่มีโครงสร้างที่แท้จริงอยู่รอบๆ
สังเกตว่าเมื่อคุณสร้างงาน PowerShell ด้านล่าง คุณไม่มีตัวเลือกมากมาย พารามิเตอร์สำหรับงานนี้มีจำนวนน้อยที่สุด มีช่อง Arguments สำหรับส่งพารามิเตอร์ไปยังสคริปต์ แต่จะเข้าใจง่ายกว่านี้ไหมถ้า Arguments ไม่ใช่ชื่อทั่วไป
บางทีคุณอาจมีสคริปต์ที่คุณใช้เป็นประจำในการสืบค้นชุดเครื่องและส่งรายงานบางส่วนกลับ สคริปต์ชื่อ Get-AcmeServerReport มีพารามิเตอร์เช่น ServerName เพื่อระบุเซิร์ฟเวอร์ที่จะรันและ ReportFilePath สำหรับตำแหน่งที่จะบันทึกรายงาน
หากไม่มีฟิลด์ใน UI ของเว็บที่ตรงกับพารามิเตอร์สคริปต์จะใช้งานง่ายกว่าอย่างที่คุณเห็นด้านล่างใช่ไหม
บทความนี้จะไม่ครอบคลุมถึงการสร้างส่วนขยาย AzDo แบบกำหนดเอง แต่คุณควรรู้ว่าสิ่งนี้เป็นไปได้ คุณสามารถย้าย “อินเทอร์เฟซ” ขึ้นไปที่ระดับไปป์ไลน์แทนที่จะเลื่อนลงที่ระดับสคริปต์ ทำให้คุณสามารถนำสคริปต์ที่มีอยู่กลับมาใช้ใหม่ได้อย่างง่ายดาย
การสร้างไปป์ไลน์ PowerShell
พูดพอแล้ว. ตอนนี้เรามาสร้างตัวอย่างไปป์ไลน์ AzDo PowerShell กันดีกว่า!
ก่อนคุณเริ่ม
บทความนี้จะเป็นการผสมผสานระหว่างการสอนและการสอนแบบลงมือปฏิบัติจริง หากคุณตั้งใจจะลองใช้ตัวอย่างใดๆ ด้วยตนเอง โปรดแน่ใจว่าได้ตั้งค่าข้อกำหนดเบื้องต้นบางประการไว้ล่วงหน้า
- ไปป์ไลน์ AzDo ที่มีอยู่ซึ่งสร้างขึ้นโดยเชื่อมโยงกับ repo - เรียนรู้วิธีสร้างไปป์ไลน์ผ่านอินเทอร์เฟซเว็บหรือใช้ Az CLI ในบทความ Azure Pipelines นี้
สิ่งที่คุณจะได้เรียนรู้
ในบทช่วยสอนแบบลงมือปฏิบัติจริงนี้ คุณจะได้เรียนรู้ทุกสิ่งที่ควรรู้เกี่ยวกับการเรียกใช้สคริปต์ PowerShell และ Bash ใน AzDo Pipelines เมื่อใช้งาน PowerShell และ Bash คุณจะเห็นวิธีเรียกใช้สคริปต์ ส่งพารามิเตอร์ไปยังสคริปต์เหล่านั้น ควบคุมข้อผิดพลาด และวิธีทำให้งานล้มเหลวในไปป์ไลน์หากเกิดปัญหาในสคริปต์
คุณยังจะได้เรียนรู้วิธีใช้ตัวแปรไปป์ไลน์ AzDo ในสคริปต์ และวิธีการตั้งค่าโดยใช้คำสั่งการบันทึก AzDo
งาน PowerShell คือเพื่อนของคุณ
หากต้องการเรียกใช้สคริปต์ PowerShell ในไปป์ไลน์จำเป็นต้องใช้งาน PowerShell งาน PowerShell รับสคริปต์หรือรหัส PowerShell จากไปป์ไลน์และรันบนตัวแทนไปป์ไลน์ ไปป์ไลน์เอเจนต์จะอยู่บน Windows หรือ Linux ขึ้นอยู่กับตัวเลือกที่เลือก
คุณยังสามารถใช้งานกรณีการใช้งานที่เฉพาะเจาะจงมากขึ้น เช่น งาน Azure PowerShell ได้เช่นกัน แต่งานเหล่านั้นจะไม่ครอบคลุมอยู่ที่นี่
สคีมางาน PowerShell
งาน PowerShell เรียกว่า PowerShell@2 และมีสคีมาที่มีลักษณะดังนี้ คุณจะเห็นว่ามีตัวเลือกต่างๆ มากมายสำหรับการเรียกใช้สคริปต์ภายใต้ส่วน inputs
- task: PowerShell@2
inputs:
targetType:
filePath:
arguments:
script:
errorActionPreference:
failOnStderr: true
ignoreLASTEXITCODE: true
pwsh: true
workingDirectory: แต่ละแอตทริบิวต์ที่คุณตัดสินใจใช้ใน อินพุต จะส่งผลต่อลักษณะการทำงานของโค้ด/สคริปต์ PowerShell
| Name | Mandatory | Options | Used with | Default Value | Description |
| targetType | No | filePath, inline | All | The PowerShell task allows you to add PowerShell code directly within the YAML pipeline or execute an existing script in the source repo. Here you can specify either filePath providing the path to the script to run or use inline which indicates that you’ll be adding the PowerShell code directly int the YAML pipeline. | |
| filePath | Yes | targetType: filePath | This attribute is where you specify the path of the script to execute. This path typically points to a script in your source repo that the pipeline checks out when it runs. For example, to tell the PowerShell task to execute a script called script.ps1 in the root of the source repo, you’d use a predefined variable like $(System.DefaultWorkingDirectory)\\script.ps1. | ||
| arguments | No | targetType: filePath | If you’ve provided a script via the filePath attribute and that script is built with parameters, this is where you would pass in values to those parameters. Note that when using inline code, this option is not used. You should specify named parameters like `-Name someName -Path -Value “some value”` | ||
| script | Yes | inline | Enclosed in quotes, this is where you provide the PowerShell code to execute. | ||
| errorActionPreference | No | SilentlyContinue, Continue, Inquire, Stop | All | Stop | Use this to set $ErrorActionPreference in the script if you haven’t done so already. |
| failOnStderr | No | true | All | false | Setting this value to true will fail the PowerShell task in the pipeline is an error is thrown via PowerShell. Otherwise, the task will only fail if the scripts exits with a non-zero exit code. |
| ignoreLASTEXITCODE | No | true | All | false | If set to false, the line `if ((Test-Path -LiteralPath variable:"\LASTEXITCODE)) { exit $LASTEXITCODE }` is appended to the end of the script. This will cause the last exit code from an external command to be propagated as the exit code of PowerShell. |
| pwsh | No | true | All | false | If the pipeline agent is running on Windows, this will force the code/script to be executed using pwsh.exe (PowerShell Core). If not set to true, the task will default to Windows PowerShell on Windows pipeline agents. |
| workingDirectory | No | All | $(Build.SourcesDirectory) | The working directory to execute the script in. This affects paths in the script like _.\\command.ps1_. | |
| env | No | All | A list of additional items to map into the process’s environment. By default, pipeline variables are mapped but secret variables are not. Here is where you would specify them like `MySecret: $(Foo)`. |
เมื่อคุณมีแนวคิดเกี่ยวกับสิ่งที่เป็นไปได้แล้ว เรามาเจาะลึกแต่ละคุณลักษณะและดูว่าอะไรเป็นไปได้บ้าง
วิ่งแบบ One-Liners ง่ายๆ
ในรูปแบบที่ง่ายที่สุดของงาน PowerShell คุณสามารถเรียกใช้ PowerShell บรรทัดเดียวได้โดยใช้ targetType เป็น inline และโดยการระบุรหัสที่จะเรียกใช้ผ่าน script รหัส> แอตทริบิวต์ที่แสดงด้านล่าง
- task: PowerShell@2
inputs:
targetType: 'inline'
script: 'Write-Host "This is me running PowerShell code!"'เมื่อไปป์ไลน์ทำงาน คุณจะเห็นเอาต์พุตที่แสดงในบันทึก
หากคุณต้องการใช้ทางลัดสำหรับวิธีนี้ คุณสามารถประหยัดเวลาได้สองสามบรรทัด แต่ใช้งานทางลัด powershell ที่ไม่บังคับก็ได้เช่นกัน
หากต้องการใช้ฟังก์ชันเดียวกันกับข้างต้น คุณสามารถใช้คำว่า powershell ตามด้วยโค้ดเพื่อเรียกใช้ตามที่แสดงด้านล่าง
- powershell: 'Write-Host "This is me running PowerShell code!"'หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการเรียกใช้โค้ด PowerShell แบบอินไลน์ โปรดดูส่วนโค้ดและสคริปต์ของบทความแรกในชุดนี้
Sidenote: Windows PowerShell กับ PowerShell (Core)
ก่อนที่คุณจะไปไกลกว่านี้ สิ่งสำคัญคือต้องชี้ให้เห็นความแตกต่างด้านพฤติกรรมบางอย่างใน Windows PowerShell และ PowerShell (Core) และวิธีการควบคุมเวอร์ชันของ PowerShell ที่สคริปต์ของคุณทำงาน
ในตัวอย่างด้านบน เวอร์ชันของ PowerShell ที่เรียกใช้โค้ดโดยสมบูรณ์จะขึ้นอยู่กับเอเจนต์ไปป์ไลน์ที่โค้ดกำลังทำงานอยู่ ไปป์ไลน์ฉลาดพอที่จะจัดการสิ่งนี้ให้กับคุณ แต่คุณจะโดนจับได้เมื่อถึงจุดหนึ่ง
ตัวอย่างเช่น จะเกิดอะไรขึ้นถ้าคุณมีรหัสเฉพาะ Windows PowerShell และใช้งาน powershell โดยสมมติว่าจะทำงานบน Windows อาจ แต่จะเกิดอะไรขึ้นถ้าคุณมีไปป์ไลน์ขนาดใหญ่ที่กำหนดไว้และคุณลืมว่าคุณเพิ่มบรรทัด pool: ubunbu-latest สำหรับงานนั้น งานจะยังคงทำงานบน Linux แต่ไม่มีทางเลือกอื่นนอกจากเรียกใช้ PowerShell (Core)
ใช้งานด้านบนเป็นตัวอย่าง สมมติว่าคุณได้กำหนดเอเจนต์ไปป์ไลน์ให้ทำงานบน Linux โดยเฉพาะเหมือนด้านล่าง งานจะเหมือนกันทุกประการ แต่ตัวแทนไปป์ไลน์ไม่เหมือนกัน
pool:
vmImage: "ubuntu-latest"
steps:
- task: PowerShell@2
inputs:
targetType: 'inline'
script: 'Write-Host "This is me running PowerShell code!'
- powershell: 'Write-Host "This is me running PowerShell code!"'จากนั้นคุณจะเห็นในบันทึกงาน โดยไปป์ไลน์จะเลือก pwsh โดยอัตโนมัติ คุณจะเห็นสิ่งเดียวกันนี้ใน Windows โดยที่ไปป์ไลน์ดำเนินการ powershell.exe
มีความชัดเจนเกี่ยวกับเวอร์ชัน PowerShell
หากมีโอกาสที่คุณกำลังเรียกใช้โค้ดที่ขึ้นอยู่กับเวอร์ชันของ PowerShell โปรดระบุเวอร์ชันที่คุณต้องการใช้งานให้ชัดเจนเสมอ
หากต้องการเรียกใช้ PowerShell (Core) ให้ใช้แอตทริบิวต์ pwsh: true ในงาน PowerShell@2 หรืองานทางลัด pwsh เสมอ อย่าคิดว่าไปป์ไลน์จะเลือกเวอร์ชันที่เหมาะสมสำหรับคุณ คุณอาจไม่เคยจำได้ว่าคุณได้ "เปลี่ยนแปลงอย่างรวดเร็วเพื่อแก้ไขปัญหา" โดยการเปลี่ยนตัวแทนไปป์ไลน์ก่อนที่จะสายเกินไป
- task: PowerShell@2
inputs:
targetType: 'inline'
script: 'Write-Host "This is me running PowerShell code!'
pwsh: true
- pwsh: 'Write-Host "This is me running PowerShell code!"'การรันสคริปต์
หากคุณต้องการรันโค้ด PowerShell เกินสองสามบรรทัด หรือต้องการส่งพารามิเตอร์ไปยังโค้ดของคุณ คุณจะต้องก้าวไปสู่การรันสคริปต์ เมื่อใช้งาน PowerShell คุณสามารถทำได้โดยตั้งค่า targetType เป็น filePath จากนั้นระบุเส้นทางของสคริปต์ที่จะเรียกใช้ผ่านแอตทริบิวต์ filePath .
ตัวอย่างเช่น บางทีคุณอาจมีสคริปต์ PowerShell ชื่อ script_no_params.ps1 ในรากของ repo แหล่งที่มาของคุณ ด้านล่างนี้ คุณสามารถดูตัวอย่างการเรียกสคริปต์ script.ps1 ที่อยู่ในเส้นทางตัวแปรไปป์ไลน์ System.DefaultWorkingDirectory นี่คือไดเร็กทอรีที่ดาวน์โหลดไฟล์ repo ต้นทางเมื่อไปป์ไลน์ทำงาน
- task: PowerShell@2
inputs:
targetType: 'filePath'
filePath: '$(System.DefaultWorkingDirectory)\script_no_params.ps1'ระวังความไม่สอดคล้องกันของการส่งต่อและแบ็กสแลช! หากคุณใช้งานสคริปต์บน Linux ให้ใช้เครื่องหมายทับ บน Windows ให้ใช้แบ็กสแลชเมื่อระบุ
filePath
สคริปต์มีบรรทัดเดียว
[CmdletBinding()]
param()
Write-Host "I'm running in a PowerShell script!!"
เมื่อไปป์ไลน์ทำงาน คุณจะเห็นว่าไปป์ไลน์อ่านโค้ดภายในสคริปต์ สร้างสคริปต์ PowerShell ของตัวเอง จากนั้นจึงรันโค้ด
หากคุณต้องการเรียกใช้สคริปต์ PowerShell ที่มีอยู่ ตรวจสอบให้แน่ใจว่าคุณไม่มีบรรทัด
- checkout: noneในไปป์ไลน์ของคุณ มิฉะนั้น สคริปต์จะไม่ถูกดาวน์โหลดไปยังตัวแทน
การส่งผ่านพารามิเตอร์
หากคุณมีสคริปต์ที่มีพารามิเตอร์ตั้งแต่หนึ่งตัวขึ้นไป คุณสามารถส่งพารามิเตอร์ไปยังสคริปต์เหล่านั้นได้โดยใช้แอตทริบิวต์ arguments
โปรดทราบว่าคุณไม่สามารถส่งพารามิเตอร์ไปยังโค้ดอินไลน์โดยใช้แอตทริบิวต์
อาร์กิวเมนต์ได้
แอตทริบิวต์ อาร์กิวเมนต์ ยอมรับพารามิเตอร์ในลักษณะเดียวกับที่คุณระบุพารามิเตอร์ที่มีชื่อภายใน PowerShell โดยใช้ -[parameter_name] [parameter_value]
ตัวอย่างเช่น บางทีคุณอาจมีสคริปต์ชื่อ script.ps1 อยู่ในรูทของแหล่งซื้อคืนของคุณ สคริปต์นั้นประกอบด้วยพารามิเตอร์สองตัวที่เรียกว่า $foo และ $bar ดังที่แสดงด้านล่าง
[CmdletBinding()]
param(
$foo,
$bar
)
Write-Host "Value of foo is $foo and value of bar is $bar"คุณสามารถระบุค่าให้กับพารามิเตอร์ $foo และ $bar ผ่านทางแอตทริบิวต์ arguments ในไปป์ไลน์ YAML เหมือนด้านล่าง
- task: PowerShell@2
inputs:
targetType: 'filePath'
filePath: '$(System.DefaultWorkingDirectory)/script.ps1'
arguments: "-foo 'foovalue' -bar 'barvalue'"จากนั้นคุณจะเห็นค่าที่ถูกส่งผ่านไปยังสคริปต์ในบันทึกผลลัพธ์ของงาน
แจ้งข้อผิดพลาดและคำเตือน
เมื่อ PowerShell ถูกเรียกใช้ผ่านไปป์ไลน์และส่งกลับข้อผิดพลาดหรือคำเตือน ลักษณะการทำงานของไปป์ไลน์จะขึ้นอยู่กับวิธีที่คุณกำหนดค่าเป็นอย่างมาก สคริปต์ PowerShell สามารถ “เกิดข้อผิดพลาด” ได้หลายวิธี เช่น ข้อผิดพลาดการยกเลิกแบบนุ่มนวล ข้อผิดพลาดที่สิ้นสุดยาก และการออกด้วยรหัสทางออกที่ไม่เป็นศูนย์ อย่าลืมสตรีมคำเตือนนั้นด้วย!
ข้อผิดพลาด
เมื่องาน PowerShell พบข้อผิดพลาด งานในไปป์ไลน์อาจจะใช่หรือไม่ก็ได้ หากคุณมีสคริปต์ที่อาจส่งคืนข้อผิดพลาดแต่ไม่ได้ร้ายแรงพอที่จะทำให้งานไปป์ไลน์ทั้งหมดล้มเหลว คุณสามารถจัดการลักษณะการทำงานนี้ได้โดยใช้แอตทริบิวต์ errorActionPreference
ตามค่าเริ่มต้น ไปป์ไลน์จะตั้งค่าสคริปต์ PowerShell ทั้งหมดเป็นค่า $ErrorActionPreference เป็น Stop ซึ่งหมายความว่าข้อผิดพลาดแบบ soft และการยกเลิกแบบถาวรทั้งหมดจะบังคับให้ PowerShell ส่งคืนโค้ดทางออกที่ไม่เป็นศูนย์ ซึ่งจะทำให้งานไปป์ไลน์ล้มเหลว
เพื่อสาธิต บางทีคุณอาจมีสคริปต์ที่ส่งคืนข้อผิดพลาดที่สิ้นสุดอย่างนุ่มนวล เช่น Write-Error ส่งกลับ หรือข้อผิดพลาดที่สิ้นสุดอย่างถาวร เช่น throw ทำ
## Soft
Write-Error -Message 'This is a soft-terminating error'
## Hard
throw 'This is a hard-terminating error'เมื่อไปป์ไลน์พบสคริปต์นี้ งานจะล้มเหลวเนื่องจาก PowerShell ไม่ได้ส่งคืนโค้ดทางออกที่เป็นศูนย์ดังที่คุณเห็นด้านล่าง
แม้ว่าจะไม่แนะนำ แต่หากคุณต้องการให้สคริปต์ล้มเหลวแต่ไม่ทำให้งานไปป์ไลน์ล้มเหลว คุณสามารถทำได้โดยการตั้งค่าแอตทริบิวต์ errorActionPreference เป็น SilentyContinue
- task: PowerShell@2
inputs:
targetType: 'filePath'
filePath: '$(System.DefaultWorkingDirectory)/script.ps1'
errorActionPreference: SilentlyContinueการปรับเปลี่ยนพฤติกรรมของรหัสทางออก
ตามค่าเริ่มต้น งาน PowerShell จะล้มเหลวถ้า PowerShell ส่งกลับรหัสทางออกที่ไม่ใช่ศูนย์ คุณเห็นตัวอย่างข้างต้นแล้ว อย่างไรก็ตาม หากคุณต้องการปรับเปลี่ยนพฤติกรรมดังกล่าว คุณสามารถทำได้โดยใช้แอตทริบิวต์ ignoreLASTEXITCODE
เมื่อใดก็ตามที่สคริปต์ PowerShell เปลี่ยน สคริปต์จะเติมตัวแปรชื่อ $LASTEXITCODE เสมอ รหัสทางออกนี้บังเอิญส่งคืนรหัสทางออกสุดท้ายที่สคริปต์ PowerShell ส่งกลับ นี่คือสิ่งที่งานไปป์ไลน์อ่านเพื่อบ่งชี้ความสำเร็จหรือความล้มเหลว
บางทีคุณอาจมีสถานการณ์ที่คำสั่งที่คุณเรียกใช้ภายในสคริปต์ส่งคืนโค้ดทางออกที่ไม่ใช่ศูนย์ แต่คุณ รู้ ว่ามันประสบความสำเร็จอยู่ดี อย่าให้ฉันเริ่มต้นกับโปรแกรมติดตั้งซอฟต์แวร์! หากคุณต้องการให้งานไปป์ไลน์สำเร็จ คุณสามารถบังคับใช้รหัสทางออกของคุณเองได้
สมมติว่าคุณมีสคริปต์ชื่อ script.ps1 เหมือนด้านล่างที่แก้ไขโค้ดทางออกที่สคริปต์ PowerShell จะหยุดทำงาน ในตัวอย่างด้านล่าง บางทีคำสั่งอาจส่งคืนโค้ดทางออกที่เป็นศูนย์ซึ่งโดยทั่วไปจะบ่งชี้ถึงความสำเร็จ แต่คุณรู้ว่าจริงๆ แล้วนั่นเป็นความล้มเหลว
$output = ./some-command.exe
if ($LASTEXITCODE -eq 0) {
exit 1
}หากคุณเรียกใช้งานนี้โดยไม่ใช้แอตทริบิวต์ ignoreLastExitCode คุณจะพบว่างานยังคงแสดงความสำเร็จอยู่ ทำไม เนื่องจากงานไม่สนใจว่ารหัสทางออกใดที่ PowerShell จริง ๆ แล้ว ส่งคืน โดยจะใช้ค่าของ $LASTEXITCODE เพื่อกำหนดสิ่งนั้น
หากต้องการลบการพึ่งพาตัวแปร $LASTEXITCODE ให้ใช้แอตทริบิวต์ ignoreLastExitCode ดังที่แสดงด้านล่าง
- task: PowerShell@2
inputs:
targetType: 'filePath'
filePath: '$(System.DefaultWorkingDirectory)/script.ps1'
ignoreLastExitCode: trueการแสดงข้อผิดพลาดและคำเตือนที่กำหนดเองในบันทึกงาน
แม้ว่าจะใช้ไม่บ่อยนัก แต่คุณยังสามารถใช้คำสั่งการบันทึกเพื่อเขียนคำเตือนและข้อผิดพลาดลงในบันทึกงานโดยใช้ PowerShell ได้ ด้านล่างนี้เป็นตัวอย่าง
- task: PowerShell@2
inputs:
targetType: 'inline'
script: |
Write-Host "##vso[task.LogIssue type=warning;]This is the warning"
Write-Host "##vso[task.LogIssue type=error;]This is the error"การเพิ่มคำเตือนและข้อผิดพลาดลงในบันทึกงานโดยตรงจะไม่ส่งผลต่อสถานะความสำเร็จ/ล้มเหลวของงาน คุณสมบัตินี้มีประโยชน์สำหรับการบันทึกข้อมูลลงในบันทึกงาน
การจัดการตัวแปรไปป์ไลน์
หัวข้อสุดท้ายที่คุณจะได้เรียนรู้คือการจัดการตัวแปรไปป์ไลน์ AzDo ช่วยให้การตั้งค่าและอ้างอิงตัวแปรไปป์ไลน์ในสคริปต์ PowerShell เป็นเรื่องง่าย
เราจะไม่เจาะลึกเกี่ยวกับตัวแปรในส่วนนี้ หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับตัวแปรไปป์ไลน์ อย่าลืมอ่านการทำความเข้าใจตัวแปร Azure DevOps [คู่มือฉบับสมบูรณ์]
การอ่านตัวแปรไปป์ไลน์
เมื่อคุณกำหนดตัวแปรในไปป์ไลน์แล้ว คุณสามารถอ่านค่าของตัวแปรเหล่านั้นได้ในสคริปต์ PowerShell โดยใช้ตัวแปรสภาพแวดล้อม
บางทีคุณอาจได้ประกาศตัวแปรในไปป์ไลน์เช่นด้านล่าง ขณะนี้ตัวแปร project_name พร้อมใช้งานตลอดทั้งไปป์ไลน์ YAML
variables:
- name: project_name
value: "foo"หากต้องการอ้างอิงค่าของตัวแปรนี้ในสคริปต์ เพียงอ้างอิงชื่อเดียวกัน แต่เป็นตัวแปรสภาพแวดล้อมดังที่แสดงด้านล่าง นั่นคือทั้งหมดที่มีให้ ตัวแปรไปป์ไลน์ทั้งหมดจะถูกแมปกับตัวแปรสภาพแวดล้อมในตัวแทนไปป์ไลน์เสมอ
Write-Host "The value of project_name is $env:project_name"การตั้งค่าตัวแปรไปป์ไลน์
บางทีคุณอาจต้องตั้งค่าตัวแปรไปป์ไลน์ในสคริปต์ PowerShell แม้ว่าจะไม่ค่อยเข้าใจง่ายนัก แต่คุณสามารถทำได้โดยใช้คำสั่งการบันทึก คำสั่งการบันทึกเป็นวิธีที่ไปป์ไลน์สื่อสารกับตัวแทน ด้วยการเขียนสตริงที่สร้างขึ้นโดยเฉพาะลงใน “คอนโซล” คุณสามารถกำหนดตัวแปรดังที่แสดงด้านล่าง
## Creates a standard pipeline variable called foo and sets the value to bar
Write-Host "##vso[task.setvariable variable=foo;]bar"
## Creates an output variable called foo and sets the value to bar
Write-Host "##vso[task.setvariable variable=foo;isOutput=true]bar"การแก้ไขปัญหา
สิ่งต่างๆ ไม่ได้เป็นไปตามที่คุณต้องการเสมอไป ดังนั้นการรู้เคล็ดลับเล็กๆ น้อยๆ เพื่อแก้ไขปัญหาปัญหาติดขัดจึงเป็นเรื่องสำคัญ
ดูคำพูดของคุณ!
หากคุณกำลังเรียกใช้โค้ดแบบอินไลน์ ราคาจะใช้สองตำแหน่ง - ในไปป์ไลน์ YAML และใน PowerShell เป็นเรื่องง่ายที่จะวางใบเสนอราคาในตำแหน่งที่ไม่ถูกต้อง ซึ่งจะทำให้ไปป์ไลน์คิดว่าใบเสนอราคานั้นเหมาะกับมัน และในทางกลับกัน
วิธีที่ง่ายที่สุดวิธีหนึ่งในการป้องกันคือการใช้โค้ดอินไลน์แบบหลายบรรทัด แทนที่จะเรียกใช้โค้ด PowerShell ในบรรทัดเดียวด้วยเครื่องหมายคำพูดและต้องรักษาอะไรแบบนี้ให้ตรง:
powershell: '"This is some code."'แต่คุณสามารถลบเครื่องหมายคำพูดที่ต้องการออกจากไปป์ไลน์ทั้งหมดพร้อมกันได้โดยใช้สัญลักษณ์ไปป์ (|) และเพิ่มโค้ดด้านล่าง วิธีนี้จะช่วยขจัดความซับซ้อนบางอย่าง
powershell: |
"This is some code"การดีบัก
หากคุณต้องการเจาะลึกลงไปถึงสิ่งที่ตัวแทนไปป์ไลน์กำลังทำในเบื้องหลัง คุณสามารถแก้ไขข้อบกพร่องไปป์ไลน์ได้โดยใช้ตัวแปร system.debug หากคุณตั้งค่าตัวแปร system.debug เป็น true ในไปป์ไลน์ คุณจะเห็นเอาต์พุตที่มีรายละเอียดมากขึ้นในบันทึกงานดังที่แสดงด้านล่าง
การแจงนับตัวแปรสภาพแวดล้อม
เมื่อทำงานกับไปป์ไลน์ YAML ที่ซับซ้อน คุณอาจพบสถานการณ์ที่คุณต้องดูว่า PowerShell มองเห็นอะไรเป็นค่าสำหรับตัวแปรไปป์ไลน์ตั้งแต่หนึ่งตัวขึ้นไป
เนื่องจากไปป์ไลน์แมปตัวแปรไปป์ไลน์ทั้งหมดกับตัวแปรสภาพแวดล้อม คุณจึงสามารถแสดงรายการตัวแปรสภาพแวดล้อมปัจจุบันทั้งหมดรวมถึงค่าของมันได้โดยใช้ Get-ChildItem
PowerShell เก็บตัวแปรสภาพแวดล้อมทั้งหมดไว้ใน PS Drive ชื่อ Env จากนั้น คุณสามารถอ่านตัวแปรสภาพแวดล้อมทั้งหมดได้โดยแสดงรายการเนื้อหาของไดรฟ์ PS นี้ดังที่แสดงด้านล่าง
Get-ChildItem -Path Env:\