Publish React Compiler to open source

This commit is contained in:
Joe Savona
2024-05-15 10:58:51 -07:00
2573 changed files with 657627 additions and 0 deletions
+247
View File
@@ -0,0 +1,247 @@
name: Commit Artifacts for Meta WWW and fbsource
on:
push:
branches: [main, meta-www, meta-fbsource]
jobs:
download_artifacts:
runs-on: ubuntu-latest
outputs:
www_branch_count: ${{ steps.check_branches.outputs.www_branch_count }}
fbsource_branch_count: ${{ steps.check_branches.outputs.fbsource_branch_count }}
steps:
- uses: actions/checkout@v4
- name: "Check branches"
id: check_branches
run: |
echo "www_branch_count=$(git ls-remote --heads origin "refs/heads/meta-www" | wc -l)" >> "$GITHUB_OUTPUT"
echo "fbsource_branch_count=$(git ls-remote --heads origin "refs/heads/meta-fbsource" | wc -l)" >> "$GITHUB_OUTPUT"
- name: Download and unzip artifacts
uses: actions/github-script@v6
env:
CIRCLECI_TOKEN: ${{secrets.CIRCLECI_TOKEN_DIFFTRAIN}}
with:
script: |
const cp = require('child_process');
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function execHelper(command, options, streamStdout = false) {
return new Promise((resolve, reject) => {
const proc = cp.exec(
command,
options,
(error, stdout) => (error ? reject(error) : resolve(stdout.trim())),
);
if (streamStdout) {
proc.stdout.pipe(process.stdout);
}
});
}
let artifactsUrl = null;
// This is a temporary, dirty hack to avoid needing a GitHub auth token in the circleci
// workflow to notify this GitHub action. Sorry!
let iter = 0;
spinloop: while (iter < 15) {
const res = await github.rest.repos.listCommitStatusesForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: context.sha
});
for (const status of res.data) {
if (/process_artifacts_combined/.test(status.context)) {
switch (status.state) {
case 'pending': {
console.log(`${status.context} is still pending`);
break;
}
case 'failure':
case 'error': {
throw new Error(`${status.context} has failed or errored`);
}
case 'success': {
// The status does not include a build ID, but we can extract it
// from the URL. I couldn't find a better way to do this.
const ciBuildId = /\/facebook\/react\/([0-9]+)/.exec(
status.target_url,
)[1];
if (Number.parseInt(ciBuildId, 10) + '' === ciBuildId) {
artifactsUrl =
`https://circleci.com/api/v1.1/project/github/facebook/react/${ciBuildId}/artifacts`;
console.log(`Found artifactsUrl: ${artifactsUrl}`);
break spinloop;
} else {
throw new Error(`${ciBuildId} isn't a number`);
}
break;
}
default: {
throw new Error(`Unhandled status state: ${status.state}`);
break;
}
}
}
}
iter++;
console.log("Sleeping for 60s...");
await sleep(60_000);
}
if (artifactsUrl != null) {
const {CIRCLECI_TOKEN} = process.env;
const res = await fetch(artifactsUrl, {
headers: {
'Circle-Token': CIRCLECI_TOKEN
}
});
const data = await res.json();
if (!Array.isArray(data) && data.message != null) {
throw `CircleCI returned: ${data.message}`;
}
for (const artifact of data) {
if (artifact.path === 'build.tgz') {
console.log(`Downloading and unzipping ${artifact.url}`);
await execHelper(
`curl -L ${artifact.url} -H "Circle-Token: ${CIRCLECI_TOKEN}" | tar -xvz`
);
}
}
} else {
process.exitCode = 1;
}
- name: Strip @license from eslint plugin and react-refresh
run: |
sed -i -e 's/ @license React*//' \
build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js
- name: Move relevant files for React in www into compiled
run: |
# Move the facebook-www folder into compiled
mkdir ./compiled
mv build/facebook-www ./compiled
# Move ReactAllWarnings.js to facebook-www
mkdir ./compiled/facebook-www/__test_utils__
mv build/__test_utils__/ReactAllWarnings.js ./compiled/facebook-www/__test_utils__/ReactAllWarnings.js
# Move eslint-plugin-react-hooks into facebook-www
mv build/oss-experimental/eslint-plugin-react-hooks/cjs/eslint-plugin-react-hooks.development.js \
./compiled/facebook-www/eslint-plugin-react-hooks.js
# Move unstable_server-external-runtime.js into facebook-www
mv build/oss-experimental/react-dom/unstable_server-external-runtime.js \
./compiled/facebook-www/unstable_server-external-runtime.js
# Move react-refresh-babel.development.js into babel-plugin-react-refresh
mkdir ./compiled/babel-plugin-react-refresh
mv build/oss-experimental/react-refresh/cjs/react-refresh-babel.development.js \
./compiled/babel-plugin-react-refresh/index.js
ls -R ./compiled
- name: Move relevant files for React in fbsource into compiled-rn
run: |
BASE_FOLDER='compiled-rn/facebook-fbsource/xplat/js'
mkdir -p ${BASE_FOLDER}/react-native-github/Libraries/Renderer/
mkdir -p ${BASE_FOLDER}/RKJSModules/vendor/react/{scheduler,react,react-is,react-test-renderer}/
# Move React Native renderer
mv build/react-native/implementations/ $BASE_FOLDER/react-native-github/Libraries/Renderer/
mv build/react-native/shims/ $BASE_FOLDER/react-native-github/Libraries/Renderer/
mv build/facebook-react-native/scheduler/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/scheduler/
mv build/facebook-react-native/react/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react/
mv build/facebook-react-native/react-is/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react-is/
mv build/facebook-react-native/react-test-renderer/cjs/ $BASE_FOLDER/RKJSModules/vendor/react/react-test-renderer/
# Delete OSS renderer. OSS renderer is synced through internal script.
RENDERER_FOLDER=$BASE_FOLDER/react-native-github/Libraries/Renderer/implementations/
rm $RENDERER_FOLDER/ReactFabric-{dev,prod,profiling}.js
rm $RENDERER_FOLDER/ReactNativeRenderer-{dev,prod,profiling}.js
ls -R ./compiled
- name: Add REVISION file
run: |
echo ${{ github.sha }} >> ./compiled/facebook-www/REVISION
echo ${{ github.sha }} >> ./compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION
- uses: actions/upload-artifact@v3
with:
name: compiled
path: compiled/
- uses: actions/upload-artifact@v3
with:
name: compiled-rn
path: compiled-rn/
commit_www_artifacts:
needs: download_artifacts
if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.www_branch_count == '0') || github.ref == 'refs/heads/meta-www' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: builds/facebook-www
- name: Ensure clean directory
run: rm -rf compiled
- uses: actions/download-artifact@v3
with:
name: compiled
path: compiled/
- run: git status -u
- name: Check if only the REVISION file has changed
id: check_should_commit
run: |
if git status --porcelain | grep -qv '/REVISION$'; then
echo "should_commit=true" >> "$GITHUB_OUTPUT"
else
echo "should_commit=false" >> "$GITHUB_OUTPUT"
fi
- name: Commit changes to branch
if: steps.check_should_commit.outputs.should_commit == 'true'
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: |
${{ github.event.head_commit.message }}
DiffTrain build for [${{ github.sha }}](https://github.com/facebook/react/commit/${{ github.sha }})
branch: builds/facebook-www
commit_user_name: ${{ github.actor }}
commit_user_email: ${{ github.actor }}@users.noreply.github.com
create_branch: true
commit_fbsource_artifacts:
needs: download_artifacts
if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.fbsource_branch_count == '0') || github.ref == 'refs/heads/meta-fbsource' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: builds/facebook-fbsource
- name: Ensure clean directory
run: rm -rf compiled
- uses: actions/download-artifact@v3
with:
name: compiled-rn
path: compiled-rn/
- run: git status -u
- name: Check if only the REVISION file has changed
id: check_should_commit
run: |
if git status --porcelain | grep -qv '/REVISION$'; then
echo "should_commit=true" >> "$GITHUB_OUTPUT"
else
echo "should_commit=false" >> "$GITHUB_OUTPUT"
fi
- name: Commit changes to branch
if: steps.check_should_commit.outputs.should_commit == 'true'
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: |
${{ github.event.head_commit.message }}
DiffTrain build for commit https://github.com/facebook/react/commit/${{ github.sha }}.
branch: builds/facebook-fbsource
commit_user_name: ${{ github.actor }}
commit_user_email: ${{ github.actor }}@users.noreply.github.com
create_branch: true
+205
View File
@@ -0,0 +1,205 @@
name: DevTools Check for bug repro
on:
issues:
types: [opened, edited]
issue_comment:
types: [created, edited]
jobs:
check-repro:
runs-on: ubuntu-latest
steps:
- uses: actions/github-script@v3
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const URL_REGEXP = /### Website or app[\r\n]+([^#]+)###/m;
const REPRO_STEPS_REGEXP = /### Repro steps[\r\n]+([^#]+)###/m;
const LABEL_NEEDS_MORE_INFORMATION = "Resolution: Needs More Information";
const LABEL_UNCONFIRMED = "Status: Unconfirmed";
function debug(...args) {
core.info(args.map(JSON.stringify).join(' '));
}
if (context.payload.comment) {
debug('Ignoring comment update.');
return;
}
const user = context.payload.sender.login;
const issue = context.payload.issue;
const body = issue.body;
const urlMatch = body.match(URL_REGEXP);
const reproStepsMatch = body.match(REPRO_STEPS_REGEXP);
const url = urlMatch !== null ? urlMatch[1].trim() : null;
const reproSteps = reproStepsMatch !== null ? reproStepsMatch[1].trim() : null;
if (!url || !reproSteps) {
debug('This issue is not a DevTools bug report.');
return;
}
debug(`found URL "${url}"`);
debug(`found repro steps "${reproSteps}"`);
async function createComment(comment) {
// Format
comment = comment
.split("\n")
.map((line) => line.trim())
.join("\n")
.trim();
await github.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment,
});
}
async function getGitHubActionComments() {
debug(`Loading existing comments...`);
const comments = await github.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});
return comments.data.filter(comment => {
debug(`comment by user: "${comment.user.login}"`);
return comment.user.login === 'github-actions[bot]';
});
}
async function getIssueLabels() {
const issues = await github.issues.listLabelsOnIssue({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});
return issues.data;
}
async function updateIssue(state, assignees = []) {
await github.issues.update({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
state,
assignees,
});
}
async function closeWithComment(comment) {
if (issue.state !== 'open') {
debug(`Issue is not open`);
return;
}
const labels = await getIssueLabels();
const label = labels.find(label => label.name === LABEL_UNCONFIRMED);
if (!label) {
debug(`Issue was not opened via DevTools bug report template`);
return;
}
const comments = await getGitHubActionComments();
if (comments.length > 0) {
debug(`Already commented on issue; won't comment again`);
return;
}
debug(`Missing required information`);
await github.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: [LABEL_NEEDS_MORE_INFORMATION],
});
await createComment(comment);
await updateIssue('closed', [user]);
}
async function openWithComment(comment) {
if (issue.state !== 'closed') {
debug(`Issue is already open`);
return;
}
const labels = await getIssueLabels();
const label = labels.find(label => label.name === LABEL_NEEDS_MORE_INFORMATION);
if (!label) {
debug(`Issue was not tagged as needs information`);
return;
}
const comments = await getGitHubActionComments();
if (comments.length === 0) {
debug(`Issue was closed by someone else; won't reopen`);
return;
}
debug(`Re-opening closed issue`);
await github.issues.removeLabel({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
name: LABEL_NEEDS_MORE_INFORMATION,
});
await createComment(comment);
await updateIssue('open');
}
const PROBABLY_NOT_A_URL_REGEX = /(^Chrome$|^Firefox$| Website)/i;
const COMMENT_HEADER = `
@${user}: We're sorry you've seen this error. ❤️
`.trim();
const COMMENT_FOOTER = `
Please help us by providing a link to a CodeSandbox (https://codesandbox.io/s/new), a repository on GitHub, or a minimal code example that reproduces the problem. (Screenshots or videos can also be helpful if they help provide context on how to repro the bug.)
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
Issues without repros are automatically closed but we will re-open if you update with repro info.
`.trim();
if (url.includes("localhost")) {
closeWithComment(`
${COMMENT_HEADER}
Unfortunately the URL you provided ("localhost") is not publicly accessible. (This means that we will not be able to reproduce the problem you're reporting.)
${COMMENT_FOOTER}
`);
} else if (url.length < 10 || url.match(PROBABLY_NOT_A_URL_REGEX)) {
closeWithComment(`
${COMMENT_HEADER}
It looks like you forgot to specify a valid URL. (This means that we will not be able to reproduce the problem you're reporting.)
${COMMENT_FOOTER}
`);
} else if (reproSteps.length < 25) {
closeWithComment(`
${COMMENT_HEADER}
Unfortunately, it doesn't look like this issue has enough info for one of us to reproduce and fix it though.
${COMMENT_FOOTER}
`);
} else {
openWithComment(`
Thank you for providing repro steps! Re-opening issue now for triage.
`);
}
+32
View File
@@ -0,0 +1,32 @@
name: facebook/react/fuzz_tests
on:
schedule:
- cron: 0 * * * *
push:
branches:
- main
workflow_dispatch:
inputs:
prerelease_commit_sha:
required: false
jobs:
test_fuzz:
if: inputs.prerelease_commit_sha == ''
runs-on: ubuntu-latest
env:
TZ: "/usr/share/zoneinfo/America/Los_Angeles"
steps:
- uses: actions/checkout@v4.1.0
- uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
cache: 'yarn'
- name: Install dependencies
run: yarn install --frozen-lockfile
env:
ELECTRON_SKIP_BINARY_DOWNLOAD: "1"
shell: bash
- name: Run fuzz tests
run: |-
FUZZ_TEST_SEED=$RANDOM yarn test fuzz --ci
FUZZ_TEST_SEED=$RANDOM yarn test --prod fuzz --ci
+46
View File
@@ -0,0 +1,46 @@
# Configuration for stale action workflow - https://github.com/actions/stale
name: 'Manage stale issues and PRs'
on:
schedule:
# Run hourly
- cron: '0 * * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
# --- Issues & PRs ---
# Number of days of inactivity before an issue or PR becomes stale
days-before-stale: 90
# Number of days of inactivity before a stale issue or PR is closed
days-before-close: 7
# API calls per run
operations-per-run: 100
# --- Issues ---
stale-issue-label: "Resolution: Stale"
# Comment to post when marking an issue as stale
stale-issue-message: >
This issue has been automatically marked as stale.
**If this issue is still affecting you, please leave any comment** (for example, "bump"), and we'll keep it open.
We are sorry that we haven't been able to prioritize it yet. If you have any new additional information, please include it with your comment!
# Comment to post when closing a stale issue
close-issue-message: >
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please create a new issue with up-to-date information. Thank you!
# Issues with these labels will never be considered stale
exempt-issue-labels: "Partner,React Core Team,Resolution: Backlog,Type: Bug,Type: Discussion,Type: Needs Investigation,Type: Regression,Type: Feature Request,Type: Enhancement"
# --- PRs ---
stale-pr-label: "Resolution: Stale"
# Comment to post when marking a pull request as stale
stale-pr-message: >
This pull request has been automatically marked as stale.
**If this pull request is still relevant, please leave any comment** (for example, "bump"), and we'll keep it open.
We are sorry that we haven't been able to prioritize reviewing it yet. Your contribution is very much appreciated.
# Comment to post when closing a stale pull request
close-pr-message: >
Closing this pull request after a prolonged period of inactivity. If this issue is still present in the latest release, please ask for this pull request to be reopened. Thank you!
# PRs with these labels will never be considered stale
exempt-pr-labels: "Partner,React Core Team,Resolution: Backlog,Type: Bug,Type: Discussion,Type: Needs Investigation,Type: Regression,Type: Feature Request,Type: Enhancement"