Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New monorepo deploys #366

Merged
merged 17 commits into from
Dec 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 36 additions & 44 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ jobs:
- run:
name: Set up git config
command: git config credential.helper "/bin/bash /home/circleci/helper-script.sh"
- run:
name: Install curl
command: |
sudo apt update
sudo apt install -y -qq curl
- run:
name: Install dds-client
comamdn: |
curl -sSL -o dds-client.tgz https://github.com/plotly/dds-client/releases/download/v0.1.0/dds-client_0.1.0_linux_x86_64.tgz
tar xzf dds-client.tgz -C /usr/local/bin
chmod +x /usr/local/bin/dds-client
- run:
name: Deploy
command: |
Expand All @@ -41,36 +52,13 @@ jobs:
exit 0
fi

git config --global user.email '<>' # Leave email blank
git config --global user.name "Circle MonoRepo Automatic Deployer"

for APP in $APPS_MODIFIED
do
if [ "$APP" == "$CIRCLE_BRANCH" ]
then
git config --global user.email '<>' # Leave email blank
git config --global user.name "Circle MonoRepo Automatic Deployer"
if [[ $APP =~ "dashr" ]]
then
cp ~/dash-sample-apps/apps/"$APP"/Aptfile ~/dash-sample-apps/
cp ~/dash-sample-apps/apps/"$APP"/Procfile ~/dash-sample-apps/
cp ~/dash-sample-apps/apps/"$APP"/.buildpacks ~/dash-sample-apps/
cp ~/dash-sample-apps/apps/"$APP"/init.R ~/dash-sample-apps/
# app.json tries to call python predeploy, which is not needed for R apps:
rm ~/dash-sample-apps/app.json
git add . && git commit -a -m "Deployed commit: $CIRCLE_SHA1"
fi
if [ ! -d ~/dash-sample-apps/apps/"$APP"/assets/ ]
then
echo "Deploy failed because there is no assets/ folder. Exiting..."
exit 1
fi
git commit -m "Deployed commit: $CIRCLE_SHA1"
git push playground $CIRCLE_BRANCH:master --force
exit 0
else
echo "appname: $APP is not same as the branchname: $CIRCLE_BRANCH. Not deploying..."
fi
CREATE_APP=true ./deploy "$APP"
done
echo "Deploy failed because of a branchname/appname mismatch. Exiting..."
exit 1
deploy_to_gallery:
docker:
- image: circleci/python:3.6-stretch
Expand All @@ -86,29 +74,34 @@ jobs:
- run:
name: Set up git config
command: git config credential.helper "/bin/bash /home/circleci/helper-script.sh"
- run:
name: Install curl
command: |
sudo apt update
sudo apt install -y -qq curl
- run:
name: Install dds-client
comamdn: |
curl -sSL -o dds-client.tgz https://github.com/plotly/dds-client/releases/download/v0.1.0/dds-client_0.1.0_linux_x86_64.tgz
tar xzf dds-client.tgz -C /usr/local/bin
chmod +x /usr/local/bin/dds-client
- run:
name: Deploy
command: |
APPS_MODIFIED=$(ls apps | grep dash- | sort -u)
if [ -z "$APPS_MODIFIED" ]
then
echo "No app change detected. Skipping the deploy.."
exit 0
fi

git config --global user.email '<>' # Leave email blank
git config --global user.name "Circle MonoRepo Automatic Deployer"

for APP in $APPS_MODIFIED
do
if [[ $APP =~ "dashr" ]]
then
continue
fi
git config --global user.email '<>' # Leave email blank
git config --global user.name "Circle MonoRepo Automatic Deployer"
if [ -d ~/dash-sample-apps/apps/"$APP"/ ]
then
git commit -m "Deployed commit: $CIRCLE_SHA1"
git remote add $APP https://dash-playground.plotly.host/GIT/$APP
git push $APP master --force || echo "Deploy failed because there is no such app on Dash Gallery: $APP. Please use the web interface to create an app with this name. Continuing deployments..."
fi
./deploy "$APP"
done
- run:
name: Push to production
command: |
git push --force git@github.com:plotly/dash-sample-apps master:production

