Rn ci cd
Skill almasumdev/awesome-react-native-agent-skills/.github/skills/build_and_tooling/rn-ci-cd
Curated agent skills, conventions, and workflows for building React Native apps with AI coding agents.
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.
What its author says it does
Copied from the file, not written here
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.
SKILL.md
5.1 KB, 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.