Continuous Integration (CI) — ay ang praktika ng development kung saan ang bawat miyembro ng koponan ay nag-i-integrate ng kanilang mga pagbabago sa karaniwang repositoryo kahit isang beses sa isang araw, at ang bawat integrasyon ay na-ve-verify ng awtomatikong build at mga test. Nakikita ng CI ang mga conflict ng code at regression error sa mga unang yugto, binabawasan ang gastos ng pag-aayos ng mga ito. Ayon sa Puppet State of DevOps Report, 2025, ang mga koponan na may CI ay nag-aayos ng bug nang 4 na beses na mas mabilis kaysa sa mga koponan na walang automation.
Mga Pangunahing Punto
Continuous Integration (CI) — ay isang methodology ng development na nag-a-automate ng proseso ng integrasyon ng code mula sa maraming kalahok sa iisang codebase. Ang termino ay ipinakilala ni Martin Fowler noong unang bahagi ng 2000s bilang isang set ng mga praktika na pumipigil sa “integration hell” — isang sitwasyon kung saan ang mga developer ay nagtatrabaho nang nakahiwalay sa loob ng ilang linggo, at sa pagsasama ng mga pagbabago ay lumilitaw ang maraming conflict na nangangailangan ng mga araw ng manual na paglutas.
Kung walang CI, tinatapos ng developer ang isang feature, sinusubukang isama ang kanyang mga pagbabago sa main branch at natuklasan na ang mga kasamahan ay nagbago ng parehong mga file. Ang paglutas ng conflict ay tumatagal ng ilang oras at madalas ay nasisira ang gumaganang code. Nilulutas ng CI ang problemang ito sa pamamagitan ng sapilitang integrasyon ng ilang beses sa isang araw: mas madalas ang integrasyon, mas kaunti ang conflict at mas madali ang paglutas ng mga ito. Ipinapakita ng praktika na sa araw-araw na integrasyon, ang paglutas ng conflict ay tumatagal ng ilang minuto, habang sa lingguhang integrasyon — ilang oras.
Ayon sa IBM Systems Sciences Institute, ang gastos ng pag-aayos ng isang bug sa yugto ng pagsulat ng code ay $25, sa yugto ng pag-test — $100, sa yugto ng produksyon — $2,500. Inililipat ng CI ang detection ng defect sa kaliwa (shift left), natutuklasan ang mga error sa yugto ng commit kung kailan halos libre ang pag-aayos ng mga ito. Ang mga koponan na may CI ay gumugugol ng average na 15% ng oras sa debugging kumpara sa 35% ng mga koponan na walang CI.
Tinukoy ni Martin Fowler ang mga pangunahing praktika ng CI na nananatiling may kaugnayan anuman ang technology stack. Ang pagsunod sa mga prinsipyong ito ay ginagarantiyahan na ang CI ay nagdudulot ng benepisyo, hindi nagiging bureaucratic na pasanin. Ang mobile development ay nagpapataw ng mga karagdagang kinakailangan, ngunit ang core ay nananatiling hindi nagbabago.
Ang lahat ng code ng proyekto ay naka-imbak sa isang repositoryo na may nag-iisang version control system (Git). Nag-iisang source ng katotohanan ay nag-aalis ng sitwasyon kung saan ang isang feature ay binuo sa isang fork at hindi na-sa-sync sa pangunahing codebase nang ilang linggo. Sa mga mobile project, ito ay nangangahulugan na ang mga bahagi ng Android, iOS, at backend ay maaaring nasa isang repositoryo (monorepositoryo) o sa magkahiwalay na repositoryo na may karaniwang versioning scheme.
Ang build ng proyekto ay dapat gawin sa isang command. Para sa Android ito ay ./gradlew assembleDebug, para sa iOS — xcodebuild o fastlane build. Ang build script ay sumusuri ng reproducibility: ang build sa CI server ay dapat magbigay ng parehong resulta tulad ng sa machine ng developer. Ang anumang pagkakaiba sa environment ay inaalis sa pamamagitan ng containerization o IaC (Infrastructure as Code).
Pagkatapos ng build, lahat ng levels ng test ay isinasagawa: module, integration, at UI. Kung ang mga test ay nabigo — ang commit ay itinuturing na hindi wasto. Pagpapanatili ng berdeng status ay magkasanib na responsibilidad ng koponan. Sa mga mobile project, madalas na pinaghihiwalay ang mabilis na mga test (ginagawa hanggang 5 minuto sa bawat commit) at mabagal na mga test (UI test sa totoong device, mas madalas isagawa).
// Halimbawa ng unit test na may CI-friendly na ulat
class LoginViewModelTest {
private val repository = mock<AuthRepository>()
private val viewModel = LoginViewModel(repository)
@Test
fun loginWithValidCredentials_success() {
val email = "test@example.com"
val password = "ValidPass123"
whenever(repository.login(email, password))
.thenReturn(Result.success(User("token-xyz")))
val result = viewModel.login(email, password)
assertEquals(LoginState.Success, result)
verify(repository).login(email, password)
}
}
Ang mga resulta ng CI ay pampubliko para sa buong koponan: lahat ay nakakakita kung kaninong commit ang sumira ng build. Ang transparency ay lumilikha ng kultura ng responsibilidad: sinusuri ng mga developer ang kanilang mga pagbabago bago ang push at inaayos ang sirang build nang wala sa pila. Ang CI server ay nagpapadala ng mga notification sa Slack o Telegram kapag nagbago ang status ng build.
Ang isang kumpletong CI system ay binubuo ng ilang mga component na nag-interact sa isa't isa. Ang bawat component ay may pananagutan sa sarili nitong bahagi ng pipeline: mula sa paglunsad hanggang sa ulat. Ang pag-unawa sa architecture ng CI ay tumutulong sa pag-diagnose ng mga problema at pag-optimize ng performance.
Ang sentral na component na namamahala sa pila ng build, pamamahagi ng resources, at publikasyon ng mga resulta. Ang CI server ay maaaring cloud-based (GitHub Actions, GitLab CI, CircleCI) o self-hosted (Jenkins, TeamCity). Sinusubaybayan ng server ang mga pagbabago sa repositoryo sa pamamagitan ng webhook o polling at nagpapatakbo ng pipeline sa bawat push o pull request.
Ang mga runner ay virtual o pisikal na machine na nagpapatupad ng mga build task. Sa cloud CI, ang mga runner ay ibinibigay ng provider at binabayaran batay sa oras ng paggamit. Ang self-hosted runner ay naka-install sa sariling infrastructure at nangangailangan ng maintenance. Para sa iOS build ay kailangan ng macOS runner, para sa Android — Linux o Windows.
Pagkatapos ng build, ang CI system ay nagse-save ng mga artifact (APK, IPA, mga ulat ng test) sa storage — available ang mga ito para i-download at i-deploy. Ang caching ng mga dependency (Gradle cache, CocoaPods cache) sa pagitan ng mga run ay nagpapabilis ng mga susunod na build nang 3–5 beses.
| Component | Layunin | Halimbawa |
|---|---|---|
| CI server | Orkestrasyon ng build | Jenkins, GitHub Actions |
| Runner | Pagpapatupad ng task | macOS runner para sa iOS |
| Repositoryo | Pag-imbak ng code | GitHub, GitLab |
| Artifact storage | Pag-imbak ng artifact | AWS S3, Artifactory |
| Notification | Pag-notify sa koponan | Slack, Telegram, email |
Ang mobile development ay naglalagay ng mga espesyal na kinakailangan para sa CI, na naiiba sa web o backend project. Mahabang build (3–15 minuto para sa Android, 5–20 minuto para sa iOS), maraming uri ng artifact (APK, AAB, IPA), pangangailangan ng pag-sign at obfuscation — lahat ng ito ay nangangailangan ng indibidwal na configuration ng CI pipeline.
Ang tipikal na CI para sa Android ay kinabibilangan ng: linting (ktlint, detekt) at static analysis, unit test gamit ang JUnit at MockK, build ng debug at release APK/AAB, instrumentation test sa emulator sa loob ng CI at publikasyon ng artifact. Ang Gradle cache ay nagpapabilis ng paulit-ulit na build — kung wala ito, bawat build ay nagda-download ng mga dependency muli, nawawalan ng 3–5 minuto.
Ang iOS CI ay nangangailangan ng macOS runner para sa compilation ng Swift/Objective-C code. Ang pipeline ay kinabibilangan ng: pag-install ng mga dependency ng CocoaPods o SPM, SwiftLint para sa style check, unit test gamit ang XCTest, build ng IPA, pag-sign ng certificate sa pamamagitan ng Fastlane match at pag-upload sa TestFlight. Ang self-hosted runner sa Mac mini o Mac sa data center — alternatibo sa cloud macOS runner.
Ang Flutter at React Native ay nag-co-compile sa native build para sa parehong platform. Dapat suportahan ng CI ang dalawang runner: Linux para sa Android build at macOS para sa iOS build. Ang optimal na strategy — hiwalay na pipeline: Android build sa Linux runner, iOS build sa macOS runner, pagkatapos nito ang parehong artifact ay pinagsama sa iisang release.
Ang pagpili ng CI tool ay depende sa laki ng koponan, kinakailangang performance, budget, at technology stack. Sa ibaba ay paghahambing ng mga popular na solusyon na may diin sa mobile development. Ang self-hosted na solusyon ay nagbibigay ng kontrol ngunit nangangailangan ng administrasyon, cloud — kaginhawahan ngunit nililimitahan ang configuration.
Libre para sa pampublikong repositoryo (2000 minuto/buwan). GitHub Actions ay nag-aalok ng ecosystem ng handa nang action para sa Android (gradle/actions) at iOS (apple-actions). Minus — ang macOS runner ay available lamang sa mga bayad na plano. Ideal para sa Open Source at maliliit na koponan na gumagamit na ng GitHub.
Self-hosted CI server na may open source code. Jenkins ay na-configure sa pamamagitan ng Groovy Pipeline, sumusuporta sa daan-daang plugin at gumagana sa anumang hardware. Nangangailangan ng DevOps engineer para sa pag-install at maintenance. Popular sa enterprise segment kung saan kritikal ang kontrol sa infrastructure.
Integrated CI/CD sa GitLab na may open runner architecture. GitLab CI ay nagpapahintulot sa paggamit ng sariling runner (kabilang ang macOS) sa libreng plano. Ang YAML configuration ay mas malakas kaysa GitHub Actions ngunit mas mahirap matutunan. Angkop para sa mga koponan na gumagamit ng GitLab bilang nag-iisang DevOps platform.
Cloud CI na may diin sa bilis. CircleCI ay sumusuporta sa Docker, macOS, at Android images, awtomatikong nag-ca-cache ng mga dependency. Ang pagpe-presyo ay batay sa credit — mas mahal kaysa GitHub Actions para sa maliliit na koponan, ngunit mas mabilis dahil sa optimized runner. Inirerekomenda para sa production project na may mga kinakailangan sa bilis.
Tingnan natin ang configuration ng CI para sa Android project gamit ang GitHub Actions. Ang pipeline ay nagsasagawa ng static analysis, build, at pag-test sa bawat push at pull request sa main branch. Ang minimal configuration ay tumatagal ng 15 minuto at hindi nangangailangan ng mga external na serbisyo.
name: Android CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
- run: ./gradlew ktlintCheck detekt
unit-tests:
needs: lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: 17
distribution: temurin
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew testDebugUnitTest
- uses: actions/upload-artifact@v4
with:
name: test-results
path: app/build/reports/tests/
Ang pipeline ay binubuo ng dalawang parallel na job: lint (nagsasagawa ng static analysis) at unit-tests (depende sa lint — kung ang linting ay hindi pumasa, ang mga test ay hindi tatakbo). Ang unit-tests job ay nag-u-upload ng test report bilang artifact — maaaring tingnan ito ng koponan sa GitHub Actions interface nang hindi nagda-download ng mga file nang lokal.
Upang maiwasan ang pagbagsak ng CI dahil sa mga trivial na error, mag-configure ng pre-push hook sa Git o Gradle task na nagpapatakbo ng parehong pagsusuri nang lokal. Halimbawa: ./gradlew ktlintCheck detekt testDebugUnitTest. Kung ang lokal na pagsusuri ay tumatagal ng higit sa 3 minuto — hatiin ang mga ito sa mabilis (linter) at mabagal (test), patakbuhin ang mabilis bago ang bawat commit at ang mabagal bago lamang ang push.
Mga Madalas Itanong
CI ay nakatutok sa integrasyon at beripikasyon ng code (build + test), habang ang CD ay nagdaragdag ng automation ng deployment. Sinusuri ng CI kung ang code ay tama; ginagarantiyahan ng CD na ang tamang code na ito ay maihahatid sa mga user. Ang CI ay precondition para sa CD, ngunit ang CD ay hindi gumagana nang walang CI.
Minimum na frequency — isang beses sa isang araw bawat developer. Ideal na praktika — push sa repositoryo sa bawat natapos na logical unit ng trabaho (bawat 1–4 na oras). Kung mas madalas ang integrasyon, mas kaunti ang conflict at mas madali ang paglutas ng mga ito. Kung higit sa 2 araw ang pagitan ng mga integrasyon — hindi ka gumagamit ng CI.
Para sa Android ay optimal ang GitHub Actions (libre, madaling i-configure) o GitLab CI (sariling runner). Para sa iOS — CircleCI (pinakamahusay na suporta sa macOS) o Bitrise (espesyalisadong CI para sa mobile project). Para sa cross-platform — GitLab CI na may dalawang runner (Linux + macOS).
Oo, ngunit may mga kondisyon. Ang UI test ay mabagal (10–30 minuto) at hindi stable (flaky). Optimal na strategy: patakbuhin ang mabilis na test (unit + integration) sa bawat push, at ang UI test sa pull request, sa gabi o bago ang release. Gumamit ng Device Farm o emulator sa CI para sa UI test.
Mga metric ng epektibong CI: oras ng build mas mababa sa 15 minuto, porsyento ng berdeng build higit sa 85%, average na oras ng recovery pagkatapos ng failure mas mababa sa 30 minuto. Kung ang build ay madalas bumagsak — ang CI ay hindi tumutulong, kundi humahadlang. Suriin ang mga test: alisin ang flaky test, i-optimize ang mga dependency, paikliin ang oras ng build.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din