1. Giới thiệu Việc tự động hóa build, test và deploy giúp nhóm phát triển tập trung vào code thay vì thao tác thủ công. Bài viết chia sẻ quy trình CI/CD thực tế cho cả React Web và React Native, sử dụng GitHub Actions làm orchestrator và Fastlane để xử lý việc ký ứng dụng và đẩy lên store. 2. Cấu trúc repository - mono‑repo chứa hai thư mục chính: `web/` (React + Vite) và `mobile/` (React Native + Expo bare workflow). - File workflow đặt tại `.github/workflows/ci.yml` và `.github/workflows/cd.yml`. - Cấu hình Fastlane nằm ở `mobile/fastlane/` (Appfile, Fastfile, Matchfile). 3. Pipeline Continuous Integration (ci.yml) - Trigger: push và pull_request nhánh `main` và `develop`. - Jobs: - `lint-and-typecheck`: chạy ESLint, Prettier, TypeScript `tsc --noEmit` cho cả hai thư mục. - `unit-test`: chạy Jest + React Testing Library (web) và Jest + @testing-library/react-native (mobile). - `build-web`: `npm run build` trong `web/`, artifact upload `dist/`. - `build-mobile`: `npm run build:android` và `npm run build:ios` (chạy trên macOS runner), artifact upload `android/app/build/outputs/apk/release/` và `ios/build/`. - Cache `node_modules` và Gradle/Xcode cache để giảm thời gian chạy. 4. Pipeline Continuous Deployment (cd.yml) - Chỉ chạy khi tag `v*` được push. - Jobs: - `deploy-web`: tải artifact `dist/`, deploy lên Vercel/Netlify qua CLI token. - `deploy-android`: dùng Fastlane `fastlane android release` – tự động tăng versionCode, ký keystore (được lưu trong GitHub Secrets), upload lên Play Console internal track. - `deploy-ios`: `fastlane ios release` – match certificates/profiles qua `match` (git‑based), tăng build number, upload lên TestFlight. - Mỗi job có `if: github.ref_type == 'tag'` để tránh deploy nhầm. 5. Quản lý secret và biến môi trường - GitHub Secrets: `VERCEL_TOKEN`, `PLAY_STORE_JSON_KEY`, `APP_STORE_CONNECT_API_KEY`, `MATCH_PASSWORD`, `KEYSTORE_PASSWORD`. - File `.env.*` không commit; dùng `dotenv` trong code và `fastlane` đọc từ `ENV`. 6. Lời khuyên thực tế - Tách workflow CI và CD để CI chạy nhanh, CD chỉ chạy khi cần release. - Sử dụng `actions/cache` cho `~/.gradle/caches` và `~/Library/Developer/Xcode/DerivedData`. - Cấu hình `fastlane` với `lane :release do ... end` để dễ dàng mở rộng (ví dụ: gửi Slack, tạo GitHub Release). - Theo dõi log build trên GitHub Actions; bật `continue-on-error: false` để dừng sớm khi có lỗi. - Viết script `scripts/version-bump.js` tự động cập nhật `package.json` và `app.json` trước khi tag, tránh version mismatch. 7. Kết luận Quy trình trên đã được áp dụng cho dự án sản phẩm thực tế, giảm thời gian release từ 2 giờ thủ công xuống còn 15 phút tự động. Các bước đều có thể tùy chỉnh cho các nền tảng CI/CD khác (GitLab CI, Bitrise) nhưng nguyên tắc cốt lõi – tách CI/CD, cache hiệu quả, quản lý secret an toàn – vẫn giữ nguyên.