Build dan test aplikasi Android secara otomatis dengan Gitlab Continuous Integration
Pada artikel ini, saya akan menjelaskan bagaimana kami di Oddbit, membangun Continuous Integration untuk aplikasi Android yang memungkinkan kita untuk mem-build, test, dan menyiapkan package yang siap dikirim ke client.
Diakhir artikel ini, anda akan menemukan konfigurasi Gitlab CI secara lengkap dan siap digunakan.
Click here to read the article in English
Gitlab
Gitlab mungkin tidak mendapatkan penghasilan sebanding dengan apa yang seharusnya mereka dapat. Tapi saya akan membagi keuntungan saya jika saya mendapatkan kesempatan nanti.
GitHub sangat bagus untuk komunitas open source. Tapi Gitlab adalah solusi one-stop-shop untuk tim developer seperti kita. Saya telah menulis beberapa artikel khusus tentang Gitlab CI, karena ini adalah salah satu hal yang paling saya sukai dengan platform ini.
Dalam contoh artikel ini, Anda dapat melihat bahwa saya telah mengonfigurasi script dengan "anchors" yang memungkinkan kami menggunakan kembali specs pekerjaan dengan cara modul DNRY. Baca lebih lanjut tentang itu di dokumentasi Gitlab jika Anda belum yakin tentang hal itu.
Step 1: Build
Untuk men-develop aplikasi Android di Gitlab CI, kita perlu men-setup enviroment, men-download dan menginstal beberapa paket terlebih dahulu.
.build_template: &build_template_def
stage: build
artifacts:
expire_in: 4 hours
paths:
- app/build/outputs/
- .android/
before_script:
# Extract the SDK version that we're building against
- export ANDROID_COMPILE_SDK=`egrep '^[[:blank:]]+compileSdkVersion' app/build.gradle | awk '{print $2}'`
# Explict output for logging purpose only
- echo $ANDROID_SDK_TOOLS
- echo $ANDROID_COMPILE_SDK
# Fetch the specified SDK tools version to build with
- wget --quiet --output-document=/tmp/sdk-tools-linux.zip https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS}.zip
- unzip /tmp/sdk-tools-linux.zip -d .android
# Set up environment variables
- export ANDROID_HOME=$PWD/.android
- export PATH=$PATH:$PWD/.android/platform-tools/
# Install platform tools and Android SDK for the compile target
- echo y | .android/tools/bin/sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}"
- chmod +x ./gradlew
build_debug:
<<: *build_template_def
only:
- develop
script:
- ./gradlew assembleDebug
build_release:
<<: *build_template_def
only:
- master
script:
- ./gradlew assembleRelease
Mari kita breakdown kasus ini menjadi beberapa bagian!
Pertama dimulai dengan mendownload SDK Tools versi terbaru, untuk melakukannya kita harus secara eksplisit menentukan versi yang ingin kita gunakan. Demi kenyamanan, saya menyimpan versi ANDROID_SDK_TOOLS ke dalam build environment variable, yang ditetapkan ke "3859397" (versi terbaru saat artikel ini ditulis).
tps://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS}.zip
Selanjutnya extract package tersebut ke dalam folder bernama .android
di dalam folder project karena kita akan menyimpan file tersebut sebagai artefak ke pekerjaan berikutnya. Artifak ini dikonfigurasi agar expired setelah 4 jam, yang rasanya sangat cukup untuk menjalankan long running test. Untuk sementara hanya ini yang kita butuhkan, sedangkan untuk membuat package aplikasi yang siap dikirim ke client akan dibahas pada akhir artikel.
Setelah kita mengekstrak paket tersebut, kita dapat menggunakan sdkmanager CLI tool untuk melakukan semua pekerjaan yang sama seperti yang dilakukan Android Studio. Pada baris pertama, kita mengekstrak konfigurasi build target SDK dari app/build.gradle
, kita akan menggunakannya untuk menginstall platform tool dan target SDK yang ingin kita kompile.
$ sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}"
Yapss itu dia, commit, push, dan tunggu… atau langsung ke langkah berikutnya!
Step 2: Test
Dalam contoh ini, testing hanya menjalankan unit testing. Tapi seperti yang akan kita lihat di artikel berikutnya “Mendeploy aplikasi ke Firebase Test Lab dengan Gitlab CI”, kita dapat mengeksekusi CI Jobs secara paralel sebelum mengemasnya jika semua test berhasil.unit_test:
stage: test
only:
- develop
- master
before_script:
- export ANDROID_HOME=$PWD/.android
- export PATH=$PATH:$PWD/.android/platform-tools/
script:
- ./gradlew test
Seperti yang bisa kita lihat, tidak banyak yang bisa dijelaskan dalam langkah ini. Library yang telah didownload dan hasil generate dari build step dapat kita akses kembali, thanks to the artifacts configuration.
Step 3: Package
Akhirnya, jika semua proses berjalan dengan benar kita akan membuat sebuah file zip file yang dapat didownload dan dikirim ke project manager, client, atau siapapun yang ingin kita inginkan.
.package_template: &package_template_def
before_script:
- export VERSION_NAME=`egrep '^[[:blank:]]+versionName[[:blank:]]' app/build.gradle | awk '{print $2}' | sed s/\"//g`
- export VERSION_CODE=`egrep '^[[:blank:]]+versionCode[[:blank:]]' app/build.gradle | awk '{print $2}'`
- mkdir -p deliverables
# Store some information about the build
- touch ./deliverables/info.txt
- echo "Build date $(date)" >> ./deliverables/info.txt
- echo "App version name ${VERSION_NAME}" >> ./deliverables/info.txt
- echo "App version code ${VERSION_CODE}" >> ./deliverables/info.txt
- echo "Git branch ${CI_COMMIT_REF_NAME}" >> ./deliverables/info.txt
- echo "Git commit ${CI_COMMIT_SHA}" >> ./deliverables/info.txt
- echo "Gitlab pipeline ${CI_PIPELINE_ID}" >> ./deliverables/info.txt
package_develop:
<<: *package_template_def
stage: package
environment: Development
only:
- develop
script:
- mv app/build/outputs/apk/app-debug.apk ./deliverables/NameOfTheApp-v$VERSION_NAME-$VERSION_CODE-debug.apk
artifacts:
expire_in: 3 days
paths:
- deliverables
package_release:
<<: *package_template_def
stage: package
environment: Release
only:
- master
script:
- mv app/build/outputs/apk/app-release.apk ./deliverables/NameOfTheApp-v$VERSION_NAME-$VERSION_CODE-release.apk
artifacts:
expire_in: 4 weeks
paths:
- deliverables
Sederhananya script ini melakukan 2 hal yaitu:
- Me-rename file APK sesuai dengan nama aplikasi dan menambahkan informasi versi dari aplikasi.
- Menambahkan file keterangan tambahan mengenai build dari aplikasi kita berupa: tanggal, commit hash, pipeline id, dan lain-lain.
Package yang dihasiilkan akan disimpan dalam jangka waktu tertentu, yang dapat kita konfigurasi sesuai dengan kebutuhan kita (bahkan kita dapat menghapus expired datenya).
Disini saya memutuskan untuk menghapus hasil “development build” setelah 3 hari. Karena branch ini adalah branch yang sibuk jadi saya ingin memastikan hanya hasil build terbaru yang ada pada branch ini.
Sedangkan pada release branch kita akan membiarkan hasil build tersimpan lebih lama dan mungkin akan ada beberapa hasil build dari periode sprint yang berbeda. Hal ini untuk menjamin jika repository kita memiliki hasil build terbaru yang dapat didownload setiap saat.
Jika pengembangan project Anda dalam kondisi vacum selama beberapa waktu, Anda dapat meningkatkan (atau menghapus) expired date. Atau mengkonfigurasi penjadwalan build otomatis setiap beberapa minggu di master branch. Hanya untuk memastikan semuanya masih ok :-)
Script Lengkap
Inilah konfigurasi lengkap, siap copy / paste ke proyek Android anda. Tapi ... Anda tidak langsung menuju script ini tanpa membaca artikel ini sampai akhir, bukan? :-) Jika Anda melakukannya: jangan tanya, baca dulu.
Klik sini untuk download dari github
image: openjdk:8-jdk
stages:
- build
- test
- package
####################################################################################################
# BUILD
#
.build_template: &build_template_def
stage: build
artifacts:
expire_in: 4 hours
paths:
- app/build/outputs/
- .android/
before_script:
# Extract the SDK version that we're building against
- export ANDROID_COMPILE_SDK=`egrep '^[[:blank:]]+compileSdkVersion' app/build.gradle | awk '{print $2}'`
# Explict output for logging purpose only
- echo $ANDROID_SDK_TOOLS
- echo $ANDROID_COMPILE_SDK
# Fetch the specified SDK tools version to build with
- wget --quiet --output-document=/tmp/sdk-tools-linux.zip https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_TOOLS}.zip
- unzip /tmp/sdk-tools-linux.zip -d .android
# Set up environment variables
- export ANDROID_HOME=$PWD/.android
- export PATH=$PATH:$PWD/.android/platform-tools/
# Install platform tools and Android SDK for the compile target
- echo y | .android/tools/bin/sdkmanager "platforms;android-${ANDROID_COMPILE_SDK}"
- chmod +x ./gradlew
build_debug:
<<: *build_template_def
only:
- develop
script:
- ./gradlew assembleDebug
build_release:
<<: *build_template_def
only:
- master
script:
- ./gradlew assembleRelease
####################################################################################################
# UNIT TESTING
#
unit_test:
stage: test
only:
- master
- develop
before_script:
- export ANDROID_HOME=$PWD/.android
- export PATH=$PATH:$PWD/.android/platform-tools/
script:
- ./gradlew test
####################################################################################################
# PACKAGE APK FOR DOWNLOADING
#
.package_template: &package_template_def
before_script:
- export VERSION_NAME=`egrep '^[[:blank:]]+versionName[[:blank:]]' app/build.gradle | awk '{print $2}' | sed s/\"//g`
- export VERSION_CODE=`egrep '^[[:blank:]]+versionCode[[:blank:]]' app/build.gradle | awk '{print $2}'`
- mkdir -p deliverables
# Store some information about the build
- touch ./deliverables/info.txt
- echo "Build date $(date)" >> ./deliverables/info.txt
- echo "App version name ${VERSION_NAME}" >> ./deliverables/info.txt
- echo "App version code ${VERSION_CODE}" >> ./deliverables/info.txt
- echo "Git branch ${CI_COMMIT_REF_NAME}" >> ./deliverables/info.txt
- echo "Git commit ${CI_COMMIT_SHA}" >> ./deliverables/info.txt
- echo "Gitlab pipeline ${CI_PIPELINE_ID}" >> ./deliverables/info.txt
package_develop:
<<: *package_template_def
stage: package
environment: Development
only:
- develop
script:
- mv app/build/outputs/apk/app-debug.apk ./deliverables/NameOfTheApp-v$VERSION_NAME-$VERSION_CODE-debug.apk
artifacts:
expire_in: 3 days
paths:
- deliverables
package_release:
<<: *package_template_def
stage: package
environment: Release
only:
- master
script:
- mv app/build/outputs/apk/app-release.apk ./deliverables/NameOfTheApp-v$VERSION_NAME-$VERSION_CODE-release.apk
artifacts:
expire_in: 4 weeks
paths:
- deliverables
artikel yang sangat keren @dennisalund !
sekedar ingin menambahkan tips, kita bisa menggunakan custom image docker yang sudah ada pre-installed SDK android, salah satunya adalah docker dari jangrewe yang memang dibuat khusus untuk CI android di Gitlab: https://github.com/jangrewe/gitlab-ci-android
lumayan bikin code CI jadi pendek :D
give it a try :)
Ya, itu sebenarnya jauh lebih bagus dan efektif. Coba saya update artikelnya dengan saran itu. Terima kasih ya!
hai kawan @dennisalund, salam...
saya ada bikin aplikasi
Steem Autovote
. Bila kamu jain dan tergabung dalam aplikasi ini, maka tiap artikel kamu akan mendapatkan upvote dari member lain. Besaran upvote yang diberikan akan tergantung dengan Steem Power kamu.yuk join ya, gabung dengan teman-teman lainnya. kita cara nafkah bersama di steem :)
untuk info lebih lanjut bisa dibaca disini: https://steemit.com/steem/@lopezdacruz/tentang-steem-indovoter-aplikasi-otomatis-vote-antar-member
terima kasih ya
Hai, selamat ketemu. Jujur dikit ya, saya gak terlalu setuju kalo ada auto-upvoting. Mungkin orang bisa dapat banyak STEEM, tapi itu tidak akan bantu untuk naikin artikel dengan kualitas, karena semua artikel dapat banyak upvote. Lama-lama, kalo bots jadi lebih penting untuk dapat STEEM, daripada feedback beneran dari orang, jadinya orang mungkin mulai posting banyak dengan kualitas rendah, malah lebih jarang tapi dengan kualitas tinggi.
Congratulations @dennisalund! You have completed some achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes
Click on any badge to view your own Board of Honor on SteemitBoard.
For more information about SteemitBoard, click here
If you no longer want to receive notifications, reply to this comment with the word
STOP