workflows:
version: 2
Expand All @@ -121,7 +114,6 @@ workflows:
filters:
branches:
ignore:
- production
- master
- deploy_to_gallery:
requires:
Expand Down
1 change: 1 addition & 0 deletions .deployignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# these apps are ignored for deployment
42 changes: 13 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,15 @@ the deployment will eventually be hosted at
https://dash-gallery.plotly.host/my-dash-app, "DDS app name" is
`my-dash-app`._

### Branches

Each app has its own branch off of `master` that has the _exact same_
name as the DDS app. This is an effective `master` branch _for that
app only_. This is because we sync the apps in this repository with
our staging deployment server, and the automatic deploys sync the app
name with the github branch name. So, for automatic deploys to work,
any changes for a particular app should be done on a branch that has
the same name as the app.

### Adding a new app

Create an app on Dash Playground. This will be the location of the
auto-deployment. To do this, log into the app manager on
[dash-playground.plotly.host](https://dash-playground.plotly.host)
and click "initialize app".

Create a branch from `master` that has the _exact same_ name as the
Dash app name. Switch to this branch, then navigate to the `apps/`
Create a branch from `master` to work on your app, the name is not required
to be anything specific. Switch to this branch, then navigate to the `apps/`
directory and add a directory for your app.

There are two options when you are naming the folder:
Expand All @@ -52,7 +42,7 @@ There are two options when you are naming the folder:

Navigate to the directory you just created, and write a small README
that only contains the name of the app. Stage the README and commit it
to your app branch.
to your branch.

See [project boilerplate!](https://github.com/plotly/dash-sample-apps#project-boilerplate)

Expand All @@ -67,7 +57,7 @@ Contributing an app written with Dash for R is very similar to the steps outline
3. The `Procfile` should contain

```
web: R -f /app/apps/"$DASH_APP_NAME"/app.R
web: R -f /app/app.R
```

4. Routing and request pathname prefixes should be set. One approach might be to include
Expand All @@ -88,19 +78,13 @@ at the head of your `app.R` file.
app$run_server(host = "0.0.0.0", port = Sys.getenv('PORT', 8050))
``

6. For convenience, it is probably easiest to set the working directory in `app.R` as well:

``
setwd(sprintf("/app/apps/%s", appName))
``

### Making changes to an existing app

Switch to the branch that has the same name as the DDS app (the "app
branch"). Then, navigate to the directory that has the same name as
Create a new branch - of any name - for your code changes.
Then, navigate to the directory that has the same name as
the DDS app.

When you are finished, make a pull request from the app branch to the master
When you are finished, make a pull request from your branch to the master
branch. Once you have passed your code review, you can merge your PR.

## Dash app project structure
Expand All @@ -117,7 +101,7 @@ branch. Once you have passed your code review, you can merge your PR.

- **`Procfile`** gets run at root level for deployment
- Make sure python working directory is at the app level
- Ex. `web: gunicorn --pythonpath apps/{DASH_APP_NAME} app:server`
- Ex. `web: gunicorn app:server`
- **`requirements.txt`**
- Install project dependecies in a virtual environment
- **`runtime.txt`**
Expand All @@ -139,7 +123,7 @@ branch. Once you have passed your code review, you can merge your PR.

#### Handle relative path

Since deployment happens at the root level `/` and not at the app level (`/apps/{DASH_APP_NAME}`), we need to make sure our application is able to run at both levels for flexibility.
Assets should never use a relative path, as this will fail when deployed to Dash Enterprise due to use of subdirectories for serving apps.

Reading from assets and data folder
```Python
Expand Down Expand Up @@ -173,13 +157,13 @@ with open(DATA_PATH.joinpath("sample-data.csv")) as f: # /data/sample-data.csv

```
# branch off master
git checkout -b "{DASH_APP_NAME}"
git checkout -b "{YOUR_CUSTOM_BRANCH}"

# create a new folder in apps/
mkdir /apps/{DASH_APP_NAME}

# push new app branch
git push -u origin {DASH_APP_NAME}
# push new branch
git push -u origin {YOUR_CUSTOM_BRANCH}
```

#### Before committing
Expand All @@ -195,7 +179,7 @@ pip install black

#### App is ready to go!
```
# once your app branch is ready, make a PR into master!
# once your branch is ready, make a PR into master!

PR has two checkers.
1. make sure your code passed the black linter
Expand Down
2 changes: 1 addition & 1 deletion apps/dash-brain-viewer/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-brain-viewer app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-clinical-analytics/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-clinical-analytics app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-cytoscape-phylogeny/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-cytoscape-phylogeny app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-cytoscape/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-cytoscape app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-daq-iv-tracer/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-daq-iv-tracer demo:server
web: gunicorn demo:server
2 changes: 1 addition & 1 deletion apps/dash-daq-satellite-dashboard/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-daq-satellite-dashboard app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-datashader/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-datashader app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-drug-discovery/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-drug-discovery app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-financial-report/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-financial-report app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-image-processing/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-image-processing app:server
web: gunicorn app:server
5 changes: 2 additions & 3 deletions apps/dash-image-processing/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import csv
import sys
import pathlib
import importlib

import boto3
import dash
Expand All @@ -16,8 +15,8 @@
from dash.dependencies import Input, Output, State
from flask_caching import Cache

drc = importlib.import_module("apps.dash-image-processing.dash_reusable_components")
utils = importlib.import_module("apps.dash-image-processing.utils")
import dash_reusable_components as drc
import utils

DEBUG = True
LOCAL = False
Expand Down
2 changes: 0 additions & 2 deletions apps/dash-image-processing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

from PIL import Image, ImageFilter, ImageDraw, ImageEnhance

# drc = importlib.import_module("apps.dash-iamge-processing.dash_reusable_components")

#
APP_PATH = str(pathlib.Path(__file__).parent.resolve())

Expand Down
2 changes: 1 addition & 1 deletion apps/dash-lastodash/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web:gunicorn --pythonpath apps/dash-lastodash lastodash:server
web: gunicorn lastodash:server
2 changes: 1 addition & 1 deletion apps/dash-live-model-training/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-live-model-training app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-manufacture-spc-dashboard/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-manufacture-spc-dashboard app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-mapd-demo/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-mapd-demo app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-medical-provider-charges/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-medical-provider-charges app:server
web: gunicorn app:server
2 changes: 0 additions & 2 deletions apps/dash-medical-provider-charges/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@
for state in state_list:
p = os.getcwd().split(os.path.sep)
csv_path = "data/processed/df_{}_lat_lon.csv".format(state)
if p[-1] != "dash-medical-provider-charges":
csv_path = "apps/dash-medical-provider-charges/" + csv_path
state_data = pd.read_csv(csv_path)
data_dict[state] = state_data

Expand Down
2 changes: 1 addition & 1 deletion apps/dash-multipage-report/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-multipage-report app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-nlp/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-nlp app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-object-detection/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-object-detection app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-oil-and-gas/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-oil-and-gas app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-oil-gas-ternary/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-oil-gas-ternary app:server
web: gunicorn app:server
2 changes: 0 additions & 2 deletions apps/dash-oil-gas-ternary/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import importlib
import pathlib
import os

Expand All @@ -11,7 +10,6 @@
import plotly.graph_objs as go
from dash.dependencies import Input, Output, State

# constants = importlib.import_module("apps.dash-oil-gas-ternary.constants")
import constants

# app initialize
Expand Down
2 changes: 1 addition & 1 deletion apps/dash-opioid-epidemic/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-opioid-epidemic app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-pk-calc/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-pk-calc app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-salesforce-crm/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-salesforce-crm index:server
web: gunicorn index:server
2 changes: 1 addition & 1 deletion apps/dash-stitching/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-stitching app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-study-browser/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-study-browser app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-svm/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-svm app:server
web: gunicorn app:server
4 changes: 2 additions & 2 deletions apps/dash-svm/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from sklearn import datasets
from sklearn.svm import SVC

drc = importlib.import_module("apps.dash-svm.utils.dash_reusable_components")
figs = importlib.import_module("apps.dash-svm.utils.figures")
import utils.dash_reusable_components as drc
import utils.figures as figs

app = dash.Dash(
__name__,
Expand Down
2 changes: 1 addition & 1 deletion apps/dash-tsne/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-tsne app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-uber-rides-demo/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-uber-rides-demo app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-web-trader/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-web-trader app:server
web: gunicorn app:server
2 changes: 1 addition & 1 deletion apps/dash-wind-streaming/Procfile
Original file line number Diff line number Diff line change
@@ -1 +1 @@
web: gunicorn --pythonpath apps/dash-wind-streaming app:server
web: gunicorn app:server
Loading