Files
Alex Hunt 88a6ace533 Fix JS API change false positives for out-of-sync branches (#56871)
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/56871

`diff-js-api-changes` was posting false positive "JavaScript API change detected" warnings on PRs that never modified `ReactNativeApi.d.ts`.

This happened because the action ran `git merge-base` against limited local history (`git fetch --depth=500`), which couldn't find the common ancestor for branches that were far behind main — including (often) pick requests to release branches. The fallback wrote an empty "before" snapshot, causing the entire API surface to appear newly added.

{F1989977284}

#### Changes

- Query the GitHub API first — if the PR doesn't touch `ReactNativeApi.d.ts`, skip the diff entirely.
- When the snapshot is touched, use the GitHub compare API to resolve the merge base instead of relying on local git history.
- Limit the check to PRs targeting `main` or `*-stable` branches.

Changelog: [Internal]

Reviewed By: christophpurrer

Differential Revision: D105572432

fbshipit-source-id: 20e5db01c9e6b51acb55548746c8fd512a363274
2026-05-20 12:01:36 -07:00

95 lines
3.7 KiB
YAML

name: diff-js-api-changes
description: Check for breaking changes in the public React Native JS API
outputs:
message:
description: Formatted markdown message describing API changes, or empty if no changes
value: ${{ steps.format_output.outputs.message }}
runs:
using: composite
steps:
- name: Resolve API diff inputs
id: api_diff
uses: actions/github-script@v8
with:
script: |
// Check if we are targeting main or a stable branch
const baseRef = context.payload.pull_request.base.ref;
if (baseRef !== 'main' && !baseRef.endsWith('-stable')) {
core.setOutput('changed', false);
return;
}
// Check if the diff touches ReactNativeApi.d.ts
const files = await github.paginate(github.rest.pulls.listFiles, {
...context.repo,
pull_number: context.payload.pull_request.number,
});
const changed = files.some(f => f.filename === 'packages/react-native/ReactNativeApi.d.ts');
core.setOutput('changed', changed);
if (!changed) return;
// Calculate merge base
const {data} = await github.rest.repos.compareCommits({
...context.repo,
base: context.payload.pull_request.base.ref,
head: context.payload.pull_request.head.sha,
});
core.setOutput('merge_base', data.merge_base_commit.sha);
- name: Fetch commits and extract API snapshots
if: steps.api_diff.outputs.changed == 'true'
shell: bash
env:
SCRATCH_DIR: ${{ runner.temp }}/diff-js-api-changes
run: |
mkdir -p $SCRATCH_DIR
git fetch origin "${{ steps.api_diff.outputs.merge_base }}" --depth=1
git fetch origin "${{ github.event.pull_request.head.sha }}" --depth=1
git show "${{ steps.api_diff.outputs.merge_base }}":packages/react-native/ReactNativeApi.d.ts > $SCRATCH_DIR/ReactNativeApi-before.d.ts \
|| echo "" > $SCRATCH_DIR/ReactNativeApi-before.d.ts
git show "${{ github.event.pull_request.head.sha }}":packages/react-native/ReactNativeApi.d.ts > $SCRATCH_DIR/ReactNativeApi-after.d.ts \
|| echo "" > $SCRATCH_DIR/ReactNativeApi-after.d.ts
- name: Run breaking change detection
if: steps.api_diff.outputs.changed == 'true'
shell: bash
env:
SCRATCH_DIR: ${{ runner.temp }}/diff-js-api-changes
run: |
node ./scripts/js-api/diff-api-snapshot \
$SCRATCH_DIR/ReactNativeApi-before.d.ts \
$SCRATCH_DIR/ReactNativeApi-after.d.ts \
> $SCRATCH_DIR/output.json
- name: Format output message
id: format_output
shell: bash
env:
SCRATCH_DIR: ${{ runner.temp }}/diff-js-api-changes
run: |
if [ ! -f "$SCRATCH_DIR/output.json" ]; then
echo "message=" >> $GITHUB_OUTPUT
exit 0
fi
RESULT=$(cat $SCRATCH_DIR/output.json | jq -r '.result // empty')
if [ -z "$RESULT" ] || [ "$RESULT" = "NON_BREAKING" ]; then
echo "message=" >> $GITHUB_OUTPUT
exit 0
fi
# Use delimiter for multiline output
{
echo "message<<EOF"
echo "> [!WARNING]"
echo "> **JavaScript API change detected**"
echo ">"
echo "> This PR commits an update to \`ReactNativeApi.d.ts\`, indicating a change to React Native's public JavaScript API."
echo ">"
echo "> - Please include a **clear changelog message**."
echo "> - This change will be subject to additional review."
echo ">"
echo "> This change was flagged as: \`${RESULT}\`"
echo "EOF"
} >> $GITHUB_OUTPUT