Gitlab-ci กล้วยๆ: การใช้งาน extends กำหนดค่าซ้ำ
หากเรามีชุดคำสั่งที่ต้องใช้งานเรียกซ้ำใน Gitlab-ci เราสามารถใช้ extends
เพื่อใช้ส่วนการกำหนดค่าซ้ำ ซึ่งมันมีความยืดหยุ่น และทำให้เราอ่านโค็ดง่ายขึ้นด้วย
extends
นั้นรองรับการเรียกซ้ำได้หลายระดับ แต่เราควรหลีกเลี่ยงการใช้มากกว่า 3 ระดับ เนื่องจากความซับซ้อนที่เพิ่มขึ้น แต่ก็ยังสามารถใช้ได้มากถึง 11 ระดับ ซึ่งตัวอย่างต่อไปนี้จะเป็นการใช้งาน extends
แบบ 2 ระดับ
.tests:
rules:
- if: $CI_PIPELINE_SOURCE == "push"
.rspec:
extends: .tests
script: rake rspec
rspec 1:
variables:
RSPEC_SUITE: '1'
extends: .rspec
rspec 2:
variables:
RSPEC_SUITE: '2'
extends: .rspec
spinach:
extends: .tests
script: rake spinach
จากตัวอย่างข้างต้น ถ้าเราอยากกำหนดชุดคำสั่งไว้เพื่อเรียกใช้งาน ให้เราใส่ .
ก่อนชื่อ แล้วจากนั้น Job ไหนที่ต้องการรียกไปใช้งานเราก็ใช้ extends
เรียกชื่อนั้นๆ ออกมา มันจะทำการรวมคำสั่งต่างๆ ให้
การใช้งาน Variables ใน extends
ตัวอย่างการใช้งาน variables
.base:
script: test
variables:
VAR1: base var 1
test1:
extends: .base
variables:
VAR1: test1 var 1
VAR2: test2 var 2
test2:
extends: .base
variables:
VAR2: test2 var 2
test3:
extends: .base
variables: {}
test4:
extends: .base
variables: null
ผลของการรวมกันแล้ว
test1:
script: test
variables:
VAR1: test1 var 1
VAR2: test2 var 2
test2:
script: test
variables:
VAR1: base var 1
VAR2: test2 var 2
test3:
script: test
variables:
VAR1: base var 1
test4:
script: test
variables: null
การใช้งาน extents
คู่กับ includes
เรามาดูตัวอย่างการใช้งานที่รวมกับ includes
กัน
จากตัวอย่างข้างล่างนี้ มีการกำหนด script
ใน included.yml
ไฟล์ หลังจากนั้นก็ includes
เข้ามาใน .gitlab-ci.yml
แล้วก็ใช้ extends
เป็นตัวเรียกชุดคำสั่งเข้ามา
- included.yml
.template:
script:
- echo Hello!
- .gitlab-ci.yml
include: included.yml
useTemplate:
image: alpine
extends: .template
เพิ่มเติมของการรวมคำสั่ง
มันจะมีเหตุการณ์บ้างอย่างที่เรากำหนดค่าไว้แล้ว 2 ชุดคำสั่ง แล้วเราก็เอา 2 ชุดคำสั่งนั้นมา extends
เข้าที่ Job เดียว ถ้าหากในชุดคำสั่งนั้นมี ข้อมูลที่ซ้ำกัน ในขั้นตอน extents
มันรวมคำสั่งให้โดยยึดเอา ชุดคำสั่งล่าสุด ไว้เสมอ ดูตัวอย่าง
.only-important:
variables:
URL: "http://my-url.internal"
IMPORTANT_VAR: "the details"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == "stable"
tags:
- production
script:
- echo "Hello world!"
.in-docker:
variables:
URL: "http://docker-url.internal"
tags:
- docker
image: alpine
rspec:
variables:
GITLAB: "is-awesome"
extends:
- .only-important
- .in-docker
script:
- rake rspec
ผลลัพธ์ของ rspec
job
rspec:
variables:
URL: "http://docker-url.internal"
IMPORTANT_VAR: "the details"
GITLAB: "is-awesome"
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_BRANCH == "stable"
tags:
- docker
image: alpine
script:
- rake rspec
อธิบายเพิ่มเติมจากข้างต้น
variables
จะถูกรวมกัน แต่URL: "http://docker-url.internal"
จะเขียนทับURL: "http://my-url.internal"
tags: ['docker']
จะเขียนทับtags: ['production']
script
ไม่ได้ถูกรวม แต่script: ['rake rspec']
จะเขียนทับscript: ['echo "Hello world!"']
!reference
tags
เราสามารถใช้ !reference
สำหรับเรียกค่าเฉพาะบ้างอันในชุดคำสั่งเราได้
จากตัวอย่างข้างล่างนี้ script
และ after_script
จะมีการเรียกคำสั่งจาก 2 ชุดคำสั่งที่ต่างกันเพื่อมาใช้งานใน test
job
setup.yml
.setup:
script:
- echo creating environment
.gitlab-ci.yml
include:
- local: setup.yml
.teardown:
after_script:
- echo deleting environment
test:
script:
- !reference [.setup, script]
- echo running my own command
after_script:
- !reference [.teardown, after_script]
มาดูอีกตัวอย่าง test-vars-1
มีการดึง variables ทั้งหมดใน .vars
มาใช้ แต่ขณะที่ test-vars-2
จะเรียกเฉพาะค่า variables มาใช้และทำการกำหนด MY_VAR
ขึ้นมาใหม่แทน
.vars:
variables:
URL: "http://my-url.internal"
IMPORTANT_VAR: "the details"
test-vars-1:
variables: !reference [.vars, variables]
script:
- printenv
test-vars-2:
variables:
MY_VAR: !reference [.vars, variables, IMPORTANT_VAR]
script:
- printenv
การใช้งาน !refereance
ในส่วนของ script
, before_script
และ after_script
เราสามารถใช้ !refereance
ได้ถึง 10 ระดับใน script
, before_script
และ after_script
แต่ก็อย่าไปใช้เยอะเลยเดียวจะสับสน ดูตัวอย่างการใช้งาน
.snippets:
one:
- echo "ONE!"
two:
- !reference [.snippets, one]
- echo "TWO!"
three:
- !reference [.snippets, two]
- echo "THREE!"
nested-references:
script:
- !reference [.snippets, three]
จากตัวอย่างข้างต้น nested-references
job จะทำคำสั่ง echo
ทั้ง 3 อัน
ตั้งค่า IDE เพื่อใข้งาน !refereance
โดยปกติ YAML จะไม่รองรับในการเขียน !refereance
ซึ่งมันจะแสดง Error ออกมาในส่วนของ IDE ที่เราใช้งาน ถ้าใครใช้ vscode อยู่สามารถแก้ไขได้ดังนี้
- แก้ไขไฟล์
settings.json
file:
"yaml.customTags": [
"!reference sequence"
]
extends
จะทำให้เราสามารถเขียนไฟล์ .gitab-ci
ได้สนุกมากขึ้น และเขียนในรูปแบบบ template เพื่อเรียกใช้งานซ้ำๆ ได้เลย ผมใช้ประจำ :)
Thanks:
- https://docs.gitlab.com/ee/ci/yaml/#extends
- https://docs.gitlab.com/ee/ci/yaml/yaml_optimization.html#use-extends-to-reuse-configuration-sections
Comments ()