From b41b924b2d1a2cb6352a6b5d1faac3f17f5015ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dawid=20Ma=C5=82ecki?= Date: Tue, 1 Jul 2025 08:58:15 -0700 Subject: [PATCH] Add diff-api-snapshot action to danger (#52045) Summary: This PR connects breaking change detection with a danger bot. The action takes snapshot from main branch and from the PR as inputs to`diff-api-snapshot` (saved in runner temp directory). ## Changelog: [Internal] For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests Pull Request resolved: https://github.com/facebook/react-native/pull/52045 Reviewed By: huntie Differential Revision: D76735630 Pulled By: coado fbshipit-source-id: 9208117340c1e0bf10d58b67892727717d22e62f --- .../diff-js-api-breaking-changes/action.yml | 23 +++++++++++++++++++ .github/workflows/danger-pr.yml | 2 ++ private/react-native-bots/dangerfile.js | 21 +++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 .github/actions/diff-js-api-breaking-changes/action.yml diff --git a/.github/actions/diff-js-api-breaking-changes/action.yml b/.github/actions/diff-js-api-breaking-changes/action.yml new file mode 100644 index 00000000000..25ec197ab02 --- /dev/null +++ b/.github/actions/diff-js-api-breaking-changes/action.yml @@ -0,0 +1,23 @@ +name: diff-js-api-breaking-changes +description: Check for breaking changes in the public React Native JS API +runs: + using: composite + steps: + - name: Fetch snapshot from PR head + shell: bash + env: + SCRATCH_DIR: ${{ runner.temp }}/diff-js-api-breaking-changes + run: | + mkdir $SCRATCH_DIR + git fetch --depth=1 origin ${{ github.event.pull_request.head.sha }} + git show ${{ github.event.pull_request.head.sha }}:packages/react-native/ReactNativeApi.d.ts > $SCRATCH_DIR/ReactNativeApi-after.d.ts \ + || echo "" > $SCRATCH_DIR/ReactNativeApi.d.ts + - name: Run breaking change detection + shell: bash + env: + SCRATCH_DIR: ${{ runner.temp }}/diff-js-api-breaking-changes + run: | + node ./scripts/diff-api-snapshot \ + ${{ github.workspace }}/packages/react-native/ReactNativeApi.d.ts \ + $SCRATCH_DIR/ReactNativeApi-after.d.ts \ + > $SCRATCH_DIR/output.json diff --git a/.github/workflows/danger-pr.yml b/.github/workflows/danger-pr.yml index 39a0e1c4922..cf28b788105 100644 --- a/.github/workflows/danger-pr.yml +++ b/.github/workflows/danger-pr.yml @@ -22,6 +22,8 @@ jobs: uses: ./.github/actions/setup-node - name: Run yarn install uses: ./.github/actions/yarn-install + - name: Run diff-js-api-breaking-changes + uses: ./.github/actions/diff-js-api-breaking-changes - name: Danger run: yarn danger ci --use-github-checks --failOnErrors working-directory: private/react-native-bots diff --git a/private/react-native-bots/dangerfile.js b/private/react-native-bots/dangerfile.js index ddec0bdbc60..1bff20819a9 100644 --- a/private/react-native-bots/dangerfile.js +++ b/private/react-native-bots/dangerfile.js @@ -11,6 +11,8 @@ 'use strict'; const {danger, fail, warn} = require('danger'); +const fs = require('fs'); +const path = require('path'); const body = danger.github.pr.body?.toLowerCase() ?? ''; @@ -28,6 +30,25 @@ const isFromPhabricator = body_contains('differential revision:'); // Provides advice if a summary section is missing, or body is too short const includesSummary = body_contains('## summary', 'summary:'); +const snapshot_output = JSON.parse( + fs.readFileSync( + path.join( + process.env.RUNNER_TEMP, + 'diff-js-api-breaking-changes/output.json', + ), + 'utf8', + ), +); +if (snapshot_output && snapshot_output.result !== 'NON_BREAKING') { + const title = ':exclamation: JavaScript API change detected'; + const idea = + 'This PR commits an update to ReactNativeApi.d.ts, indicating a change to React Native's public JavaScript API. ' + + 'Please include a clear changelog message. ' + + 'This change will be subject to extra review.\n\n' + + `This change was flagged as: ${snapshot_output.result}`; + warn(`${title} - ${idea}`); +} + const hasNoUsefulBody = !danger.github.pr.body || danger.github.pr.body.length < 50; const hasTooShortAHumanSummary =