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 00000000000000..c58d63e5e8edff --- /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 39a0e1c4922a15..06daf7ee8378c8 100644 --- a/.github/workflows/danger-pr.yml +++ b/.github/workflows/danger-pr.yml @@ -15,13 +15,15 @@ permissions: jobs: danger: runs-on: ubuntu-latest - if: github.repository == 'facebook/react-native' + if: github.repository == 'coado/react-native' steps: - uses: actions/checkout@v4 - name: Setup Node.js 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/packages/react-native/ReactNativeApi.d.ts b/packages/react-native/ReactNativeApi.d.ts new file mode 100644 index 00000000000000..86fe96261c7a23 --- /dev/null +++ b/packages/react-native/ReactNativeApi.d.ts @@ -0,0 +1,4 @@ + +export interface ReactNativeApi { + foo: string, +} diff --git a/private/react-native-bots/dangerfile.js b/private/react-native-bots/dangerfile.js index ddec0bdbc60d13..1bff20819a9709 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 =