react-native-appsflyer
Version:
React Native Appsflyer plugin
172 lines (129 loc) • 7.91 kB
Markdown
# Release operator manual
Step-by-step guide for cutting, validating, and shipping a React Native plugin release using the automated RC pipeline.
## Prerequisites
- **GitHub**: write access to `AppsFlyerSDK/appsflyer-react-native-plugin`, ability to run Actions
- **npm**: publish rights for the `react-native-appsflyer` package
- **Jira**: access to the project for fix-version validation
- **Slack**: member of the release notification channel
## Workflow overview
```
release.yml (RC) ── lint-test-build.yml ───┐
ios-e2e.yml ──────────┤
android-e2e.yml ──────┤
▼
publish RC to npm
create pre-release + PR
│
rc-smoke.yml (auto-triggers)
│
QA adds "pass QA ready for deploy" label
│
promote-release.yml
(strips -rcN suffix)
│
Human merges PR to master
│
release.yml (production)
(publishes to npm @latest)
```
## 1. Cut a release candidate
1. Go to **Actions** > **Release** > **Run workflow**. Select `release_type: rc`.
2. Fill in the required inputs:
| Input | Required | Example | Description |
|-------|----------|---------|-------------|
| `release_type` | Yes | `rc` | Release type (`rc` or `production`). |
| `rn_version` | Yes | `6.18.0-rc1` | Plugin version. Must match `X.Y.Z-rcN` format for RC. |
| `ios_sdk_version` | No | `6.18.0` | iOS native AppsFlyer SDK version to pin — RC only. |
| `android_sdk_version` | No | `6.18.0` | Android native AppsFlyer SDK version to pin — RC only. |
| `base_branch` | No | `development` | Branch to cut the release from (default: `development`). |
| `pc_version` | No | `6.15.2` | PurchaseConnector iOS version override. Leave empty to auto-fetch latest from GitHub. |
| `skip_unit` | No | `false` | Skip Jest + ESLint inside Lint, Test & Build. |
| `skip_builds` | No | `false` | Skip Android + iOS release builds inside Lint, Test & Build. |
| `skip_e2e` | No | `false` | Skip iOS + Android E2E test jobs. Blocks publish if not skipped. |
| `dry_run` | No | `true` | **Default is true.** Set to `false` to actually publish to npm. Dry runs still create the branch and PR. |
3. Click **Run workflow**.
## 2. What the pipeline does automatically
Once triggered, the pipeline runs these stages in order:
1. **Validate inputs** -- checks version format, branch existence, and Jira fix version.
2. **Lint, Test & Build** -- Jest tests, ESLint, Android release build, iOS release build.
3. **Create release branch** -- creates `releases/X.Y.Z-rcN` from `base_branch` with version bumps in:
- `package.json` (version field; `react-native-appsflyer.podspec` reads from this)
- `android/build.gradle` (Android SDK fallback version)
- `android/.../RNAppsFlyerConstants.java` (PLUGIN_VERSION)
- `ios/RNAppsFlyer.h` (kAppsFlyerPluginVersion)
- `README.md` (SDK version badges)
- `CHANGELOG.md` (new entry prepended)
4. **E2E tests** -- iOS and Android E2E suites run on the release branch.
5. **Publish RC** -- `npm publish --tag rc` (skipped if `dry_run` is true).
6. **GitHub pre-release** -- created with release notes.
7. **PR to master** -- auto-opened from the release branch.
8. **Slack notification** -- posts to the release channel.
9. **Smoke tests** -- `rc-smoke.yml` triggers automatically after the RC workflow succeeds. Installs the RC from npm in a fresh project and runs smoke scenarios. Posts a `rc-smoke/npm` check-run on the release branch.
## 3. QA validation
1. Wait for the `rc-smoke/npm` check-run to appear green on the PR.
2. Install the RC in a test app and validate manually:
```bash
npm install react-native-appsflyer@6.18.0-rc1
```
3. Test attribution, deep linking, and any feature changes specific to this release.
4. If the RC passes QA, apply the label **`pass QA ready for deploy`** to the PR.
If the RC fails QA: fix the issue on `development`, then cut a new RC with an incremented suffix (e.g., `6.18.0-rc2`).
## 4. Promote to production
When the `pass QA ready for deploy` label is applied:
1. `promote-release.yml` triggers automatically.
2. It verifies `rc-smoke/npm` passed, then strips the `-rcN` suffix from all version files on the release branch and commits.
3. **You must manually merge the PR to master.** The bot cannot merge (org policy).
## 5. Production publish
When the PR merges to master:
1. `release.yml` triggers automatically (production path).
2. It publishes to npm with the `latest` tag.
3. Creates a GitHub release (not pre-release).
4. Notifies Slack.
## 6. Post-release verification
```bash
# Verify npm
npm view react-native-appsflyer version
# Expected: 6.18.0
# Verify GitHub
# Check https://github.com/AppsFlyerSDK/appsflyer-react-native-plugin/releases
```
## Troubleshooting
### RC smoke tests failed
Check the `rc-smoke.yml` run logs and the `.af-e2e/reports` artifacts. Common causes:
- npm registry propagation delay (retry the smoke workflow manually)
- E2E infrastructure flake (re-run the workflow via Actions > RC Smoke > Run workflow)
### Promote blocked: "rc-smoke/npm is missing"
The smoke workflow hasn't finished or wasn't triggered. Run `rc-smoke.yml` manually with the RC version and release branch, wait for it to pass, then re-apply the `pass QA ready for deploy` label.
### npm publish succeeded but PR/Slack failed
The published package is valid. Manually complete the failed steps:
- Create the PR from the release branch to master if missing.
- Post to Slack manually.
### npm publish failed
Fix the root cause (auth, network, version conflict), then re-run the RC workflow with the **same version**. npm rejects duplicate version+tag combos, so if the version was partially published, you may need to `npm unpublish react-native-appsflyer@6.18.0-rc1` first (within 72h) or bump to `-rc2`.
### Wrong content published to npm
1. Deprecate the bad version:
```bash
npm deprecate react-native-appsflyer@6.18.0-rc1 "broken, use 6.18.0-rc2"
```
2. Fix the issue on `development`.
3. Cut a new RC with the next suffix (`-rc2`).
### E2E tests failed during RC
Check `.af-e2e/reports` artifacts in the workflow run. E2E failures block npm publish (unless `skip_e2e` was set). Fix the issue, then either:
- Re-run the failed E2E job from the Actions UI, or
- Cut a new RC if code changes are needed.
### release.yml (production) did not trigger after merge
The workflow triggers on `pull_request: closed` to `master` from `releases/*` branches. If it didn't fire:
- Verify the PR was merged (not just closed).
- Verify the source branch matched `releases/*`.
- Use the manual dispatch: Actions > Release > Run workflow, select `production` type, enter the version.
## Version files reference
These files contain version strings. The RC and promote workflows update them automatically. Listed here for manual intervention scenarios.
| File | Field | Updated by |
|------|-------|------------|
| `package.json` | `"version"` | RC workflow |
| `react-native-appsflyer.podspec` | `s.version` (reads from package.json) | Indirect |
| `android/build.gradle` | `appsflyerVersion` fallback | RC workflow |
| `android/.../RNAppsFlyerConstants.java` | `PLUGIN_VERSION` | RC workflow |
| `ios/RNAppsFlyer.h` | `kAppsFlyerPluginVersion` | RC workflow |
| `README.md` | SDK version badges | RC workflow |
| `CHANGELOG.md` | Release entry | RC workflow |