xref: /expo/CONTRIBUTING.md (revision 3d20bbfa)
1e12a7039SBrent Vatne# Contributing to the Expo SDK
240fd0347SVille Immonen
3275a6932SEvan Bacon- [�� Download and Setup](#-download-and-setup)
4d4ca1135Sguanw- [✍️ Editing SDK Packages](#%EF%B8%8F-editing-sdk-packages)
5e12a7039SBrent Vatne  - [Style](#style)
6275a6932SEvan Bacon  - [Extra Credit](#extra-credit)
7275a6932SEvan Bacon- [⏱ Testing Your Changes](#-testing-your-changes)
8275a6932SEvan Bacon  - [✅ Unit Testing](#-unit-testing)
9275a6932SEvan Bacon  - [�� E2E Testing](#-e2e-testing)
10275a6932SEvan Bacon- [�� Updating Documentation](#-updating-documentation)
11275a6932SEvan Bacon- [�� Writing a Commit Message](#-writing-a-commit-message)
12275a6932SEvan Bacon- [�� Before Submitting](#-before-submitting)
13275a6932SEvan Bacon  - [Extra Credit](#extra-credit-1)
1440fd0347SVille Immonen
15e12a7039SBrent VatneThanks for the help! We currently review PRs for `packages/`, `docs/`, `templates/`, `guides/`, `apps/`, and markdown files.
1640fd0347SVille Immonen
17e12a7039SBrent VatneExpo for Web code is easy to test and contribute to compared to the native code, and we welcome all contributions to it. You may find that some of the web features you are looking for actually live in the [expo-cli repo](https://github.com/expo/expo-cli).
18e12a7039SBrent Vatne
19e12a7039SBrent VatneWe recommend that folks interested in contributing to the SDK use the `apps/bare-expo` project in their SDK development workflow instead of the Expo client. The Expo client itself (in the `ios/` and `android/` directories) are difficult to setup and require API tokens.
20e12a7039SBrent Vatne
21492d6b85SKudo ChienThe `bare-expo` project includes most of the Expo SDK and runs the JavaScript code from `apps/test-suite` to allow you to easily write and run E2E tests for iOS, Android, and web for any given SDK package. Unit tests can be written within the SDK package itself. When pushed to the remote, CI will run this project with Detox for Android/iOS and Puppeteer for web and report the results on your pull request.
22e12a7039SBrent Vatne
23e12a7039SBrent VatneManual smoke tests are included in `apps/native-component-list`, this is a good fit for demos or tests that require physical interactions. This is particularly useful if you are testing interactions with UI components, or there is something that is very difficult to test in an automated way but would be easy to verify through manual interaction.
24e12a7039SBrent Vatne
25e12a7039SBrent Vatne> �� How does `bare-expo` relate to `test-suite`?
26e12a7039SBrent Vatne>
271ef3e21eSHays Stanford> `bare-expo` is a bare workflow app that links all of the Expo SDK dependencies in the `packages/` directory in order to be able to run projects in the `apps/` directory in the bare workflow rather than the Expo client. It currently only runs `test-suite`. `test-suite` is a regular managed workflow Expo app with some custom code to turn it into a test runner. If you run `expo start` in the `test-suite` directory you can load the project in Expo client. `bare-expo` imports the `test-suite` app root component and uses it as its own root component.
2840fd0347SVille Immonen
29275a6932SEvan Bacon## �� Download and Setup
3040fd0347SVille Immonen
3132cf793dSBrent Vatne> �� The development environment for this repository does not support Windows; WSL is required to contribute from Windows.
32d01a0a7bSBrent Vatne
3332cf793dSBrent Vatne1. If you are an Expo team member, clone the repository. If you are an external contributor, [fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device. (`git remote add upstream [email protected]:expo/expo.git` ��). You can use `git clone --depth 1 --single-branch --branch main [email protected]:expo/expo.git`, discarding most of branches and history to clone it faster.
3432cf793dSBrent Vatne2. Install [direnv](https://direnv.net/). On macOS: `brew install direnv`. Don't forget to install the [shell hook](https://direnv.net/docs/hook.html) to your shell profile.
3532cf793dSBrent Vatne3. Install [git-lfs](https://git-lfs.github.com/). On macOS: `brew install git-lfs`.
3632cf793dSBrent Vatne4. Install [Node 16 LTS](https://nodejs.org/).
3740fd0347SVille Immonen
3832cf793dSBrent Vatne### Set up documentation
3932cf793dSBrent Vatne
4032cf793dSBrent VatneIf you plan to contribute to the documentation, run `npm run setup:docs`.
4132cf793dSBrent Vatne
4232cf793dSBrent Vatne### Set up Android
4332cf793dSBrent Vatne
4432cf793dSBrent VatneIf you plan to contribute to Android, run `npm run setup:native`. This command does the following for you:
4540fd0347SVille Immonen
46275a6932SEvan Bacon- Downloads submodules (like `react-native`) with `git submodule update --init`
47275a6932SEvan Bacon- Ensures Yarn is installed
48275a6932SEvan Bacon- Ensures your computer is set up for React Native (will install the Android NDK if it's not present)
49275a6932SEvan Bacon- Downloads the Node packages (`yarn install`)
5040fd0347SVille Immonen
514a51ff9aSBartłomiej KlocekMake sure that you're using Java 11 (e.g. Azul Zulu JDK 11.0.15+10). `ANDROID_SDK_ROOT` environmental variable should be set or configured via `local.properties` file in `android` folder of the native project you're working with.
522cfc8c5aSJakub
5332cf793dSBrent Vatne### Set up iOS
5432cf793dSBrent Vatne
5532cf793dSBrent VatneIf you will be working with the iOS project, ensure **ruby 2.7** is installed on your machine. macOS comes with ruby 2.6, which is not supported in this repository; if you use Homebrew you can just run `brew install [email protected]`. You will also need to have the latest stable version of Xcode installed, along with Xcode command line tools.
5632cf793dSBrent Vatne
5732cf793dSBrent Vatne### Verify native installation is successful
5832cf793dSBrent Vatne
5932cf793dSBrent Vatne1. Navigate to the bare sandbox project `cd apps/bare-expo`
6032cf793dSBrent Vatne2. Run the project on any platform (maybe start with web; it's the fastest! ��)
6140fd0347SVille Immonen
62275a6932SEvan Bacon   - Web: `yarn web`
63275a6932SEvan Bacon   - iOS: `yarn ios`
64275a6932SEvan Bacon   - Android: `yarn android`
65dd7c660dSIgor Ordecha   - If you are working on Linux, make sure to set the `TERMINAL` environment variable to your preferred terminal application. (e.g. `export TERMINAL="konsole"`)
662cfc8c5aSJakub
6732cf793dSBrent Vatne3. You are now running the `test-suite` app via the `bare-expo` project. The next section explains how you can begin to make changes to SDK packages.
6840fd0347SVille Immonen
69275a6932SEvan Bacon> If this didn't work for you as described, please [open an issue.](https://github.com/expo/expo/issues/new/choose)
7040fd0347SVille Immonen
71e12a7039SBrent Vatne## ✍️ Editing SDK Packages
7240fd0347SVille Immonen
73e12a7039SBrent VatneAll Expo SDK packages can be found in the `packages/` directory. These packages are automatically linked to the projects in the `apps/` directory, so you can edit them in-place and see the changes in the running app.
7440fd0347SVille Immonen
75e12a7039SBrent Vatne <!-- (meaning any iOS, Android, web, or API changes can be tested from `apps/bare-expo/`). -->
762cfc8c5aSJakub
77275a6932SEvan Bacon1. Navigate to a package you want to edit. Ex: `cd packages/expo-constants`
78275a6932SEvan Bacon2. Start the TypeScript build in watch mode: `yarn build`
79275a6932SEvan Bacon3. Edit code in that package's `src/` directory
80275a6932SEvan Bacon4. Play with your changes on a simulator or device through `bare-expo`:
81275a6932SEvan Bacon   - Add or modify a file named after the API you're working on. Ex: `apps/test-suite/tests/Constants.js`
82e12a7039SBrent Vatne   - To see native changes, you will need to run the `test-suite` with the `apps/bare-expo` project using `yarn <android | ios | web>`.
83e12a7039SBrent Vatne   - If you are only making JavaScript changes, you can run `test-suite` from the `apps/test-suite` project using `expo start`.
84492d6b85SKudo Chien   - To run the full test suite with Puppeteer or Detox, you can run the tests `yarn test:<android | ios | web>`.
85275a6932SEvan Bacon5. You can edit a package's native code directly from its respective folder in the `packages/` directory or by opening `bare-expo` in a native editor:
86de43828eSVojtech Novak   - Navigate to the `bare-expo` app directory: `cd apps/bare-expo`
87275a6932SEvan Bacon   - Android Studio: `yarn edit:android`
88275a6932SEvan Bacon   - Xcode: `yarn edit:ios`
89275a6932SEvan Bacon   - Remember to **rebuild** the native project whenever you make a native change
9040fd0347SVille Immonen
91e12a7039SBrent Vatne### Style
92e12a7039SBrent Vatne
93e12a7039SBrent VatneAll modules should adhere to the style guides which can be found here:
94e12a7039SBrent Vatne
95e12a7039SBrent Vatne- [Guide to Unimodule Development](guides/Expo%20Universal%20Module%20Infrastructure.md)
96e12a7039SBrent Vatne- [Expo JS Style Guide](guides/Expo%20JavaScript%20Style%20Guide.md) (also mostly applies to TypeScript)
971cd978b1STomasz Sapeta- [Updating Changelogs](guides/contributing/Updating%20Changelogs.md)
98e12a7039SBrent Vatne
99275a6932SEvan Bacon### Extra Credit
10040fd0347SVille Immonen
101275a6932SEvan Bacon- The React Native dev tools are currently disabled in our fork [#5602](https://github.com/expo/expo/issues/5602). You can hack around this by cloning React Native outside this repo, then copying the contents `react-native/React/DevSupport` into `expo/react-native-lab/react-native/React/DevSupport` (this will only enable the shake gesture, CMD+R won't work yet).
102275a6932SEvan Bacon- We use a fork of `react-native` in this repo; this fork is located at `react-native-lab/react-native` (you can make changes or cherry-picks from here if you want). It diverges the minimal amount necessary from the `react-native` version in its `package.json`.
103275a6932SEvan Bacon- All of the package's `build/` code should be committed. This is because it is simpler to reproduce issues if all contributors are running the same code and so we don't need to rebuild dozen of packages locally on every `git pull` or `git checkout` operation.
104275a6932SEvan Bacon- We use a unified set of basic Bash scripts and configs called `expo-module-scripts` to ensure everything runs smoothly (TypeScript, Babel, Jest, etc...).
10540fd0347SVille Immonen
106275a6932SEvan Bacon## ⏱ Testing Your Changes
10740fd0347SVille Immonen
108275a6932SEvan Bacon> You'll need write about how you tested your changes in the PR under the **Test Plan** section.
10940fd0347SVille Immonen
110275a6932SEvan BaconThe best way to get your changes merged is to build good tests for them! We have three different kinds of tests: unit-tests, automated E2E tests, and demos (adding tests that you notice are missing is a great way to become my friend ��)!
111275a6932SEvan Bacon
112275a6932SEvan Bacon### ✅ Unit Testing
113275a6932SEvan Bacon
114275a6932SEvan Bacon1. Create a test for your feature in the appropriate package's `src/__tests__` directory (if the file doesn't exist already, create it with the `*-test.ts` or `*-test.tsx` extension).
11542588157SBrent Vatne2. Any new bridged native functions have to be added to the [jest-expo](https://github.com/expo/expo/blob/main/packages/jest-expo/src/preset/expoModules.js) package to ensure they are mocked. To help you do this more easily, we've written a tool and a guide on how to do this. Check out [Generating Jest Mocks](https://github.com/expo/expo/blob/main/guides/Generating%20Jest%20Mocks.md)!
11662073571SThorben Primke3. Run the test with `yarn test` and ensure it handles all platforms (iOS, Android, and web). If the feature doesn't support a platform, then you can exclude it by putting your test in a file with a platform extension like: `-test.ios.ts`, `-test.native.ts`, `-test.web.ts`...
11762073571SThorben Primke4. You can also test platforms one at a time by pressing <kbd>X</kbd> and selecting the platform you want to test!
118275a6932SEvan Bacon
119275a6932SEvan Bacon### �� E2E Testing
120275a6932SEvan Bacon
121275a6932SEvan Bacon1. Write your tests in `apps/test-suite/tests`
122275a6932SEvan Bacon   - These tests are written with a non-feature-complete version of Jasmine that runs on the Android and iOS clients, so no special features like snapshot testing will be available.
123275a6932SEvan Bacon   - If you created a new test file, be sure to add it in `apps/test-suite/TestUtils.js`. This is where you can do platform exclusion. Use `global.DETOX` to test for iOS tests, and `ExponentTest.isInCI` to test for Android Device Farm.
124492d6b85SKudo Chien2. Run your tests locally from the `bare-expo` directory with `yarn test:android`, `yarn test:ios`, or `yarn test:web`.
125275a6932SEvan Bacon   - It's important you test locally because native CI tests can be fragile, take a while to finish, and be frustrating when they fail.
126275a6932SEvan Bacon   - When testing for web, you can set `headless: false` in the `apps/bare-expo/jest-puppeteer.config.js` to watch the tests live. You can also execute `await jestPuppeteer.debug();` in `apps/bare-expo/e2e/TestSuite-test.web.js` to pause the tests and debug them!
127275a6932SEvan Bacon3. Remember to try and get your feature running on as many platforms as possible.
128275a6932SEvan Bacon
129275a6932SEvan BaconThanks again for helping to make sure that Expo is stable for everyone!
130275a6932SEvan Bacon
131275a6932SEvan Bacon## �� Updating Documentation
132275a6932SEvan Bacon
133*3d20bbfaSAman MittalOur docs are made with [Next.js](https://github.com/vercel/next.js). They're located in the **docs/** directory. For more information look at the [`docs/README.md`](/docs/README.md).
134275a6932SEvan Bacon
135275a6932SEvan Bacon**TL;DR:**
136275a6932SEvan Bacon
137*3d20bbfaSAman Mittal1. Navigate to the **docs/** directory and run `yarn`.
138edee0724SAman Mittal2. Start the project with `yarn dev` (make sure you don't have another server running on port `3002`).
139*3d20bbfaSAman Mittal3. Navigate to the docs you want to edit: `cd docs/pages/`.
140*3d20bbfaSAman Mittal4. If you update an older version, ensure the relevant changes are copied into `docs/pages/versions/unversioned/` for API docs.
141275a6932SEvan Bacon
142275a6932SEvan Bacon## �� Writing a Commit Message
143275a6932SEvan Bacon
144275a6932SEvan Bacon> If this is your first time committing to a large public repo, you could look through this neat tutorial: ["How to Write a Git Commit Message"](https://chris.beams.io/posts/git-commit/)
145275a6932SEvan Bacon
146275a6932SEvan BaconCommit messages are most useful when formatted like so: `[platform][api] Title`. For example if you fix a bug in the package `expo-video` for iOS, you could write: `[ios][video] Fixed black screen bug that appears on older devices`.
147275a6932SEvan Bacon
148275a6932SEvan Bacon## �� Before Submitting
149275a6932SEvan Bacon
150275a6932SEvan BaconTo help keep CI green, please make sure of the following:
151275a6932SEvan Bacon
152eae5f0b1STomasz Sapeta- Remember to add a concise description of any user-facing changes to `CHANGELOG.md` file in the package you've changed or [root's CHANGELOG.md](/CHANGELOG.md) if your changes don't apply to any package. This is especially helpful for breaking changes!
153275a6932SEvan Bacon- If you modified anything in `packages/`:
154275a6932SEvan Bacon  - You transpiled the TypeScript with `yarn build` in the directory of whichever package you modified.
155275a6932SEvan Bacon  - Run `yarn lint --fix` to fix the formatting of the code. Ensure that `yarn lint` succeeds without errors or warnings.
156275a6932SEvan Bacon  - Run `yarn test` to ensure all existing tests pass for that package, along with any new tests you would've written.
157275a6932SEvan Bacon  - All `console.log`s or commented out code blocks are removed! :]
158275a6932SEvan Bacon- If you edited the `docs/`:
159275a6932SEvan Bacon  - Any change to the current SDK version should also be in the unversioned copy as well. Example:
160275a6932SEvan Bacon    - You fixed a typo in `docs/pages/versions/vXX.0.0/sdk/app-auth.md`
161275a6932SEvan Bacon    - Ensure you copy that change to: `docs/pages/versions/unversioned/sdk/app-auth.md`
162275a6932SEvan Bacon  - You don't need to run the docs tests locally. Just ensure the links you include aren't broken, and the format is correct!
163275a6932SEvan Bacon
164275a6932SEvan Bacon### Extra Credit
165275a6932SEvan Bacon
166275a6932SEvan Bacon- Our CI tests will finish early if you didn't make changes to certain directories. If you want to **get results faster** then you should make changes to `docs/` in one PR, and changes to anything else in another!
167