Code Monkey home page Code Monkey logo

appr's Introduction

appr

npm version travis" Maintenance Status

Automatically Deploy Pull Requests for Create React Native App and Expo

demo


appr builds and deploys pull requests in your create-react-native-app (and other Expo-based) projects, and replies with a link you can open directly on your device or emulator.

Compatibility warning ⚠️

As of Expo SDK 26, the Expo iOS client is no longer able to open QR codes due to Apple App Store limitations. We are investigating on how to adapt appr to work with newer version of Expo iOS. In the meantime, appr only works for Android testing workflows and Expo SDK versions 25 and older on iOS.

Etymology /ɛtɪˈmɒlədʒi/

appr /ˈapə/

noun

  • appr - Pull Request Review Apps for React Native
  • appr - Portmanteaux of app and PR.
  • appr - Throwback to Web 2.0, when everything was bettr

What are "Review Apps"?

Mature technical organizations peer-review their code. Reviewing code on GitHub is simple enough: for most well-crafted pull requests, you can review the code diff in your browser, and either approve the changes, or request further improvements.

Testing another developer's changes isn't quite as easy. Typically, you will have to stash any work in progress in your own workspace, pull down the remote branch, install dependencies, compile and start the application before you can verify that the changes work as intended.

Since it was launched, I've loved Heroku's GitHub-integrated Review Apps. As part of your branch build, Heroku will spin up a new review instance of your application, which you can then access with a direct link from your GitHub pull request. Netlify offers the same functionality for deploying static websites.

Unfortunately, a one-click workflow like this doesn't exist for mobile development. To add insult to injury, the ramp-up time to test mobile app changes on your local device can be much longer than for web applications.

Enter appr. Built on Expo and inspired by Expo Sketch, appr aims to make peer-reviewing React Native app code as easy as static websites. appr creates a new Expo Release Channel for every PR or branch you enable it on and automatically pushes your code to the release channel on every change.

Getting started

Add appr and exp to your project.

  yarn add --dev appr exp

Or, using npm:

  npm install --dev appr exp

exp, the Expo CLI, is a required peer dependency. In versions 1.x of appr it was installed by default, so if your'e upgrading to [email protected], please install exp manually.

Add the appr task to the scripts section of your package.json:

  scripts: {
+   "appr": "appr",
  }

Next, configure one of the currently supported CI environments:

Contributions for other CI platforms welcome.

Limitations

There are a few limitations you should be aware of. appr is currently not able to deploy:

  1. React Native apps started with something other than create-react-native-app or Expo.
  2. Ejected React Native apps containing custom native module dependencies.
  3. Pull Requests from forked repositories. This is due to Travis and Circle security policies (wisely) not exposing secure environment variables to forked builds. (Circle CI allows you to disable this setting, but it is not recommended!)

Contributions and ideas for solutions welcome.

Configuring Travis

Travis CI is free for open source projects, and offers paid plans for private repositories. To get started, create an account on Travis using your GitHub login.

Add .travis.yml to your project

Add the following to your .travis.yml:

language: node_js
node_js:
  - "node"
cache: yarn
script:
  - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then yarn appr; fi'

This will configure your Travis build to use the latest Node.js and Yarn, and ensure that the appr build only runs on Pull Request builds.

(Optional) Pushing non-PR branches

You may also want to automatically push some target branches, e.g. your develop or master branches to a release channel to test your integrated code. In that case, you can whitelist the branches to release in your .travis.yml:

script:
  - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ] || [ "$TRAVIS_BRANCH" == "master" ]; then yarn appr; fi'

(Optional) Running tests

It's advisable to run your unit tests before deploying review apps. You can do this by adding other steps in the script section, and always leaving the appr step last:

script:
+ - yarn ci-test-command
  - 'if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then yarn appr; fi'

Note that the default test command in create-react-native-app runs Jest in --watch mode, which will hang forever. You can either change the test script in your package.json, or, or override the test command as above.

Enable Travis

The final step is to enable Travis CI on your repository. Log into your Travis account, and turn on the build for your project in your Profile.

