Skip to content

Commit 156238c

Browse files
committed
ci: follow core releases and publish React Native packages
1 parent 3990dfd commit 156238c

12 files changed

Lines changed: 1173 additions & 1031 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Check release automation
2+
3+
on:
4+
push:
5+
branches: [main]
6+
paths:
7+
[
8+
"scripts/*release*",
9+
".github/workflows/*release*",
10+
"packages/react-native-nitro-modules/nitro",
11+
]
12+
pull_request:
13+
paths:
14+
[
15+
"scripts/*release*",
16+
".github/workflows/*release*",
17+
"packages/react-native-nitro-modules/nitro",
18+
]
19+
20+
permissions:
21+
contents: read
22+
23+
jobs:
24+
check:
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v7
28+
with:
29+
submodules: recursive
30+
- uses: actions/setup-node@v6
31+
with:
32+
node-version: "24"
33+
- run: node --test scripts/find-core-release.test.mjs
34+
- run: node --check scripts/release-ci.mjs && bash -n scripts/release.sh
35+
- uses: docker://rhysd/actionlint:1.7.12
36+
with:
37+
# GitHub supports concurrency.queue since May 2026; actionlint 1.7.12 does not yet recognize it.
38+
# https://github.blog/changelog/2026-05-07-github-actions-concurrency-groups-now-allow-larger-queues/
39+
args: -ignore unexpected.key..queue..for..concurrency..section .github/workflows/release.yml .github/workflows/check-release.yml

‎.github/workflows/release.yml‎

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
name: Release
2+
3+
on:
4+
schedule:
5+
- cron: "7,22,37,52 * * * *"
6+
workflow_dispatch:
7+
inputs:
8+
core-tag:
9+
description: "Published Nitro tag to adopt or retry (empty prioritizes regular releases, then the newest nightly)"
10+
type: string
11+
required: false
12+
13+
concurrency:
14+
group: release
15+
queue: max
16+
cancel-in-progress: false
17+
18+
permissions:
19+
contents: read
20+
21+
jobs:
22+
discover:
23+
if: github.repository == 'margelo/react-native-nitro-modules' && github.ref == 'refs/heads/main'
24+
runs-on: ubuntu-latest
25+
outputs:
26+
tag: ${{ steps.release.outputs.tag }}
27+
steps:
28+
- uses: actions/checkout@v7
29+
with:
30+
submodules: recursive
31+
persist-credentials: false
32+
- uses: actions/setup-node@v6
33+
with:
34+
node-version: "24"
35+
- name: Find the next completed core release
36+
id: release
37+
env:
38+
GH_TOKEN: ${{ github.token }}
39+
CORE_TAG: ${{ inputs.core-tag }}
40+
run: node scripts/find-core-release.mjs
41+
42+
release:
43+
needs: discover
44+
if: needs.discover.outputs.tag != ''
45+
runs-on: macos-26
46+
timeout-minutes: 90
47+
permissions:
48+
contents: write
49+
id-token: write
50+
steps:
51+
- uses: actions/checkout@v7
52+
with:
53+
ref: main
54+
fetch-depth: 0
55+
submodules: recursive
56+
- uses: actions/setup-node@v6
57+
with:
58+
node-version: "24"
59+
- run: npm install --global npm@11.19.0
60+
- uses: oven-sh/setup-bun@v2
61+
with:
62+
bun-version-file: package.json
63+
- uses: ruby/setup-ruby@v1
64+
with:
65+
ruby-version: "3.3"
66+
- uses: actions/setup-java@v6
67+
with:
68+
distribution: zulu
69+
java-version: "17"
70+
- uses: android-actions/setup-android@v3
71+
- name: Select Xcode
72+
run: sudo xcode-select -s /Applications/Xcode_26.5.app/Contents/Developer
73+
- name: Adopt, verify and publish the core release
74+
env:
75+
GH_TOKEN: ${{ github.token }}
76+
CORE_TAG: ${{ needs.discover.outputs.tag }}
77+
BUNDLE_FROZEN: "true"
78+
run: node scripts/release-ci.mjs

‎CONTRIBUTING.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ To update the pinned core:
6060
4. If the core version changed, run `bun update-core-version`. Run `bun install`, `bun specs`, and the relevant native checks, then commit the core pin, version/lockfile changes, and any intended generated test bindings here. Push the wrapper commit after the core commit is available remotely.
6161
5. On another checkout, run `git submodule update --init --recursive` followed by `bun install` after pulling the wrapper commit.
6262

63-
Prepare version changes in the standalone `nitro` repository with `bun version:set VERSION`. This updates `nitro-core`, Nitrogen, its core dependency, and embedded JS/native versions in `packages/nitro-core/js/version.ts` and `packages/nitro-core/cpp/utils/NitroDefines.hpp`. Build Nitrogen and refresh the core lockfile before committing. Publish `nitro-core` followed by `nitrogen` from the `nitro` repository, then use the final pushed core commit when updating the wrapper as described above. Nitrogen depends on `nitro-core` with a compatible semver range. The RN package depends on the exact core version to match its native runtime. All three packages use the coordinated release version.
63+
Start releases in the standalone `nitro` repository's GitHub Actions workflow, choosing the exact version there. CI updates the authoritative package and JS/native versions, publishes `nitro-core` and `nitrogen`, and completes a GitHub release. This repository's release workflow adopts the published tag, updates its pinned commit and versions, validates the packages and native builds, and publishes `react-native-nitro-modules` at the same version. See [RELEASING.md](RELEASING.md) for npm trusted-publisher setup, prereleases, and recovery.
6464

65-
`bun update-core-version` copies the authoritative version into the wrapper and test packages. Inspect real `npm pack` tarballs for `nitro-core`, `nitrogen`, and the RN package and run the native consumer checks before publishing. In this repository, `bun release` checks the existing version and publishes only `react-native-nitro-modules` through `npm publish`; it does not bump versions with release-it.
65+
`bun update-core-version` copies the authoritative version into the wrapper and test packages. Use it when testing an intentional core pin change locally. `bun release [core-tag]` dispatches this repository's GitHub workflow to adopt or retry a completed core release; it does not bump versions or publish locally.
66+
67+
Nitro also publishes a nightly for every commit pushed to its `main`. The wrapper follows those releases at the same version under npm's `nightly` tag. Nightly version commits are tagged without changing this repository's `main` version or core pin. Pending regular releases take priority over nightlies.
6668

6769
The RN tarball includes staged native files and its own JS integration. Shared JS is installed through its `nitro-core` dependency. Neither package needs a core checkout or Git access when installed from npm.
6870

‎RELEASING.md‎

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Releasing React Native Nitro Modules
2+
3+
Start releases in [margelo/nitro](https://github.com/margelo/nitro). Until `core-split` is merged, run `bun release VERSION` there. After the merge, you can also choose the exact version in its **Release Nitro** GitHub Actions workflow. Nitro publishes `nitro-core` and `nitrogen`, then completes its GitHub release. This repository picks up that release and publishes `react-native-nitro-modules` at the same version.
4+
5+
All three packages share a release version. To release a wrapper-only change, such as a podspec fix, start a patch release in Nitro. The wrapper has no independent version bump.
6+
7+
## One-time setup
8+
9+
In the npm settings for `react-native-nitro-modules`, configure a GitHub Actions trusted publisher:
10+
11+
- Organization or user: `margelo`
12+
- Repository: `react-native-nitro-modules`
13+
- Workflow filename: `release.yml`
14+
- Environment: leave empty
15+
16+
The core packages need their own trusted publishers for `margelo/nitro` and `release.yml`. See Nitro's [release instructions](https://github.com/margelo/nitro/blob/core-split/RELEASING.md). The workflows use npm OIDC and do not need an npm token or a token with access to both repositories.
17+
18+
Keep this workflow on `main`, the repository's default branch, so GitHub runs its schedule. Repository rules must allow its `GITHUB_TOKEN` to push the release commit to `main`, create `vVERSION`, and create GitHub releases. Release commits use `Marc Rousavy <me@mrousavy.com>`. Check branch and tag rules before the first release. If a rule rejects the push, the workflow stops before publishing.
19+
20+
`0.37.1` already exists on npm. The first release after the split must use a newer version.
21+
22+
## Automatic adoption
23+
24+
The **Release** workflow checks Nitro's published GitHub releases every 15 minutes. GitHub can delay scheduled jobs. It includes prereleases and only considers releases with the `nitro-release.json` manifest produced by the coordinated core release workflow. Historical Nitro tags do not trigger it.
25+
26+
Each run processes the oldest pending regular release, including manually chosen prereleases such as beta or RC versions. Once those are complete, it processes the newest pending nightly. A failed older nightly does not block newer commits or regular releases. Earlier nightlies can be backfilled when no newer version is waiting. For each release, CI:
27+
28+
1. Verifies the core tag, manifest, tarballs, and published npm package integrities.
29+
2. Pins `packages/react-native-nitro-modules/nitro` to that exact commit, stages the gitlink, runs `update-core-version`, and refreshes `bun.lock`.
30+
3. Stages the shared native sources, builds and typechecks the workspace, regenerates the existing specs, and runs the package tests and performance-tool tests.
31+
4. Runs CocoaPods for both apps to update their lockfiles, including podspec checksums, then builds the example app for the iOS simulator and Android.
32+
5. Packs the RN package and installs all three release tarballs into a temporary consumer outside the workspace. It checks package contents, real package directories, TypeScript, and generation for the existing object and view fixtures.
33+
6. Pushes the version commit and tag together with an atomic Git push for regular releases. Nightlies push only a tag. CI then saves a draft GitHub release with the exact tarball and `nitro-rn-release.json` manifest.
34+
7. Publishes the RN tarball to npm and completes the GitHub release.
35+
36+
The wrapper inherits the core release's npm tag. Stable releases normally use `latest`; a version such as `0.38.0-beta.1` normally uses `beta`. GitHub marks prereleases accordingly.
37+
38+
The native builds use the staged workspace sources. The temporary consumer checks package installation and generation; it does not run native builds or Harness. Continue running the existing iOS and Android Harness workflows before releasing behavior changes.
39+
40+
## Nightlies
41+
42+
Every commit pushed to Nitro's `main` starts a nightly core release. Its version has the form `0.37.2-nightly.123.gabcdef123456`, where the suffix records the workflow run number and source commit. This repository adopts that completed release and publishes the matching RN package to the `nightly` npm tag.
43+
44+
The wrapper builds a nightly from its current `main` in a detached checkout. The version commit records the nightly core pin, but only its Git tag is pushed. This keeps `main` on the last regular release's version and core pin. The nightly manifest records the wrapper source commit separately from the generated version commit.
45+
46+
Nightlies pass the same package and native build checks as regular releases. They do not update npm's `latest` tag. If a delayed retry publishes an older nightly after a newer nightly is already available, it uses a `nightly-COMMIT` npm tag to keep `nightly` pointing at the newer version. The older version can still be installed by its exact version number.
47+
48+
A nightly whose sources fail validation remains unpublished. Fixes in a newer core commit can release automatically without waiting for that failed build. You can select any published core nightly tag manually to retry or backfill it.
49+
50+
## Trigger or retry from GitHub
51+
52+
Open this repository's **Release** workflow and choose **Run workflow** on `main`. Leave `core-tag` empty to use the regular-release priority above, or enter an exact published core tag, such as `v0.37.2` or a nightly tag.
53+
54+
The equivalent commands are:
55+
56+
```sh
57+
bun release
58+
bun release v0.37.2
59+
```
60+
61+
These commands dispatch GitHub Actions through `gh`; they do not publish from the local checkout. A manual regular release cannot skip an earlier pending regular release. Any marked nightly can be selected for recovery or backfill. A completed release can be selected again to verify its saved package.
62+
63+
For failures after the release checkpoint was saved, rerun the workflow with the same tag. CI downloads the saved tarball, verifies its integrity, and publishes it only if that exact version is still missing from npm. If npm already has the same tarball, CI completes the remaining GitHub release step. A different tarball at the same npm version stops the workflow.
64+
65+
If the Git tag was pushed but the draft checkpoint was not saved, retrying rebuilds and validates the tagged commit. Main is never rewound. Do not delete or move release tags, replace saved tarballs, or choose another version to work around an authentication failure.
66+
67+
If a build fails before the version commit was pushed, fix the wrapper on `main` and rerun the same core tag. For regular releases, resolve the failed version before proceeding with another regular release. A nightly with a core implementation bug can remain unpublished while a newer fixed nightly proceeds.
68+
69+
## Development commands
70+
71+
`bun sync-core` stages the native sources from the recorded submodule commit. `bun update-core-version` adopts the authoritative core version and exact JS dependency; it never changes the generated native header. The release workflow runs both commands.
72+
73+
For development, follow [CONTRIBUTING.md](CONTRIBUTING.md#shared-sources-and-releases) to test a core commit before it has a release tag. Ordinary builds and checkout updates always use the committed submodule SHA.

‎REPOSITORY_SPLIT.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ bun specs
3939

4040
Commit the updated pin, metadata, lockfile, and any intended generated fixture changes here. Normal checkout updates use `git submodule update --init --recursive`, without `--remote`.
4141

42-
For a version change, run `bun version:set <version>` in Nitro first. It updates the authoritative package versions, Nitrogen's `nitro-core` dependency, `packages/nitro-core/js/version.ts`, and `NITRO_VERSION` in `packages/nitro-core/cpp/utils/NitroDefines.hpp`. The wrapper's `bun update-core-version` adopts that version; it never writes a generated native header. See [CONTRIBUTING.md](CONTRIBUTING.md#shared-sources-and-releases) for the full sequence.
42+
Choose release versions in Nitro's GitHub Actions workflow. It updates `nitro-core`, Nitrogen, the JS version, and `NITRO_VERSION`, then publishes both npm packages and a GitHub release. This repository polls those completed releases, pins the exact tagged commit, adopts the same version, validates the RN package, and publishes it with its own GitHub release. Native sources continue to come from the committed gitlink.
4343

44-
Publish `nitro-core` followed by `nitrogen` from Nitro, then `react-native-nitro-modules` from this repository. The wrapper's `bun release` checks for committed sources and matching versions, builds, and publishes only the RN package. Packing rebuilds the output and rejects uncommitted core sources. No npm packages or release tags were created during this split.
44+
`bun update-core-version` remains the local command for adopting the pinned core's version. `bun release [core-tag]` dispatches this repository's release workflow through `gh`. See [RELEASING.md](RELEASING.md) for setup, validation, and retry behavior. No npm packages or release tags were created while implementing this automation.
45+
46+
Nightlies follow every commit pushed to Nitro's `main` and publish all three packages at the same nightly version. The wrapper publishes a tagged version commit without changing its `main` branch. Regular releases take priority when both channels have pending releases.
4547

4648
## Package contents
4749

0 commit comments

Comments
 (0)