Di era CI / CD di mana-mana, kita dihadapkan dengan berbagai alat terkait, termasuk sistem CI. Namun, GitLab-lah yang paling dekat dengan kami, benar-benar "asli". Dia mendapatkan popularitas terkemuka di industri secara keseluruhan *. Para pengembang produk tidak ketinggalan ketertarikan yang tumbuh dalam penggunaannya, secara teratur memuaskan komunitas pengembang dan insinyur DevOps dengan versi baru.
Bulan repositori GitLab dan agregasi tagGitLab adalah kasus ketika pengembangan aktif membawa banyak fitur baru dan menarik. Jika bagi pengguna potensial, ini hanyalah salah satu faktor dalam memilih alat, untuk yang sudah ada, situasinya adalah sebagai berikut: jika Anda belum memperbarui instalasi GitLab Anda pada bulan lalu, maka dengan probabilitas tinggi Anda melewatkan sesuatu yang menarik. Termasuk pembaruan keamanan yang muncul secara berkala.Tentang yang paling signifikan - yaitu diminta oleh para insinyur dan pelanggan DevOps kami - inovasi dalam rilis terbaru edisi Komunitas GitLab, dan artikel ini akan dibahas.* 5 , «GitLab», : «, GitHub?». — , Google Trends 5- «gitlab» . «» , . , , «» .№1: needs
Pikir dependencies
- ini yang Anda butuhkan? Mungkin, kami bukan satu-satunya yang melakukan kesalahan dalam menetapkan arahan ini ... Diperlukan untuk membuat daftar pekerjaan sebelumnya, artefak yang diperlukan. Itu adalah artefak, dan bukan ketergantungan pada kinerja tugas sebelumnya.Misalkan terjadi bahwa dalam satu tahap ada pekerjaan yang tidak perlu dilakukan, tetapi untuk beberapa alasan tidak ada kemungkinan atau hanya keinginan untuk membawa mereka ke tahap yang terpisah (kemalasan adalah mesin kemajuan, tetapi jangan terbawa).Situasi:
Seperti yang Anda lihat, stage Deploy berisi tombol untuk meluncurkan produksi dan stage, dan tes Selenium jobuntuk beberapa alasan tidak dieksekusi. Sederhana saja: ia menunggu sampai semua pekerjaan dari tahap sebelumnya berhasil diselesaikan. Namun, dalam kerangka pipeline yang sama, kita tidak perlu menggunakan stage sekarang untuk menjalankan tes (dipompa keluar sebelumnya tidak dalam tag). Apa yang harus dilakukan? Kalau begitu datanglah ke kebutuhan penyelamatan !Kami hanya mencantumkan pekerjaan yang diperlukan sebelumnya untuk menjalankan tes kami: needs:
- To production (Cluster 1)
- To production (Cluster 2)
... dan kami mendapatkan pekerjaan, yang secara otomatis dipanggil setelah hanya pekerjaan yang terdaftar dieksekusi:
Mudah, bukan? Tetapi begitu saya berharap bahwa arahan akan bekerja seperti ini dependencies
...2: meluas
Bosan membaca gulungan .gitlab-ci.yaml
? Prinsip kode reuse hilang? Maka Anda sudah mencoba dan mungkin berhasil membawa milik Anda .gitlab-ci.yaml
ke keadaan seperti ini:.base_deploy: &base_deploy
stage: deploy
script:
- my_deploy_command.sh
variables:
CLUSTER: "default-cluster"
MY_VAR: "10"
Deploy Test:
<<: *base_deploy
environment:
url: test.example.com
name: test
Deploy Production:
<<: *base_deploy
environment:
url: production.example.com
name: production
variables:
CLUSTER: "prod-cluster"
MY_VAR: "10"
Kedengarannya bagus? Namun, jika Anda melihat lebih dekat, sesuatu menarik perhatian Anda ... Mengapa kami mengubah produksi tidak hanya variables.CLUSTER
, tetapi juga ditentukan untuk kedua kalinya variables.MY_VAR=10
? Haruskah variabel ini diambil base_deploy
? Ternyata itu seharusnya tidak: YAML bekerja sehingga, mendefinisikan ulang apa yang diterima dari jangkar, itu tidak memperluas konten bidang yang cocok, tetapi menggantinya . Oleh karena itu, kami dipaksa untuk membuat daftar variabel yang sudah diketahui kami dalam paragraf yang cocok.Ya, "ekspansi" adalah kata yang tepat: inilah yang disebut sebagai fitur yang dimaksud. Extends
Mereka memungkinkan kita tidak hanya menulis ulang bidang, seperti yang terjadi dengan jangkar, tetapi untuk melakukan penggabungan yang cerdas untuk itu:.base_deploy:
stage: deploy
script:
- my_deploy_command.sh
variables:
CLUSTER: "default-cluster"
MY_VAR: "10"
Deploy Production:
extends: .base_deploy
environment:
url: production.example.com
name: production
variables:
CLUSTER: "prod-cluster"
Di sini, di pekerjaan akhir Deploy Production akan ada variabel MY_VAR
dengan nilai default dan yang diganti CLUSTER
.Tampaknya ini adalah hal yang sepele, tetapi bayangkan: Anda memiliki satu base_deploy
dan 20 sirkuit yang dikerahkan dengan cara yang sama. Mereka perlu diteruskan ke orang lain cluster
, environment.name
sambil mempertahankan seperangkat variabel tertentu atau bidang yang cocok lainnya ... Kesenangan kecil ini memungkinkan kita untuk mengurangi deskripsi penyebaran rangkaian rangkaian dev sebanyak 2-3 kali.3: termasuk
.gitlab-ci.yaml
masih terlihat seperti instruksi lipat untuk penyedot debu dalam 20 bahasa (yang Anda hanya mengerti yang asli) apakah sulit ketika Anda harus berurusan dengan salah satu bagiannya tanpa mengubah dalam menghadapi pekerjaan yang tidak diketahui yang dihadapi dalam perjalanan?Teman pemrograman lama akan membantu include
:stages:
- test
- build
- deploy
variables:
VAR_FOR_ALL: 42
include:
- local: .gitlab/ci/test.yml
- local: .gitlab/ci/build.yml
- local: .gitlab/ci/deploy-base.yml
- local: .gitlab/ci/deploy-production.yml
Itu Sekarang kami dengan berani mengedit penyebaran dalam produksi, sementara penguji sibuk memodifikasi file mereka, yang bahkan kita tidak melihatnya. Selain itu, ini membantu menghindari penggabungan konflik: tidak selalu menyenangkan untuk memahami kode orang lain.Tetapi bagaimana jika kita mengetahui pipa 20 proyek kita secara terus menerus, dapatkah kita menjelaskan logika masing-masing pekerjaan darinya? Bagaimana ini akan membantu kami? Bagi mereka yang telah mencapai pencerahan dalam penggunaan kembali kode dan untuk semua yang memiliki banyak proyek serupa, Anda dapat:Selusin jenis proyek yang sama dengan kode yang berbeda, tetapi digunakan dengan cara yang sama - dengan mudah dan tanpa mempertahankan CI terbaru di semua repositori!Contoh penggunaan praktis include
juga diberikan dalam artikel ini .Nomor 4: hanya / kecuali referensi
- Kondisi komprehensif, termasuk perubahan variabel dan file.
- Karena ini adalah seluruh keluarga fungsi, beberapa bagian mulai muncul di GitLab 10.0, sementara yang lain (misalnya,
changes
) mulai muncul di 11.4. - docs.gitlab.com/ce/ci/yaml/#onlyexcept-advanced
Kadang-kadang bagi saya tampaknya ini bukan saluran pipa mendengarkan kita, tetapi kita dia. Alat manajemen yang sangat baik adalah only
/ except
- sekarang terintegrasi. Apa artinya ini?Dalam kasus yang paling sederhana (dan mungkin yang paling menyenangkan), lewati tahapan:Tests:
only:
- master
except:
refs:
- schedules
- triggers
variables:
- $CI_COMMIT_MESSAGE =~ /skip tests/
Dalam contoh pekerjaan, ini hanya berjalan di cabang master, tetapi tidak dapat dipicu oleh jadwal atau pemicu (GitLab berbagi pemanggilan dan pemicu API, meskipun ini pada dasarnya adalah API yang sama). Pekerjaan tidak akan dieksekusi jika ada passphrase tes lewati dalam pesan komit . Misalnya, kesalahan ketik dalam README.md
proyek atau dokumentasi telah diperbaiki - mengapa menunggu hasil tes?"Hei, 2020 ada di luar!" Mengapa saya setiap kali harus menjelaskan kepada kotak besi bahwa tidak perlu melakukan tes ketika mengubah dokumentasi? " Dan sungguh: only:changes
ini memungkinkan Anda untuk menjalankan tes ketika mengubah file hanya di direktori tertentu. Contohnya: only:
refs:
- master
- merge_requests
changes:
- "front/**/*"
- "jest.config.js"
- "package.json"
Dan untuk tindakan sebaliknya - mis. jangan lari - ya except:changes
.Nomor 5: aturan
Arahan ini sangat mirip dengan yang sebelumnya only:*
, tetapi dengan perbedaan penting: ini memungkinkan Anda untuk mengontrol parameter when
. Misalnya, jika Anda tidak ingin sepenuhnya menghapus kemungkinan memulai pekerjaan. Anda cukup meninggalkan tombol, yang, jika diinginkan, akan dipanggil secara independen, tanpa meluncurkan pipa baru atau tanpa membuat komit.# 6: environment: auto_stop_in
Kami belajar tentang peluang ini tepat sebelum penerbitan artikel dan belum memiliki cukup waktu untuk mencobanya dalam praktik, tetapi ini jelas merupakan "hal yang sama" yang sangat diharapkan dalam beberapa proyek.Anda dapat menentukan parameter di lingkungan GitLab on_stop
- ini sangat berguna ketika Anda ingin membuat dan menghapus lingkungan secara dinamis, misalnya, untuk setiap cabang. Pekerjaan yang ditandai dengan k on_stop
dieksekusi, misalnya, ketika penggabungan MR ada di cabang master atau ketika MR ditutup (atau bahkan hanya dengan mengklik tombol), yang karenanya lingkungan yang tidak perlu dihapus secara otomatis.Semuanya nyaman, logis, berfungsi ... jika bukan karena faktor manusia. Banyak pengembang menggabungkan MR bukan dengan mengklik tombol di GitLab, tetapi secara lokal via git merge
. Anda dapat memahaminya: nyaman! Namun dalam hal ini, logikanyaon_stop
itu tidak berhasil, kami telah mengumpulkan lingkungan yang terlupakan ... Di sinilah yang lama ditunggu-tunggu berguna auto_stop_in
.Bonus: gubuk sementara saat tidak ada peluang yang cukup
Terlepas dari semua ini (dan banyak lainnya), fungsi baru yang dituntut dari GitLab, sayangnya, kadang-kadang kondisi untuk memenuhi suatu pekerjaan tidak mungkin digambarkan dalam kerangka kemampuan yang tersedia saat ini.GitLab tidak sempurna, tetapi menyediakan alat dasar untuk membangun jalur pipa impian ... jika Anda siap untuk melampaui DSL sederhana, terjun ke dunia scripting. Berikut adalah beberapa solusi dari pengalaman kami, yang sama sekali tidak berpura-pura benar atau direkomendasikan secara ideologis, tetapi disajikan lebih untuk menunjukkan kemungkinan yang berbeda dengan kurangnya fungsionalitas API bawaan.Solusi No. 1: luncurkan dua pekerjaan dengan satu tombol
script:
- >
export CI_PROD_CL1_JOB_ID=`curl -s -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs" | \
jq '[.[] | select(.name == "Deploy (Cluster 1)")][0] | .id'`
- >
export CI_PROD_CL2_JOB_ID=`curl -s -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs" | \
jq '[.[] | select(.name == "Deploy (Cluster 2)")][0] | .id'`
- >
curl -s --request POST -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/jobs/$CI_PROD_CL1_JOB_ID/play"
- >
curl -s --request POST -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \
"https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/jobs/$CI_PROD_CL2_JOB_ID/play"
Dan mengapa tidak, jika Anda benar-benar menginginkannya?Solusi No. 2: transfer diubah dalam file MR rb untuk rubocop di dalam gambar
Rubocop:
stage: test
allow_failure: false
script:
...
- export VARFILE=$(mktemp)
- export MASTERCOMMIT=$(git merge-base origin/master HEAD)
- echo -ne 'CHANGED_FILES=' > ${VARFILE}
- if [ $(git --no-pager diff --name-only ${MASTERCOMMIT} | grep '.rb$' | wc -w |awk '{print $1}') -gt 0 ]; then
git --no-pager diff --name-only ${MASTERCOMMIT} | grep '.rb$' |tr '\n' ' ' >> ${VARFILE} ;
fi
- if [ $(wc -w ${VARFILE} | awk '{print $1}') -gt 1 ]; then
werf --stages-storage :local run rails-dev --docker-options="--rm --user app --env-file=${VARFILE}" -- bash -c /scripts/rubocop.sh ;
fi
- rm ${VARFILE}
Tidak ada gambar di dalamnya .git
, jadi saya harus keluar untuk memeriksa hanya file yang diubah.Catatan: Ini bukan situasi yang sangat standar dan upaya putus asa untuk mematuhi banyak kondisi masalah, deskripsi yang tidak termasuk dalam ruang lingkup artikel ini.Penanganan # 3: pemicu untuk memulai pekerjaan dari repositori lain saat diluncurkan
before_script:
- |
echo '### Trigger review: infra'
curl -s -X POST \
-F "token=$REVIEW_TOKEN_INFRA" \
-F "ref=master" \
-F "variables[REVIEW_NS]=$CI_ENVIRONMENT_SLUG" \
-F "variables[ACTION]=auto_review_start" \
https://gitlab.example.com/api/v4/projects/${INFRA_PROJECT_ID}/trigger/pipeline
Tampaknya hal yang sederhana dan perlu (dalam dunia layanan-mikro) meluncurkan perangkat-layanan lain ke dalam rangkaian yang baru dibuat sebagai ketergantungan. Tapi itu bukan, karena itu, diperlukan panggilan API dan fitur yang sudah dikenal (dijelaskan di atas): only:
refs:
- triggers
variables:
- $ACTION == "auto_review_start"
Catatan:- Pekerjaan pada pemicu dirancang untuk dikaitkan dengan meneruskan variabel ke API, mirip dengan contoh No. 1. Lebih logis untuk mengimplementasikan ini pada API dengan nama pekerjaan disahkan.
- Ya, fungsinya ada dalam versi komersial (EE) dari GitLab, tetapi kami tidak mempertimbangkannya.
Kesimpulan
GitLab mencoba mengikuti tren, secara bertahap menerapkan fitur yang menyenangkan dan diminati oleh komunitas DevOps. Mereka cukup mudah digunakan, dan ketika fitur dasar tidak cukup, mereka selalu dapat diperluas dengan skrip. Dan jika kita melihat ternyata ternyata tidak begitu elegan dan nyaman untuk mendukung ... itu masih menunggu rilis baru GitLab - atau untuk membantu proyek dengan kontribusi kami .PS
Baca juga di blog kami: