# Continuous Installation

#### Jonathan M. Hill

#### 2017-03-26

RInno supports continuous installation of shiny apps through APIs to public/private BitBucket and GitHub repos. On start up, RInno apps call your repository. If there have been any hotfixes or releases since installation, the app automatically updates, letting its user know through a windows progress bar, and then opens normally.

This feature requires:

1. A URL to the app’s repo, `app_repo_url` (for private repos, provide `auth_user` and `auth_pw`).
2. A release tag on GitHub, or a version on BitBucket.
3. An R package structure that can be installed via `devtools::install_github` or `devtools::install_bitbucket`.

The release tag or version is compared with the package DESCRIPTION file, i.e. `0.0.0.9000`, to determine if the app should call `devtools::install_github` or `devtools::install_bitbucket` respectively. So update the app’s version in both places (2 & 3 above) with each new version, otherwise the app will re-install every time its icon is clicked.

## R Package Structure

To connect a shiny app to a remote repository, the app must be on Github or Bitbucket, and it must be in the `inst/app` directory of an R package. The easiest way to do this is by creating a new project in RStudio and selecting R Package. See Dean Attali’s Blog for a detailed tutorial on including shiny apps in your R package.

package/ |  |
--- | --- | ---
| inst/app/ |
|  | ui.R
|  | server.R
| R |
| … |
| DESCRIPTION |
| … |

The package should be called `app_name`, and within the DESCRIPTION file, `Package: app_name`.

## Bitbucket

On Bitbucket, enable issue tracking in the repo’s settings. This will add Versions to the Issues section and make it accessible via BitBucket’s API. Add `0.0.0.9000` to Versions and within the package’s DESCRIPTION file, `Version: 0.0.0.9000`.

Then create an RInno installer:

    create_app(
      app_name     = 'myapp',
      app_repo_url = 'https://bitbucket.org/fi_consulting/myapp',
      auth_user    = '<read_only_username>',
      auth_pw      = '<password>')

    compile_iss()

Or for custom installers, directly through `create_config`:

    create_config(
      app_name     = 'myapp',
      R_version    = '3.3.2',
      app_dir      = 'app',
      app_repo_url = 'https://bitbucket.org/fi_consulting/myapp',
      auth_user    = '<read_only_username>',
      auth_pw      = '<password>')

    # -------------------------------------------------- Many steps later
    compile_iss()

Shiny apps compiled/installed this way will call the BitBucket API on start up, and re-install every time there is an update to the BitBucket repo’s version.

## GitHub

On GitHub, create a release for the app. The release(s) tab is located on the repo’s homepage next to branch(es) just before contributor(s). Add `0.0.0.9000` to the release tag and within the package’s DESCRIPTION file, `Version: 0.0.0.9000`. This will make the release tag accessible via GitHub’s API.

Then create an RInno installer:

    create_app(
      app_name     = 'myapp',
      app_repo_url = 'https://github.com/fi_consulting/myapp',
      auth_user    = '<read_only_username>',
      auth_pw      = '<password>')

    compile_iss()

Or for custom installers, directly through `create_config`:

    create_config(
      app_name     = 'myapp',
      R_version    = '3.3.2',
      app_dir      = 'app',
      app_repo_url = 'https://github.com/fi_consulting/myapp',
      auth_user    = '<read_only_username>',
      auth_pw      = '<password>')

    # -------------------------------------------------- Many steps later
    compile_iss()

Shiny apps compiled/installed this way will call the GitHub API on start up, and re-install every time there is an update to the GitHub repo’s most recent release tag.

### A Note on Versions

A released version number consists of three numbers, `major.minor.patch`. Semantic Versioning 2.0.0 is a good specification to follow because `numeric_version` will interpret it correctly:

    numeric_version('0.1.0') == numeric_version('0.1')

    ## [1] TRUE

    # First release!
    numeric_version('0.0.1') > numeric_version('0.0.0.9000')

    ## [1] TRUE

This is important because RInno determines the `local_version` of the app via `installed.packages()`. If R cannot parse the version correctly, the continuous installation will be… nonstop. Users will love you.