After enabled, you'll be taken to your project build page. Before triggering the first build, you'll need to add a few secure environment variables to your build under More options > Settings:

  • EXP_USERNAME - Exponent username, under which to publish the review apps. Use your main account, or create a new one for review apps. All review apps will be unlisted, so only you can see them in your app listings.
  • EXP_PASSWORD - Exponent password for the publish user.
  • GITHUB_USERNAME - A user account you want to use for posting the review app links. Use your own, or create a new "bot" account and grant them access to your repo.
  • GITHUB_TOKEN - A Personal API Token of the user with access to the repository. If the repository is private, the token needs to be granted the full repo scope. For public repositories, the public_repo scope is enough.

Test it

You should now be able to create a new branch, make changes, and open a pull request. If the stars are aligned, the Travis build should publish the app to Expo!

Configuring Circle CI

Circle CI offers one free build container for public and private repositories. To get started, create an account on Circle CI using your GitHub login.

Add circle.yml to your project

Add the following to your circle.yml:

dependencies:
  override:
    - yarn
machine:
  node:
    version: 6.9
deployment:
  appr:
    branch: /.*/
    commands:
      - 'if [ "$CI_PULL_REQUEST" != "" ]; then yarn appr; fi'

This will configure your Circle build to use the latest Node.js and Yarn (optional), and ensure that the appr build only runs on Pull Request builds.

(Optional) Pushing non-PR branches

You may also want to automatically push some target branches, e.g. your develop or master branches to a release channel to test your integrated code. In that case, you can whitelist the branches to release in your circle.yml:

deployment:
  appr:
    branch: /.*/
    commands:
      - 'if [ "$CI_PULL_REQUEST" != "" ] || [ "$CIRCLE_BRANCH" == "master" ]; then yarn appr; fi'

(Optional) Running tests

Circle CI will automatically run your tests before the deployment. Note that the default test command in create-react-native-app runs Jest in --watch mode, which will hang forever. You can either change the test script in your package.json, or, or override the test command in circle.yml:

test:
  override:
    - yarn ci-test-command

Enable Circle CI

The final step is to enable Circl CI on your repository. Log into your Circle CI account, and turn on the build for your project.

After enabled, you'll be taken to your project build page. Before triggering the first build, you'll need to add a few secure environment variables to your build under [Gear icon] > Settings > Environment variables:

  • EXP_USERNAME - Exponent username, under which to publish the review apps. Use your main account, or create a new one for review apps. All review apps will be unlisted, so only you can see them in your app listings.
  • EXP_PASSWORD - Exponent password for the publish user.
  • GITHUB_USERNAME - A user account you want to use for posting the review app links. Use your own, or create a new "bot" account and grant them access to your repo.
  • GITHUB_TOKEN - A Personal API Token of the user with access to the repository. If the repository is private, the token needs to be granted the full repo scope. For public repositories, the public_repo scope is enough.

Optionally, you can enable Advanced settings > Only build pull requests to avoid running build on branches that do not have open pull requests.

Test it

You should now be able to create a new branch, make changes, and open a pull request. If the stars are aligned, the Circle CI build should publish the app to Expo!

Configuring other CIs

If your preferred CI is not explicitly supported by appr, but supports building GitHub pull requests, you can use it by defining environment variables as shown in the default config file.

Contributing

Improvements and additions welcome. For large changes, please submit a discussion issue before jumping to coding; we'd hate you to waste the effort.

In lieu of a formal style guide, follow the included eslint rules, and use Prettier to format your code.

Maintenance Status

Archived: This project is no longer maintained by Formidable. We are no longer responding to issues or pull requests unless they relate to security concerns. We encourage interested developers to fork this project and make it their own!

appr's People

Contributors

boygirl avatar conrad-vanl avatar jevakallio avatar krivachy avatar tonyxiao avatar xcarpentier avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

appr's Issues

Use Expo release channels instead of package namespacing

Expo has rolled out support for official release channels. These are a lot more elegant way of what we are currently solving by namespacing the package name with a branch name.

PR #22 adds release channel support. The scope of that PR is to use release channels as separate argument, but instead we might want to just use that as the primary mechanism.

`yarn appr` returns "Error starting tunnel"

Error starting tunnel: Error: {"status_code":400,"msg":"failed to deserialize request parameter","details":{"err":{"Type":{}}}}

