ทำ CI/CD ใน Android ด้วย Gitlab CI

Noey Jariya
True e-Logistics
3 min readFeb 21, 2018

--

การเขียนแอปพลิเคชัน ขั้นตอนที่เราต้องทำกันอยู่เสมอคือการ Build, Test และ Deploy เบื่อมั้ยที่ต้องมานั่งกดทีละขั้นตอนทุกครั้งที่แอปมีการอัปเดต? มาใช้ CI/CD ทำเรื่องพวกนี้แทนกันดีกว่า..

ในบทความนี้จะพูดถึงว่า CI/CD คืออะไร? ทำงานร่วมกับ Android ยังไง? แล้วจะสั่งให้มัน Build และ Deploy แอพเองทุกครั้งที่เรา push code ขึ้น gitlab ต้องทำยังไง?

เริ่มต้นกันที่ CI/CD คือ?

CI/CD หรือ Continuous Integration/ Continuous Deployment เป็นเครื่องมือที่ช่วยให้การทำงานต่างๆทำงานเองอัตโนมัติ เช่นในกรณีนี้ เราเขียนแอพ เราอยากจะให้มัน build แล้วก็ deploy เองเลยเวลาที่แอปเรามีการอัปเดต CI ก็จะอ่าน script คำสั่งที่เราเขียนขึ้นมาและทำงานให้เองอัตโนมัติ

Gitlab CI

จริงๆแล้ว CI มี server ให้เลือกใช้อยู่อีกหลายตัวเช่น Jenkins, Travis-CI, Buildbot, Drone และอีกมากมาย แต่เหตุผลที่เลือก Gitlab CI เนื่องจากใช้ Gitlab เป็น version control อยู่แล้ว เลยเลือกใช้ CI ของ Gitlab ซะเลย :)

Flow การทำงาน

ในบทความนี้จะขอข้ามขั้นตอนการทำ Test ไป จะใช้ CI เพื่อทำเพียง automate build และ deploy app เท่านั้น โดยมี Flow การทำงานเบื้องต้นดังรูปภาพด้านล่าง

Gitlab CI จะทำงานโดยการอ่าน script หรือคำสั่งจาก ไฟล์ .gitlab-ci.yml ซึ่งเราจะสร้างไฟล์นี้ไว้ที่โฟลเดอร์ของโปรเจ็ค

ไฟล์ .gitlab-ci.yml

ไฟล์นี้เป็นไฟล์สำคัญ สำหรับการทำ CI ด้วย Gitlab เพราะ Gitlab CI จะเริ่มต้นทำงานโดยอ่านคำสั่งผ่านไฟล์นี้ ซึ่ง Gitlab จะอ่านและทำงานตามคำสั่งในไฟล์นี้เองโดยที่เราไม่ต้องใส่คำสั่งใดๆเพิ่ม แค่ใส่ไฟล์นี้เอาไว้ที่โฟลเดอร์ของโปรเจ็คเท่านั้น

ขั้นตอนหลักๆ จากไฟล์ .gitlab-ci.yml ข้างต้น ประกอบด้วย

  • Define image
  • Define variables
  • Prepare environment
  • Define stages
  • Build app
  • Deploy app

ทำความเข้าใจ(บาง)ขั้นตอนในไฟล์ .gitlab-ci.yml

Define image

image: openjdk:8-jdk

เรา define image เพื่อเป็นการบอก docker ว่าจะใช้ docker image ตัวไหนในการทำงานครั้งนี้

Define stages

stages:
- build
- deploy

stages แต่ละ stages เปรียบเหมือนการจัดกลุ่มให้แต่ละ jobs ซึ่ง jobs ใน stage เดียวกันจะทำงานเป็น parallel โดยแต่ละ jobs ใน stages นั่นๆต้องทำงานเสร็จก่อน stages ถัดไปจะเริ่มทำงาน

Build App + Deploy App

ก่อนจะไปลงรายละเอียดขั้นตอนในการ build กับการ deploy ด้านล่างคือ flow การทำงานของทั้งสองขั้นตอน

Build App

build:
stage: build
script:
# Creating variable
- export APP_VERSION=V.${CI_BUILD_TAG}
- export FILE_NAME=app-$APP_VERSION.apk

# Build apk
- ./gradlew assembleRelease

# Change file name
- mv app/build/outputs/apk/release/app-release.apk app/build/outputs/apk/release/$FILE_NAME
artifacts:
paths:
- app/build/outputs/
only:
- tags

build job เริ่มต้นด้วยการสร้างตัวแปรเพื่อมาเก็บเลข version ซึ่งเอาค่ามากจากชื่อ tags ตอนเรา push ซึ่งคือ ${CI_BUILD_TAG} > คำสั่ง assembleRelease คือให้ build release version ของ app > เปลี่ยนชื่อไฟล์เป็นเลข version > output ที่ได้จากการ build จะสามารถดาวน์โหลดได้ผ่าน artifacts field ตาม path ที่กำหนดเอาไว้ โดย job นี้จะทำงานก็เมื่อเรา push tags ใน Gitlab เท่านั้น

Deploy App

deploy:
stage: deploy
script:
# Installing node and firebase
- curl -sL https://deb.nodesource.com/setup_9.x | bash
- apt-get install -y nodejs
- npm install -g --unsafe firebase-tools
- firebase init database
- firebase use --token $FIREBASE_DEPLOY_KEY production
- export APP_VERSION=V.${CI_BUILD_TAG}
- export FILE_NAME=app-$APP_VERSION.apk
- echo $FILE_NAME
# Uploading apk to S3
- ./gradlew uploadApk

# Updating value on firebase realtime database
- echo "\"$APK_LINK/production/release/$FILE_NAME\"" | firebase database:set /config/app/test/stable/url --confirm
- echo "\"$APP_VERSION\"" | firebase database:set /config/app/test/stable/version --confirm
dependencies:
- build
only:
- tags

ใน stage deploy นี้ขึ้นอยู่กับแต่ละคนว่าจะเอา output ของ การ build ไปทำอะไร เช่นอัพโหลดขึ้น Google Play เป็นต้น แต่สำหรับในบทความนี้ ตาม code ข้างต้น จะนำ output ที่ได้อัพโหลดขึ้น server ของ S3

จะเริ่มต้นด้วยการติดตั้ง Node และ Firebase > set ค่าตัวแปร > Upload APK ขึ้น S3 server(สามารถดูการเรียกใช้ plugin uploadApk ได้ที่ https://github.com/rambabusaravanan/gradle-android-s3 ) > update Url และ version ล่าสุดของ APK ไฟล์ไว้ที่ Realtime database ของ Firebase เพื่อนำไปใช้งานต่อไป

--

--