Rn ci cd
Skill almasumdev/awesome-react-native-agent-skills/.github/skills/build_and_tooling/rn-ci-cd
Expert guidance on CI/CD for React Native with EAS Build, GitHub Actions, Fastlane, and EAS Update / CodePush for OTA delivery. Use when asked about builds, store submission, or OTA updates.From its SKILL.md
npx -y skills add almasumdev/awesome-react-native-agent-skills --skill rn-ci-cdAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
5.1 KB, ~1.4k tokens by cl100k_base, as published. Nobody here has run it
React Native CI/CD
Instructions
Automate three pipelines: PR checks (lint, type, unit, E2E smoke), internal builds (per-commit on main), and release (tagged, signed, submitted).
1. PR Checks (GitHub Actions)
# .github/workflows/pr.yml
name: pr
on:
pull_request:
branches: [main]
concurrency:
group: pr-${{ github.ref }}
cancel-in-progress: true
jobs:
static:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with: { version: 9 }
- uses: actions/setup-node@v4
with: { node-version: 20, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm lint
- run: pnpm typecheck
- run: pnpm test --ci --coverage
android-build:
runs-on: ubuntu-latest
needs: static
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: 17 }
- uses: pnpm/action-setup@v4
with: { version: 9 }
- uses: actions/setup-node@v4
with: { node-version: 20, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: cd android && ./gradlew :app:assembleDevDebug --no-daemon
2. EAS Build for Release
eas.json:
{
"cli": { "version": ">= 10.0.0" },
"build": {
"dev": { "developmentClient": true, "distribution": "internal", "channel": "dev" },
"staging": { "distribution": "internal", "channel": "staging", "env": { "APP_ENV": "staging" } },
"prod": { "channel": "prod", "env": { "APP_ENV": "prod" }, "autoIncrement": true }
},
"submit": {
"prod": {
"ios": { "appleId": "[email protected]", "ascAppId": "1234567890", "appleTeamId": "ABCDE12345" },
"android": { "serviceAccountKeyPath": "./secrets/play-sa.json", "track": "production" }
}
}
}
Trigger from a tag:
# .github/workflows/release.yml
name: release
on:
push:
tags: ['v*']
jobs:
build-and-submit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with: { version: 9 }
- uses: actions/setup-node@v4
with: { node-version: 20, cache: pnpm }
- uses: expo/expo-github-action@v8
with: { eas-version: latest, token: ${{ secrets.EXPO_TOKEN }} }
- run: pnpm install --frozen-lockfile
- run: eas build --profile prod --platform all --non-interactive
- run: eas submit --profile prod --platform all --non-interactive
3. Fastlane for Bare Projects
ios/fastlane/Fastfile:
default_platform(:ios)
platform :ios do
desc "Build and upload to TestFlight"
lane :beta do
setup_ci if ENV['CI']
match(type: "appstore", readonly: true)
increment_build_number(xcodeproj: "MyApp.xcodeproj")
build_app(scheme: "MyApp-Prod", configuration: "Release", export_method: "app-store")
upload_to_testflight(skip_waiting_for_build_processing: true)
end
end
android/fastlane/Fastfile:
default_platform(:android)
platform :android do
desc "Ship to internal track"
lane :internal do
gradle(task: "clean bundleProdRelease")
upload_to_play_store(track: "internal", aab: "app/build/outputs/bundle/prodRelease/app-prod-release.aab")
end
end
4. OTA Updates
Use EAS Update (preferred) or CodePush to ship JS-only fixes without a store review.
eas update --branch prod --message "Fix checkout null ref"
Channel to branch mapping lives in eas.json ("channel": "prod"). On app start, expo-updates will download and apply on the next launch.
Rules for OTA:
- Never ship native changes via OTA; a mismatched JS bundle will crash.
- Include the bundle version in the update message so rollbacks are traceable.
- Roll out gradually (e.g., branch
prod-canaryfirst) and promote after bake time.
5. Secrets
- Store signing keys and service accounts in the CI secret store (GitHub Encrypted Secrets, EAS Secrets).
- Never check in
.env.prod,*.keystore,*.p8, orplay-sa.json. - Rotate Apple API keys and Play service accounts at least yearly.
6. Versioning
versioninapp.json(Expo) orInfo.plist/build.gradle(bare) is the user-visible version.buildNumber/versionCodeis incremented automatically by EAS ("autoIncrement": true) or Fastlane.- Tag releases as
vX.Y.Zand let CI pick the tag name up for release notes.
Checklist
- PR CI runs lint, typecheck, unit tests, and a cheap platform build on every PR.
- Release builds are triggered only by signed tags, never manual dispatches.
- EAS Build (or Fastlane) handles signing; no signing material is in the repo.
-
eas submit(or Fastlanedeliver) handles store upload; no manual drag-and-drop. - OTA updates are JS-only, matched to native binary versions via channels.
- Secrets are stored in the CI secret manager and rotated on a schedule.
- Build numbers auto-increment; user-visible version bumps are deliberate.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.