Running yarn appr gives an error. It publishes the pr branch to the main expo project (in this case https://exp.host/@marcdel/cheese-log), but the returned QR code is invalid because the PR branch "experience" is unavailable (exp://exp.host/@marcdel/cheese-log-add-appr).

You can see the associated build here.
https://travis-ci.org/solid-af/cheese-log#L277

Make GitHub comments less spammy

Currently appr will create a new comment for every build in an open PR - most commonly this means for every push, which can get a bit spammy.

Consider making the user experience better by amending existing comments, or if we still want to post a new comment every time, at least collapsing the content of older comments.

Danger does this quite well. We could see if we can use Danger internally, or more likely, just get inspiration of how it works since we may not want the full danger comment format.

Error Pushing Packages to Expo

After the latest release a2520e3d97f08356b950fc29558dc4c49615736 I'm getting an error.

Running on Travis on OSX:

[exp] Invalid Version: undefined
[exp] TypeError: Invalid Version: undefined
    at new SemVer (/Users/travis/build/companyApp/company-ui/node_modules/semver/semver.js:279:11)
    at Function.major (/Users/travis/build/companyApp/company-ui/node_modules/semver/semver.js:551:10)
    at /xdl/src/project/Doctor.js:629:18
    at /Users/travis/build/companyApp/company-ui/node_modules/lodash/lodash.js:4944:15
    at baseForOwn (/Users/travis/build/companyApp/company-ui/node_modules/lodash/lodash.js:3001:24)
    at /Users/travis/build/companyApp/company-ui/node_modules/lodash/lodash.js:4913:18
    at Function.forEach (/Users/travis/build/companyApp/company-ui/node_modules/lodash/lodash.js:9359:14)
    at /xdl/src/project/Doctor.js:619:9
    at Generator.throw (<anonymous>)
    at step (/Users/travis/build/companyApp/company-ui/node_modules/exp/node_modules/xdl/build/project/Doctor.js:615:191)
    at /Users/travis/build/companyApp/company-ui/node_modules/exp/node_modules/xdl/build/project/Doctor.js:615:402
    at <anonymous>
/Users/travis/build/companyApp/company-ui/node_modules/appr/index.js:22
      throw new Error('Failed to publish package to Expo');
      ^
Error: Failed to publish package to Expo
    at publishError (/Users/travis/build/companyApp/company-ui/node_modules/appr/index.js:22:13)
    at ChildProcess.child.on.code (/Users/travis/build/companyApp/company-ui/node_modules/appr/scripts/spawn.js:16:5)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at maybeClose (internal/child_process.js:925:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
The command "yarn appr" exited with 1.
cache.2
store build cache

Does not work for react-native

It is stated in the readme that appr only works for CRNA or Expo created projects. There is a limitation and appr will not work for - React Native apps started with something other than create-react-native-app or Expo.

Are there any plans to make it work for projects created with react-native cli?

Currently the pipeline succeeds, the project appears in expo and there's a comment with QR code in the PR, but the application fails to open

exp socket hang up

All of my builds fail with CircleCI at

[exp]  ERROR  watch /home/ubuntu/citest2/node_modules/react-native-maps/lib/android/build/tmp/expandedArchives/classes.jar_rvtuwwbhztnbbkxi8oruhd9v/android/support/v4/hardware/fingerprint ENOSPC

I'm guessing because of the watch command? Here is the full log.

if [ "$CI_PULL_REQUEST" != "" ]; then yarn appr; fi
yarn appr v0.27.5
$ appr
[appr] Logging into Expo...
There is a new version of exp available (44.0.0).
You are currently using exp 36.0.0
Run `npm install -g exp` to get the latest version

Success.
[appr] Logged into Expo.
[appr] Preparing project for publish...
[appr] Publishing project into Expo.
There is a new version of exp available (44.0.0).
You are currently using exp 36.0.0
Run `npm install -g exp` to get the latest version
[exp] Making sure project is set up correctly...
-[exp] Warning: Not using the Expo fork of react-native. See https://docs.getexponent.com/.

-[exp] Warning: 'react' peer depencency missing. Run `npm ls` in /home/ubuntu/citest2 to see full warning.
[exp] 
[exp] If there is an issue running your project, please run `npm install` in /home/ubuntu/citest2 and restart.

[exp] Your project looks good!
[exp] Unable to find an existing exp instance for this directory, starting a new one...
[exp] Warning: Not using the Expo fork of react-native. See https://docs.getexponent.com/.
[exp] Warning: 'react' peer depencency missing. Run `npm ls` in /home/ubuntu/citest2 to see full warning.
[exp] 
[exp] If there is an issue running your project, please run `npm install` in /home/ubuntu/citest2 and restart.
[exp] Starting React Native packager...
[exp] Scanning 826 folders for symlinks in /home/ubuntu/citest2/node_modules (9ms)
[exp] 
[exp] Running packager on port 19001
[exp] 
[exp] 
[exp] 
[exp] Looking for JS files in
[exp]    /home/ubuntu/citest2 
[exp] 
[exp] 
[exp] 
[exp] 
[exp] React packager ready.
[exp] 
[exp] 
[exp] 
[exp] Publishing...
[exp]  ERROR  watch /home/ubuntu/citest2/node_modules/react-native-maps/lib/android/build/tmp/expandedArchives/classes.jar_rvtuwwbhztnbbkxi8oruhd9v/android/support/v4/hardware/fingerprint ENOSPC
[exp] 
[exp] {"code":"ENOSPC","errno":"ENOSPC","syscall":"watch /home/ubuntu/citest2/node_modules/react-native-maps/lib/android/build/tmp/expandedArchives/classes.jar_rvtuwwbhztnbbkxi8oruhd9v/android/support/v4/hardware/fingerprint","filename":"/home/ubuntu/citest2/node_modules/react-native-maps/lib/android/build/tmp/expandedArchives/classes.jar_rvtuwwbhztnbbkxi8oruhd9v/android/support/v4/hardware/fingerprint"}
[exp] Error: watch /home/ubuntu/citest2/node_modules/react-native-maps/lib/android/build/tmp/expandedArchives/classes.jar_rvtuwwbhztnbbkxi8oruhd9v/android/support/v4/hardware/fingerprint ENOSPC
[exp]     at exports._errnoException (util.js:1022:11)
[exp]     at FSWatcher.start (fs.js:1429:19)
[exp]     at Object.fs.watch (fs.js:1456:11)
[exp]     at NodeWatcher.watchdir (/home/ubuntu/citest2/node_modules/jest-haste-map/node_modules/sane/src/node_watcher.js:150:20)
[exp]     at Walker.<anonymous> (/home/ubuntu/citest2/node_modules/jest-haste-map/node_modules/sane/src/node_watcher.js:374:12)
[exp]     at emitTwo (events.js:106:13)
[exp]     at Walker.emit (events.js:191:7)
[exp]     at /home/ubuntu/citest2/node_modules/walker/lib/walker.js:69:16
[exp]     at go$readdir$cb (/home/ubuntu/citest2/node_modules/graceful-fs/graceful-fs.js:149:14)
[exp]     at FSReqWrap.oncomplete (fs.js:123:15)
[exp] 
[exp] socket hang up
Error: socket hang up
    at createHangUpError (_http_client.js:254:15)
    at Socket.socketOnEnd (_http_client.js:346:23)
    at emitNone (events.js:91:20)
    at Socket.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
/home/ubuntu/citest2/node_modules/appr/index.js:22
      throw new Error('Failed to publish package to Expo');
      ^

Error: Failed to publish package to Expo
    at publishError (/home/ubuntu/citest2/node_modules/appr/index.js:22:13)
    at ChildProcess.child.on.code (/home/ubuntu/citest2/node_modules/appr/scripts/spawn.js:16:5)
    at emitTwo (events.js:106:13)
    at ChildProcess.emit (events.js:191:7)
    at maybeClose (internal/child_process.js:877:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
error Command failed with exit code 1.

if [ "$CI_PULL_REQUEST" != "" ]; then yarn appr; fi returned exit code 1

Action failed: if [ "$CI_PULL_REQUEST" != "" ]; then yarn appr; fi

Regexp replace is incorrect.

This regexp missing flag g so it only replaces first characters

return `${name}`.replace(/[^a-zA-Z0-9\\-]/, '-');

Example:

'my-app-@giautm/@signature'.replace(/[^a-zA-Z0-9\\-]/, '-')
"my-app--giautm/@signature"

Adding the send link option to the PR

what about the option that is left right now to send the link to your mail, maybe automate it?(two step instead of one, but still better than nothing)

Pushing to Expo for master branch

I currently have a project set up to use appr by deploying pull requests (like the docs say).

Is there a way to deploy my master branch to the master Expo branch when master is updated?

Thanks!

Missing configuration key error

Hi, would be great if anyone could help me. I have followed all the steps but I get an error when building with Travis.

xxxxx/node_modules/appr/scripts/config.js:20
throw new Error(Missing configuration key ${key});
^
Error: Missing configuration key expUsername

This is the pull request/repo I am working on for reference:
TK-data/BilparkApp#18

Thanks!

Circle CI 2 doc

I’m using appr with Circle CI 2.0. If there’s no good reason to document the configuration in CircleCI 1.0 on README, it would be nice to update the doc for developpers like me.

Change exp to a peerDependency

appr's current behaviour is to prefer <app>/node_modules/exp over <app>/node_modules/appr/node_modules/exp - a duplication that exists if the app has a newer or incompatible version of exp as a dependency.

This is useful behaviour - e.g. to synchronise the version of exp between appr and any custom CI scripts used by the app. Moving exp to peerDependencies would simply codify it and make it explicit.

Allow setting --max-workers / other publish options

Background

I'm encountering a similar issue to #21 (only it's on Travis rather than CircleCI). sshing into the build worker and tweaking appr/index.js, I am able to get it to publish using exp publish --max-workers=1 (introduced in exp v50.0.0). (I'm going to try using a quick fork of appr to validate that this completely solves the issue, will report back)

Feature suggestions

What do you think of having a generic way to pass options to exp publish through appr? Or at least a way to pass --max-workers through? Or even just defaulting to --max-workers=1?

Heroku support

Hi there,

I'm a newbie and want to set appr up for heroku pipelines.

Any advice will be appreciated.

Thanks

Adding expo-cli breaks appr

I replaced exp with recently released expo-cli and it borke appr. Even re-adding exp did not help. This is the part of travis log that shows the error:

$ appr
[appr] Logging into Expo...
{ Error: spawn ./node_modules/exp/bin/exp.js ENOENT
    at _errnoException (util.js:1024:11)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:190:19)
    at onErrorNT (internal/child_process.js:372:16)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
    at Function.Module.runMain (module.js:678:11)
    at startup (bootstrap_node.js:187:16)
    at bootstrap_node.js:608:3
  code: 'ENOENT',
  errno: 'ENOENT',
  syscall: 'spawn ./node_modules/exp/bin/exp.js',
  path: './node_modules/exp/bin/exp.js',
  spawnargs: 
   [ 'login',
     '-u',
     '[secure]',
     '-p',
     '[secure]',
     '--non-interactive' ] }
/home/travis/build/hiposfer/hive/node_modules/appr/index.js:13
    throw new Error('Failed to log into Expo');
    ^
Error: Failed to log into Expo
    at loginError (/home/travis/build/hiposfer/hive/node_modules/appr/index.js:13:11)
    at ChildProcess.child.on.code (/home/travis/build/hiposfer/hive/node_modules/appr/scripts/spawn.js:16:5)
    at emitTwo (events.js:126:13)
    at ChildProcess.emit (events.js:214:7)
    at maybeClose (internal/child_process.js:925:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:209:5)
    at onErrorNT (internal/child_process.js:372:16)
    at _combinedTickCallback (internal/process/next_tick.js:138:11)
    at process._tickCallback (internal/process/next_tick.js:180:9)
    at Function.Module.runMain (module.js:678:11)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

"Loading dependency graph, done."

Hello,
I have followed the documentation to configure appr but the build travis stops with the following error message:"Loading dependency graph, done.".

What could this problem be? I think it's because expo is launching the application and waiting for interactions, but I don't know how to fix this problem.

Thank you

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.