Automated QA & Deployment Menggunakan Gitlab CI/CD
Pada dinamika software development yang sangat cepat dan dinamis, setiap harinya, developer menyumbangkan atau mengubah kode suatu perangkat lunak setiap jam atau bahkan setiap menit. Dari situlah perlu diperlukan sistem QA untuk memastikan perubahan kode yang terjadi tidak merusak kode yang sudah sebelumnya sudah berjalan. Sistem QA ini masih memungkinkan dengan hanya mengandalkan manusia (dalam hal ini developer) saja apabila perangkat lunak yang dikembangkan masih sederhana. Namun bayangkan apabila perangkat lunak yang dikembangkan cukup kompleks dimana dalam pengerjaannya melibatkan banyak developer yang saling bekerja sama. Tentunya akan sulit apabila proses QA ini dilakukan secara manual oleh developer. Belum lagi pada proses integrasi antara perubahan yang dilakukan oleh developer satu dengan perubahan kode yang dilakukan oleh developer lain. Tentunya akan sulit dilakukan pengecekan secara manual untuk memastikan integrasi tersebut tidak merusak kode yang sudah berjalan. Lalu untuk kasus lainnya adala, h bagaimana kita bisa men-deliver produk secara langsung tanpa harus terlalu mengandalkan manusia? Permasalahan-permasalahan tersebut merupakan masalah yang bisa diselesaikan dengan menggunakan CI/CD. Pada artikel ini, Saya akan menjelaskan mengenai CI/CD serta implementasinya dengan menggunakan Gitlab pada PPL.
Apa itu CI/CD?
CI/CD tersusun atas CI (continuous integration) dan CD(continuous delivery/continuous deployment).
Continuous integration pada dasarnya adalah proses mengotomasi QA atau pengecekan kode seperti validasi dan testing. Pada proses development, pengecekan tersebut terjadi secara berulang-ulang sehingga dengan mengotomasi proses tersebut akan menghemat waktu development bagi developer. Selain itu, proses CI dapat memastikan kode tetap berjalan dengan baik secara konsisten dan kontinu. Hal ini juga diperkuat apabila pada Gitlab misalkan, terdapat sistem apabila salah satu proses gagal, maka tidak bisa dilakukan integrasi melalui merge sehingga proses CI ini akan memastikan kode akan tetap berjalan dengan baik walaupun setelah integrasi.
Continuous delivery pada dasarnya adalah setiap kode yang sudah diujikan pada tahap CI bisa tersimpan di suatu repository atau tempat tertentu sehingga kode bisa langsung di-deploy ke production secara manual oleh seseorang. Pada tahap ini bisa saja dilakukan pengujian yang menguji aspek non fungsionalitas perangkat lunak seperti stress testing atau performance testing sebelum perangkat lunak bisa dirilis atau deploy oleh manusia.
Continuous deployment merupakan tahap yang lebih maju dibandingkan continuous delivery. Pada tahap ini kode yang sudah terintegrasi dan sudah dites bisa secara otomatis ter-deploy ke production dari repository tanpa harus melibatkan intervensi manusia.
Jadi dari definisi-definisi tersebut, proses CI/CD pada dasarnya adalah otomasi proses pengecekan kualitas kode serta deployment kode yang sudah teruji dan terintegrasi ke production. Proses otomasi ini akan membentuk pipeline yangmana pipeline sendiri dapat dianalogikan seperti assembly line pada pabrik. Apabila dianalogikan pada proses perakitan mobil, Continuous integration bisa diibaratkan sebagai proses penggabungan komponen-komponen mobil serta pembuatan satu jenis komponen mobil dimana terdapat pengecekan apakah komponen mobil yang dibuat mengandung kecacatan atau tidak oleh mesin pabrik. Continous delivery bisa diibaratkan sebagai tahap pengujian secara keseluruhan mobil yang sudah dirakit, misalkan proses test drive, pengujian performa mobil, dan sebagainya. Dan terakhir, continous deployment sendiri bisa diibaratkan sebagai proses pengantaran mobil dari pabrik ke dealer.
Bagaimana Melakukan Proses CI/CD?
Saya akan menjelaskan bagaimana melakukan proses CI/CD dengan menggunakan Gitlab. Sebenarnya proses CI/CD bisa menggunakan berbagai platform lain seperti Circle CI, Travis CI, Jenkins, atau Github. Namun, karena pada kuliah PPL ini kami menggunakan Gitlab, Saya akan menjelaskan bagaimana melakukannya dengan menggunakan Gitlab. Pada gitlab, proses CI/CD didefinisikan pada script bernama .gitlab-ci.yml. Script ini terletak pada direktor root project serta berisikan susunan alur dari job atau perkerjaan yang akan dieksekusi. Setiap job tergabung dalam suatu stage dimana stage digunakan untuk menentukan kapan job akan terpanggil. Stage ini perlu didefinisikan secara terurut dari atas ke bawah dimana stage teratas akan dieksekusi pertama kali lalu dilanjutkan pada stage di bawahnya. Pada proyek PPL, kami menggunakan tiga stage yang terdiri atas:
- test: Stage untuk mengecek kualitas dan kebenaran kode
- sonar-scanner-test: Stage untuk mengecek kualitas kode secara lebih mendalam dengan menggunakan sonarqube
- deploy: Stage untuk deploy kode ke server
Berikut merupakan .gitlab-ci.yml yang kami gunakan untuk backend.
Sebagai catatan, semua yang berawalan dengan $ merupakan nilai dari suatu environment variable (Misalkan $HEROKU_TOKEN, maka itu menunjukkan nilai dari environment variable HEROKU_TOKEN). Nilai dari environment variable dapat kita buat pada bagian Setting -> CI/CD -> Variables sebagaimana yang tercantum di bawah.
Berikut merupakan penjelasan flow dari script .gitlab-ci.yml yang kami gunakan:
- Pada baris 1–4, terdapat pendefinisian stage untuk semua job serta alurnya. Seperti yang disinggung sebelumnya, karena urutan stage dari atas ke bawah maka flow jobnya adalah semua job dengan stage “test” akan dieksekusi ==> semua job dengan stage “sonarqube-sonar-test” => semua job dengan stage “deploy”.
- Pada baris 7–16, terdapat job untuk melakukan unit testing. Job ini termasuk dalam stage test sehingga akan dieksekusi pertama kali. Pada job ini menggunakan image golang karena pada job ini dilakukan unit testing terhadap kode golang. Script berisikan langkah-langkah yang dilakukan pada suatu job. Untuk job ini, langkah yang dilakukan adalah meng-install dependensi lalu dilanjutkan dengan unit testing. Langkah unit testing ini akan menghasilkan artifact .testCoverage.txt. Artifact inilah yang akan digunakan oleh sonarqube pada stage selanjutnya.
- Pada baris 18–25 terdapat job checkstyle. Job ini termasuk dalam stage test sehingga job ini akan dijalankan secara parallel dengan job unit-test. Job ini akan mengecek apakah penulisan kode golang sudah mengikuti best practice atau belum. Yang dilakukan oleh job ini adalah meng-install dependensi, meng-install go lint (library untuk mengecek formatting dan codestyle kode), dan melakukan pengecekan format & codestyle kode. Terdapat parameter tambahan allow_failure. Pada job ini kami set true sehingga apabila job berhasil mendeteksi kode yang tidak mengikuti best practice standar, maka hanya akan muncul semacam warning dan pipeline akan tetap berjalan. Hal ini dilakukan karena checkstyle hanya mengecek penulisan kode saja sehingga tidak mengecek apakah kode sudah dengan berjalan dengan benar atau tidak. Sedangkan hal tersebut sudah ditangani oleh job unit-test.
- Pada baris 27–43 terdapat job untuk melakukan pengecekan kode dengan sonarqube. Job ini tergabung dalam stage sonar-scanner-test sehingga akan dieksekusi setelah job unit-test dan checkstyle berjalan dengan sukses. Yang dilakukan adalah job ini mengecek kode dengan sonarqube. Sonarqube ini akan menghasilkan report yang berisikan code coverage, jumlah duplikasi code, dan sebagainya. Oleh karena itu, job ini dieksekusi setelah stage selesai. Pada line 41–43, terdapat field except untuk memspesifikasikan branch mana yang tidak bisa menjalankan suatu job. Seperti yang terlihat pada potongan kode, job ini tidak bisa dieksekusi oleh branch staging & master.
- Pada baris 45–60, jobnya mirip dengan job pada baris 27–43. Perbedaannya terletak pada branch yang mengeksekusi job ini. Apabila pada job sonarqube-dev terdapat field except, maka pada sonarqube field except tersebut diganti menjadi only. Hal tersebut menunjukkan bahwa job ini hanya bisa dieksekusi oleh semua branch yang tercantum pada field only. Pada script tersebut, terlihat bahwa hanya branch staging & master yang bisa mengeksekusi job ini.
- Pada baris 63–75 dilakukan proses deploy kode ke server heroku untuk staging. Job ini termasuk pada stage deploy sehingga akan dieksekusi terakhir. Pada job ini terdapat field before_script. Field tersebut menunjukkan urutan langkah-langkah yang perlu dieksekusi suatu job sebelum mengeksekusi langkah-langkah yang didefinisikan pada script. Pada bagian before_script, akan dilakukan dpl yangmana dpl ini akan digunakan pada script untuk proses deployment ke heroku staging. Barulah pada bagian script, dilakukan proses deployment kode ke server heroku staging. Seperti yang terlihat, job ini hanya dieksekusi pada branch staging.
- Pada baris 77–89 terdapat job untuk melakukan proses melakukan deployment pada server heroku production. Job ini mirip dengan deployment-staging, perbedaannya adalaha bila pada job deployment-staging melakukan deployment ke url heroku server staging untuk job ini, proses deployment dilakukan terhadap url heroku server production. Selain itu, job ini hanya bisa dieksekusi pada branch master.
Penutup
Proses CI/CD dapat mengotomasi pekerjaan yang repetitif seperti pengecekan kode, deployment, dan sebagainya sehingga dapat mengurangi pekerjaan yang harus dikerjakan oleh developer serta waktu yang perlu dihabiskannya. CI/CD juga memastikan proses pengecekan kode dapat terus dilakukan secara konsisten serta memudahkan proses deployment kode ke server sehingga tim developer bisa fokus untuk proses implementasi kode. Dalam PPL ini Saya merasa dengan adanya CI/CD, Saya merasa bahwa waktu yang habiskan jauh lebih banyak ke implementasi kode dibandingkan mengurus masalah deployment(tidak harus melakukan banyak setup pada server) sehingga sebagai developer, saya merasa terbantu dengan adanya CI/CD.
Panduan mengenai CI/CD gitlab bisa dibaca lebih jelas di sini.