Continuous Integration (CI) — روشی توسعه است که در آن هر عضو تیم تغییرات خود را حداقل یک بار در روز در مخزن مشترک یکپارچه میکند و هر یکپارچهسازی با بیلد خودکار و تستها تأیید میشود. CI تداخلهای کد و اشکالات بازگشتی را در مراحل اولیه شناسایی میکند و هزینه رفع آنها را کاهش میدهد. طبق گزارش Puppet State of DevOps 2025، تیمهای دارای CI اشکالات را ۴ برابر سریعتر از تیمهای بدون خودکارسازی رفع میکنند.
نکات اصلی
Continuous Integration (CI) — روششناسی توسعه است که فرآیند یکپارچهسازی کد از چندین مشارکتکننده را در یک پایگاه کد واحد خودکار میکند. این اصطلاح توسط مارتین فاولر در اوایل دهه ۲۰۰۰ به عنوان مجموعهای از رویهها برای جلوگیری از «جهنم یکپارچهسازی» معرفی شد — وضعیتی که در آن توسعهدهندگان هفتهها به صورت مجزا کار میکنند و هنگام ادغام تغییرات، تداخلهای زیادی ایجاد میشود که روزها زمان برای رفع دستی نیاز دارد.
بدون CI، توسعهدهنده یک ویژگی را تمام میکند، سعی میکند تغییرات خود را با شاخه main ادغام کند و متوجه میشود که همکاران همان فایلها را تغییر دادهاند. رفع تداخلها ساعتها طول میکشد و اغلب کد کار را خراب میکند. CI این مشکل را با یکپارچهسازی اجباری چند بار در روز حل میکند: هرچه یکپارچهسازی بیشتر باشد، تداخلها کمتر و رفع آنها آسانتر است. تجربه نشان میدهد که با یکپارچهسازی روزانه، رفع تداخل دقایق طول میکشد و با یکپارچهسازی هفتگی — ساعتها.
به گزارش IBM Systems Sciences Institute، هزینه رفع اشکال در مرحله نوشتن کد ۲۵ دلار، در مرحله آزمایش ۱۰۰ دلار و در مرحله تولید ۲۵۰۰ دلار است. CI شناسایی نقصها را به حداکثر چپ منتقل میکند (shift left) و اشکالات را در مرحله commit شناسایی میکند، زمانی که رفع آنها تقریباً رایگان است. تیمهای دارای CI به طور متوسط ۱۵٪ از زمان خود را صرف رفع اشکال میکنند در مقابل ۳۵٪ برای تیمهای بدون CI.
مارتین فاولر رویههای کلیدی CI را تعریف کرد که صرف نظر از پشته فناوری همچنان معتبر هستند. پیروی از این اصول تضمین میکند که CI سودمند است و به یک بار بوروکراتیک تبدیل نمیشود. توسعه موبایل الزامات اضافی را تحمیل میکند، اما هسته اصلی بدون تغییر میماند.
تمامی کد پروژه در یک مخزن با یک سیستم کنترل نسخه واحد (Git) ذخیره میشود. منبع واحد حقیقت وضعیتی را رد میکند که یک ویژگی در یک fork توسعه یابد و هفتهها با پایگاه کد اصلی همگامسازی نشود. در پروژههای موبایل، این بدان معناست که بخشهای Android، iOS و backend میتوانند در یک مخزن (مخزن واحد) یا در مخازن جداگانه با یک طرح نسخهگذاری مشترک قرار گیرند.
بیلد پروژه باید با یک دستور انجام شود. برای Android این است ./gradlew assembleDebug، برای iOS — xcodebuild یا fastlane build. اسکریپت بیلد تکرارپذیری را بررسی میکند: بیلد روی سرور CI باید همان نتیجه ماشین توسعهدهنده را بدهد. هرگونه تفاوت در محیط با کانتینرسازی یا IaC (Infrastructure as Code) برطرف میشود.
پس از بیلد، تمام سطوح تست اجرا میشوند: واحد، یکپارچهسازی و UI. اگر تستها ناموفق باشند — commit نامعتبر محسوب میشود. حفظ وضعیت سبز مسئولیت مشترک تیم است. در پروژههای موبایل، اغلب تستهای سریع (تا ۵ دقیقه در هر commit) و تستهای کند (تستهای UI روی دستگاههای واقعی که کمتر اجرا میشوند) جدا میشوند.
// مثال تست واحد با گزارش CI-friendly
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)
}
}
نتایج CI برای کل تیم عمومی است: همه میبینند که commit چه کسی بیلد را خراب کرده است. شفافیت فرهنگ مسئولیتپذیری ایجاد میکند: توسعهدهندگان تغییرات خود را قبل از push بررسی میکنند و بیلد خراب را خارج از نوبت تعمیر میکنند. سرور CI هنگام تغییر وضعیت بیلد از طریق Slack یا Telegram اعلان ارسال میکند.
یک سیستم CI کامل از چندین جزء تشکیل شده است که با یکدیگر تعامل دارند. هر جزء مسئول بخش خود از خط لوله است: از راهاندازی تا گزارش. درک معماری CI به تشخیص مشکلات و بهینهسازی عملکرد کمک میکند.
جزء مرکزی که صف بیلدها، توزیع منابع و انتشار نتایج را مدیریت میکند. سرور CI میتواند ابری (GitHub Actions, GitLab CI, CircleCI) یا self-hosted (Jenkins, TeamCity) باشد. سرور تغییرات مخزن را از طریق webhook یا polling ردیابی میکند و در هر push یا pull request خط لوله را اجرا میکند.
Runnerها ماشینهای مجازی یا فیزیکی هستند که وظایف بیلد را انجام میدهند. در CIهای ابری، runnerها توسط ارائهدهنده تأمین میشوند و بر اساس زمان استفاده پرداخت میشوند. Runnerهای self-hosted روی زیرساخت خود نصب میشوند و نیاز به نگهداری دارند. برای بیلدهای iOS به runnerهای macOS نیاز است، برای Android — Linux یا Windows.
پس از بیلد، سیستم CI آثار (APK، IPA، گزارشهای تست) را در انبار ذخیره میکند — آنها برای دانلود و استقرار در دسترس هستند. ذخیره نهان وابستگیها (Gradle cache, CocoaPods cache) بین اجراها بیلدهای بعدی را ۳ تا ۵ برابر سریعتر میکند.
| جزء | هدف | مثال |
|---|---|---|
| سرور CI | هماهنگی بیلدها | Jenkins, GitHub Actions |
| Runner | اجرای وظایف | Runner مک برای iOS |
| مخزن | ذخیره کد | GitHub, GitLab |
| Artifact storage | ذخیره آثار | AWS S3, Artifactory |
| Notification | اعلان به تیم | Slack, Telegram, ایمیل |
توسعه موبایل الزامات ویژهای برای CI دارد که با پروژههای وب یا backend متفاوت است. بیلد طولانی (۳–۱۵ دقیقه برای Android، ۵–۲۰ دقیقه برای iOS)، چندین نوع اثر (APK, AAB, IPA)، نیاز به امضا و مبهمسازی — همه اینها نیاز به تنظیم فردی خط لوله CI دارد.
CI معمولی برای Android شامل: لینتینگ (ktlint, detekt) و تحلیل ایستا، تستهای واحد با JUnit و MockK، بیلد debug و release APK/AAB، تستهای ابزاری روی شبیهساز در CI و انتشار آثار است. حافظه نهان Gradle بیلدهای تکراری را سریعتر میکند — بدون آن، هر بیلد وابستگیها را دوباره دانلود میکند و ۳ تا ۵ دقیقه از دست میدهد.
iOS CI برای کامپایل کد Swift/Objective-C به runner macOS نیاز دارد. خط لوله شامل: نصب وابستگیهای CocoaPods یا SPM، SwiftLint برای بررسی سبک، تستهای واحد با XCTest، بیلد IPA، امضای گواهی از طریق Fastlane match و بارگذاری در TestFlight است. Runner self-hosted روی Mac mini یا Mac در مرکز داده — جایگزینی برای runnerهای ابری macOS.
Flutter و React Native به بیلدهای بومی برای هر دو سکو کامپایل میشوند. CI باید از دو runner پشتیبانی کند: Linux برای بیلد Android و macOS برای بیلد iOS. استراتژی بهینه — خط لوله جداگانه: بیلد Android روی runner لینوکس، بیلد iOS روی runner مک، پس از آن هر دو اثر در یک انتشار واحد ترکیب میشوند.
انتخاب ابزار CI به اندازه تیم، عملکرد مورد نیاز، بودجه و پشته فناوری بستگی دارد. در زیر مقایسه راهحلهای محبوب با تأکید بر توسعه موبایل آورده شده است. راهحلهای self-hosted کنترل میدهند اما نیاز به مدیریت دارند، ابری — راحتی اما پیکربندی را محدود میکنند.
برای مخازن عمومی رایگان (۲۰۰۰ دقیقه/ماه). GitHub Actions اکوسیستمی از actionهای آماده برای Android (gradle/actions) و iOS (apple-actions) ارائه میدهد. نکته منفی — runnerهای macOS فقط در طرحهای پولی در دسترس هستند. ایدهآل برای Open Source و تیمهای کوچکی که قبلاً از GitHub استفاده میکنند.
سرور CI self-hosted با کد منبع باز. Jenkins از طریق Groovy Pipeline پیکربندی میشود، از صدها افزونه پشتیبانی میکند و روی هر سختافزاری کار میکند. برای نصب و نگهداری به مهندس DevOps نیاز دارد. در بخش enterprise که کنترل زیرساخت حیاتی است محبوب است.
CI/CD داخلی در GitLab با معماری runner باز. GitLab CI به شما امکان میدهد از runnerهای خود (از جمله macOS) در طرح رایگان استفاده کنید. پیکربندی YAML قدرتمندتر از GitHub Actions اما یادگیری آن دشوارتر است. مناسب برای تیمهایی که از GitLab به عنوان سکوی واحد DevOps استفاده میکنند.
CI ابری با تأکید بر سرعت. CircleCI از تصاویر Docker، macOS و Android پشتیبانی میکند، وابستگیها را به طور خودکار ذخیره میکند. قیمتگذاری اعتباری — برای تیمهای کوچک گرانتر از GitHub Actions، اما به دلیل runnerهای بهینهشده سریعتر است. برای پروژههای تولیدی با نیاز به سرعت توصیه میشود.
بیایید تنظیم CI را برای یک پروژه Android با استفاده از GitHub Actions بررسی کنیم. خط لوله تحلیل ایستا، بیلد و آزمایش را در هر push و pull request به شاخه main انجام میدهد. حداقل پیکربندی ۱۵ دقیقه طول میکشد و به سرویسهای خارجی نیاز ندارد.
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/
خط لوله از دو job موازی تشکیل شده است: lint (تحلیل ایستا را انجام میدهد) و unit-tests (به lint وابسته است — اگر لینتینگ ناموفق باشد، تستها اجرا نمیشوند). Job unit-tests گزارش تست را به عنوان یک اثر بارگذاری میکند — تیم میتواند آن را در رابط GitHub Actions بدون دانلود فایلها به صورت محلی مشاهده کند.
برای جلوگیری از شکست CI به دلیل اشکالات ساده، یک pre-push hook در Git یا یک وظیفه Gradle تنظیم کنید که همان بررسیها را به صورت محلی اجرا کند. به عنوان مثال: ./gradlew ktlintCheck detekt testDebugUnitTest. اگر بررسیهای محلی بیش از ۳ دقیقه طول میکشد — آنها را به سریع (لینتر) و کند (تستها) تقسیم کنید، سریع را قبل از هر commit و کند را فقط قبل از push اجرا کنید.
سؤالات متداول
CI بر یکپارچهسازی و تأیید کد (بیلد + تست) متمرکز است، در حالی که CD خودکارسازی استقرار را اضافه میکند. CI بررسی میکند که کد درست است؛ CD تضمین میکند که این کد درست میتواند به کاربران تحویل داده شود. CI پیشنیاز CD است، اما CD بدون CI کار نمیکند.
حداقل تعداد — یک بار در روز برای هر توسعهدهنده. روش ایدهآل — push به مخزن در هر واحد کار منطقی تکمیلشده (هر ۱ تا ۴ ساعت). هرچه یکپارچهسازی بیشتر باشد، تداخل کمتر و رفع آنها آسانتر است. اگر بین یکپارچهسازیها بیش از ۲ روز فاصله باشد — از CI استفاده نمیکنید.
برای Android GitHub Actions (رایگان، راهاندازی آسان) یا GitLab CI (runnerهای خود) بهینه است. برای iOS — CircleCI (بهترین پشتیبانی macOS) یا Bitrise (CI تخصصی برای پروژههای موبایل). برای چندسکویی — GitLab CI با دو runner (Linux + macOS).
بله، اما با ملاحظاتی. تستهای UI کند (۱۰–۳۰ دقیقه) و ناپایدار هستند. استراتژی بهینه: تستهای سریع (واحد + یکپارچهسازی) را در هر push اجرا کنید، تستهای UI را در pull request، شب یا قبل از انتشار. برای تستهای UI از Device Farm یا شبیهسازها در CI استفاده کنید.
معیارهای CI مؤثر: زمان بیلد کمتر از ۱۵ دقیقه، درصد بیلدهای سبز بیش از ۸۵٪، میانگین زمان بازیابی پس از خرابی کمتر از ۳۰ دقیقه. اگر بیلد مرتباً خراب میشود — CI کمکی نمیکند، بلکه مانع میشود. تستها را مرور کنید: تستهای ناپایدار را حذف کنید، وابستگیها را بهینه کنید، زمان بیلد را کاهش دهید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید