Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .babelrc

This file was deleted.

13 changes: 13 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true

[*.md]
trim_trailing_whitespace = false
52 changes: 0 additions & 52 deletions .eslintrc

This file was deleted.

1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
40 changes: 40 additions & 0 deletions .github/RELEASING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Releasing

Release Please keeps one reviewable release pull request up to date from Conventional Commits. Merging it updates `package.json` and `CHANGELOG.md`, creates a `v*` tag and GitHub Release, then publishes the checked tarball to npm with short-lived OIDC credentials and provenance.

## One-time setup

After `release.yml` is on `master` and before merging the first release pull request:

1. Create a GitHub environment named `npm`. Add required reviewers if desired.
2. Configure npm trusted publishing:

```sh
npm trust github react-native-rating \
--repo f0rr0/react-native-rating \
--file release.yml \
--env npm \
--allow-publish
```

3. Backfill the missing npm 2.0.4 baseline tag so the first generated comparison link resolves:

```sh
git tag v2.0.4 a07d5dc89eec88bff2fa4da65a079028c19d4976
git push origin v2.0.4
```

4. Keep Actions' default token read-only and allow Actions to create pull requests. The release job grants only the three write permissions it needs: contents, issues, and pull requests.
5. Require `Check`, `React Native (minimum)`, `React Native (current)`, and `Dependency review` on `master`, and protect `v*` tags from deletion or force updates.

The first automated pull request may require a maintainer to approve its CI run because it is opened with `GITHUB_TOKEN`.

Use Conventional Commit pull request titles and squash merges so the default-branch history remains release-ready.

After the first trusted publish succeeds, set npm publishing access to **Require two-factor authentication and disallow tokens**, then revoke any legacy automation token.

## Recovery

Retry a failed publish job from its original workflow run. To retry later, run the Release workflow on `master` with its existing stable tag, such as `v3.0.0`; the publish step verifies the npm tarball before treating an existing version as successful.

After the historical baseline is in place, do not create version tags or edit release versions by hand.
34 changes: 34 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
version: 2

updates:
- package-ecosystem: bun
directory: /
schedule:
interval: weekly
day: monday
time: "06:00"
timezone: Etc/UTC
cooldown:
default-days: 7
groups:
dependencies:
patterns:
- "*"
commit-message:
prefix: chore(deps)

- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
time: "06:30"
timezone: Etc/UTC
cooldown:
default-days: 7
groups:
actions:
patterns:
- "*"
commit-message:
prefix: chore(deps)
23 changes: 23 additions & 0 deletions .github/fixtures/consumer/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useState } from "react";
import { Text } from "react-native";
import { Rating } from "react-native-rating";
import type { RatingRenderItemProps } from "react-native-rating";

const renderItem = ({ fill, index }: RatingRenderItemProps) => (
<Text>{`${index + 1}:${fill}`}</Text>
);

export const RatingConsumer = () => {
const [value, setValue] = useState(3.5);

return (
<Rating
accessibilityLabel="Review score"
max={5}
onChange={setValue}
renderItem={renderItem}
step={0.5}
value={value}
/>
);
};
5 changes: 5 additions & 0 deletions .github/fixtures/consumer/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"name": "react-native-rating-consumer",
"private": true,
"type": "module"
}
14 changes: 14 additions & 0 deletions .github/fixtures/consumer/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"compilerOptions": {
"exactOptionalPropertyTypes": true,
"jsx": "react-jsx",
"lib": ["ESNext"],
"module": "ESNext",
"moduleResolution": "bundler",
"noEmit": true,
"skipLibCheck": false,
"strict": true,
"target": "ESNext"
},
"include": ["index.tsx"]
}
57 changes: 57 additions & 0 deletions .github/scripts/check-package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env bash

set -euo pipefail

: "${PACKAGE_TARBALL:?PACKAGE_TARBALL is required}"
: "${REACT_NATIVE_VERSION:?REACT_NATIVE_VERSION is required}"
: "${REACT_TYPES_VERSION:?REACT_TYPES_VERSION is required}"
: "${REACT_VERSION:?REACT_VERSION is required}"

if test "$REACT_NATIVE_VERSION" = "current"; then
REACT_NATIVE_VERSION="$(
node -p "require('./package.json').devDependencies['react-native']"
)"
REACT_TYPES_VERSION="$(
node -p "require('./package.json').devDependencies['@types/react']"
)"
REACT_VERSION="$(node -p "require('./package.json').devDependencies.react")"
fi

TYPESCRIPT_VERSION="$(
node -p "require('./package.json').devDependencies.typescript"
)"

consumer_directory="$(mktemp -d)"
trap 'rm -rf -- "$consumer_directory"' EXIT

cp -R .github/fixtures/consumer/. "$consumer_directory"

(
cd "$consumer_directory"
bun add \
--exact \
--ignore-scripts \
"$PACKAGE_TARBALL" \
"@types/react@$REACT_TYPES_VERSION" \
"react@$REACT_VERSION" \
"react-native@$REACT_NATIVE_VERSION" \
"typescript@$TYPESCRIPT_VERSION"

./node_modules/.bin/tsc --project tsconfig.json

node --input-type=module <<'NODE'
import { createRequire } from "node:module";

const require = createRequire(import.meta.url);
const commonjsEntry = require.resolve("react-native-rating");
const moduleEntry = import.meta.resolve("react-native-rating");

if (!commonjsEntry.endsWith("/lib/commonjs/index.js")) {
throw new Error(`Unexpected CommonJS entry: ${commonjsEntry}`);
}

if (!moduleEntry.endsWith("/lib/module/index.js")) {
throw new Error(`Unexpected module entry: ${moduleEntry}`);
}
NODE
)
121 changes: 121 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
name: CI

on:
merge_group:
pull_request:
push:
branches:
- master

permissions:
contents: read

concurrency:
group: ci-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
check:
name: Check
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install toolchain
uses: jdx/mise-action@9e7f7633ff6f6d6048a9418a68d48f288f50eb14 # v4.2.3
with:
cache: true
version: 2026.7.15
- name: Install dependencies
run: bun ci --ignore-scripts
- name: Check source and package
run: mise run check
- name: Add coverage summary
run: |
node --input-type=commonjs <<'NODE' >> "$GITHUB_STEP_SUMMARY"
const { total } = require("./coverage/coverage-summary.json");
const metrics = ["statements", "branches", "functions", "lines"];
console.log("## Coverage\n");
console.log("| Metric | Covered |\n| --- | ---: |");
for (const metric of metrics) {
console.log(`| ${metric} | ${total[metric].pct}% |`);
}
NODE
- name: Pack checked package
run: |
mkdir -p "$RUNNER_TEMP/package"
bun pm pack \
--filename "$RUNNER_TEMP/package/react-native-rating.tgz" \
--ignore-scripts
- name: Upload coverage
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
if-no-files-found: error
name: coverage
path: coverage
retention-days: 14
- name: Upload package
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
if-no-files-found: error
name: package
path: ${{ runner.temp }}/package/react-native-rating.tgz
retention-days: 7

compatibility:
name: React Native (${{ matrix.label }})
needs: check
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
include:
- label: minimum
react: 19.1.1
react-native: 0.82.1
react-types: 19.1.17
- label: current
react: current
react-native: current
react-types: current
steps:
- name: Check out compatibility fixture
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install toolchain
uses: jdx/mise-action@9e7f7633ff6f6d6048a9418a68d48f288f50eb14 # v4.2.3
with:
cache: true
version: 2026.7.15
- name: Download checked package
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: package
path: ${{ runner.temp }}/package
- name: Check consumer compatibility
env:
PACKAGE_TARBALL: ${{ runner.temp }}/package/react-native-rating.tgz
REACT_NATIVE_VERSION: ${{ matrix.react-native }}
REACT_TYPES_VERSION: ${{ matrix.react-types }}
REACT_VERSION: ${{ matrix.react }}
run: bash .github/scripts/check-package.sh

dependency-review:
name: Dependency review
if: github.event_name == 'pull_request'
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Review dependency changes
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
with:
fail-on-severity: high
Loading