A react-native app to help monitor the state of your Octopus deployments and servers (across multiple instances)
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


OctoWatch react-native project (currently iOS only)

Instances Machines Releases Tasks
Instances Machines Releases Tasks

Table of Contents

  1. Summary of tech
  2. Installing
  3. Getting Started
  4. Making changes
  5. Release builds

Summary of tech

  • Summary videos of this app (from our TLDR meetings) can be found on YouTube. This video discusses React and later this video discussing TypeScript
  • Built with React Native
  • Uses Realm.io for persistent data storage (for saving your Octopus instances)
  • Written with Typescript - for those who prefer statically-typed languages :)
  • Uses TSLint to keep developers in check for readability, maintainability, and functionality errors
  • Integrated with Redux to give the app a predictable state container
  • Uses React Navigation, because it seemed to be the only extensible yet easy-to-use x-platform navigation solution


  • Run npm install -g react-native-cli from the root directory (see dependencies at https://facebook.github.io/react-native/docs/getting-started.html)
  • Run npm install from the root directory to install the node modules
  • Run npm run build from the root directory to build the typescript artifacts (ie. compile of js)
  • Assuming you're on a Mac with XCode installed (which will install the iOS Simulator for you that you need), run react-native run-ios from the root directory (this will take some time on the first run) ... or open and debug directly from the XCode project

NOTE: I have not run or tested on Android at all, so I don't expect Android to run at the present time.

Install Troubleshooting

  • If you have troubles running the app, Google it or ask Mark S. We're all new to this :D

Getting Started

  • All the source files live in ./src (and the main entry point is established at index.js)
  • This index.js wraps our app in a redux store, so we can dispatch actions to our components
  • This index.js also loads the AppNavigator and the logging middleware using redux so we get nice logging of state changes in dev mode
  • 'Components' can be thought of similarly to our view controllers in Angular. They're all in the ./components folder
  • This code uses a redux pattern where we establish types of actions we want to dispatch (see ./actions/types.js)
  • These actions are processed by an equivalent redux reducer (see ./reducers to see how navigation routes are working)
  • Programmers can dispatch actions (methods) to the store (ie. root state of our app). These actions then get processed by our reducers and changes get applied on our app's root state, which in turn propagates the changes down to components

So from our components, we can call actions on our redux store, those actions dispatch state to our components, and we go round in a neat little circle to have predictable state management :)

Read more about the dispatch pattern below.

Redux and Dispatching Actions from Components

Let's say you had a component in your top nav bar, and you wanted it to know when the "machines count" had changed (a count that was calculated from some other component that lived in a nested tab bar component, somewhere else in your app):

  • First you need to import the redux store: Eg. import store from '../store/ReduxStore'
  • Then you need to know what action (method) you want to dispatch to the store: Eg. setMachinesCount in ./src/ApiResponseActions.js
  • From your component, you dispatch this action to the store as follows: Eg. See ./src/components/MachinesTab/ and how it uses store.dispatch(setMachinesCount(totalResults)); (setMachinesCount is an action in ./src/actions/ApiResponseActions.js)
  • Then you need a reducer that handles this action type, and returns changes to the state (see ./src/reducers/ApiResponseReducers.js and the machinesCount const)

Your app's root state is now changed. You can now subscribe to these state changes from any other component in your app (see how below).

Redux and Detecting State Changes from Components

  • First you need to import the connect method in your component (Eg. import { connect } from 'react-redux';)
  • Then you need to subscribe to the root state properties that you want your component to know about. This is where the reducers come into play. Eg. See ./src/components/HomeScreenTabReporter.js and the mapStateToProps at the bottom (the component is subscribed to the machinesCount method from the ./src/reducers/ApiResponseReducers.js). It can then respond to this change and update its UI accordingly.

Summary: In this example, our setMachinesCount action tells the store that there's a new machine count. The HomeScreenTabReporter component has subscribed to that machineCount property (see mapStateToProps), so it knows to update its UI in response to this action)

Making changes

This project is using typescript. So after you've made changes to your typescript files, we need to call npm run build in order to build the artifacts folder with our compiled js. Then you can hit refresh in your simulator to see the changes.

Note: At the time of writing, the compileOnSave property in the tslint.json does not seem to work, otherwise you could probably skip the manual npm run build step after making and saving changes.

Release builds

These instructions apply after you've setup all your release certificates and provisioning profiles in the Apple developer site, and hooked all that up in your XCode target.

Once your provisioning profiles are all setup, if you open XCode and look at this project's AppDelegate.m, you'll see how the react-native js gets bundled during both development and release builds. During development, react is running a package server locally and it references that package. However, during release builds, you need to manually bundle your artifacts (the compiled js from our typescript) and make sure this bundle is included in your XCode target's bundle resources.

So firstly to create the bundle, do this from command line:

react-native bundle --entry-file artifacts/index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios

Then drag the created main.jsbundle into your XCode project.

Now, when you do release builds, the project will use the bundled js package and you'll be good to go. Without this, it will blow up and you'll be scratching your head wondering wtf is going on :)