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

Update production deployment #244

Merged
merged 19 commits into from
Apr 20, 2022
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
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Continuous Integration

on:
push:

jobs:
test:
name: "Tests"
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [15.x]

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: make ci
5 changes: 0 additions & 5 deletions .travis.yml

This file was deleted.

23 changes: 14 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Welcome
# Flow Playground

The Flow Playground is the best way to learn and try Cadence. For newcomers to Flow
the [Flow Developer Documentation](https://docs.onflow.org) has a guide on how to use the Playground.
The Flow Playground is the best way to learn and try Cadence. For newcomers to Flow,
the [Flow Developer Documentation](https://docs.onflow.org) includes a guide on how to use the Playground.

## Philosophy

Expand All @@ -14,27 +14,28 @@ We built the Flow Playground as a static website or typical "JAM stack" website
- Fast build and deploy cycles
- We want to maximize the amount of potential contributions

### What Is the Playground?
### What is the Playground?

We want the Playground to have features that help you build on Flow. We also want to balance functionality with learning.

The Playground is a learning tool first and an awesome development tool second, although the two go hand-in-hand.

## Contributing

### Read the [Contribution Guidelines](https://github.com/onflow/flow-playground/blob/master/CONTRIBUTING.md)
### Read the [Contribution Guidelines](CONTRIBUTING.md)

### Git workflow:
### Git Workflow

- Use merge squashing, not commit merging [eg. here](https://blog.dnsimple.com/2019/01/two-years-of-squash-merge/). Squash merge is your friend.
- The master branch is the base branch, there is no dedicated development branch
- The `staging` branch is the base branch and contains the code deployed at https://play.staging.onflow.org.

# Developing
## Developing

### Pre-requisites

You'll need to have Docker installed to develop.

## Installation
### Installation

Clone the repo

Expand Down Expand Up @@ -89,3 +90,7 @@ If you are using VSCode, you can use this debugging config (works with workspace
]
}
```

## Deployment

The runbook contains details on [how to deploy the Flow Playground web app](RUNBOOK.md).
83 changes: 83 additions & 0 deletions RUNBOOK.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
## Overview

The Flow Playground is a web-based interactive IDE for running Cadence code.
It also provides an environment for the [Cadence intro tutorials](https://docs.onflow.org/cadence/tutorial/01-first-steps).

The overall project consists of the web app (this) and an [API backend](https://github.com/onflow/flow-playground-api).

The Playground Web App is implemented in React. The major components are as follows:

### GraphQL / Apollo Client

- All HTTP communication with the Playground API is done via `GraphQL` using the `Apollo` client.
- The GraphQL schema is defined by the Playground API in [schemal.graphql](https://github.com/onflow/flow-playground-api/blob/master/schema.graphql)
- This project uses Apollo Client's `localStorage` interface as well.
- You can view the _local_ GraphQL schema in [local.graphql](src/api/apollo/local.graphql).
- CRUD methods (wrapped Apollo client) are implemented in [projectMutator.ts](src/providers/Project/projectMutator.ts).
- TypeScript typings and CRUD methods for Apollo are auto-generated using [GraphQL Code Generator](https://www.graphql-code-generator.com/).
- After making changes to the `schema.local` you will need to run `npm run graphql:codegen` to auto-generate new typings and methods for Apollo Client.

### Monaco Editor

- The editor interface itself is implemented using [Monaco Editor](https://microsoft.github.io/monaco-editor/).
- The editor component can be found here: https://github.com/onflow/flow-playground/tree/master/src/containers/Editor
- The Cadence language definition (for linting and syntax highlighting) for Monaco can be found here: https://github.com/onflow/flow-playground/blob/master/src/util/cadence.ts

### Cadence Language Server

- The Cadence Language Server (used by Monaco) is implemented in Golang and compiled to WASM.
- The WASM bundle is built from [source files in the Cadence repository](https://github.com/onflow/cadence/tree/master/npm-packages/cadence-language-server) and [published on npm](https://www.npmjs.com/package/@onflow/cadence-language-server).
- You can read more about the Cadence Language Server in the [Cadence repository](https://github.com/onflow/cadence/blob/master/languageserver/README.md).
- The Playground integration can be found here:
- Server: https://github.com/onflow/flow-playground/blob/master/src/util/language-server.ts
- Client: https://github.com/onflow/flow-playground/blob/master/src/util/language-client.ts

## Deployment

The Playground Web App is deployed to [Vercel](https://vercel.com). You will see a link to join the Flow Vercel team when you open your first PR. You must be a member of the team to trigger deployments.

### Staging Deployment

URL: https://play.staging.onflow.org

The Playground Web App is deployed to https://play.staging.onflow.org each time a new commit is pushed to the `staging` branch on this repository.

1. Open a new pull request and select `staging` as the base branch. Vercel will trigger a new deployment once the PR is approved and merged.

2. Vercel will then report the deployment status on the `staging` branch:

![vercel-deployment](vercel-deployment.png)

### Production Deployment

URL: https://play.onflow.org

Once a staging deployment has been verified, you can promote the changes to production.

The Playground Web App is deployed to https://play.onflow.org each time a new commit is pushed to the `production` branch on this repository.

1. Open a new pull request and select `production` as the base branch and `staging` as the source branch. Production deployments should always deploy the same code that is already live in staging. Vercel will trigger a new deployment once the PR is approved and merged.

2. Vercel will then report the deployment status on the `production` branch:

![vercel-deployment](vercel-deployment.png)

## Important Gotcha: User Sessions & Project "Forking"

_The Playground will not function in browsers where cookies or localStorage are disabled._

### How It Works

The Playground determines what content to load into the UI based on a url query param named `projectId`.
- When a user first visits the Playground, the `projectId` param is set to `local-project`, indicating that this is a new project and has not been persisted.
- https://github.dev/onflow/flow-playground/blob/2e3323aba9504e6a07fc13d1b2cec0e703edce43/src/util/url.ts#L16-L17
- At this point, a representation of the `Project` _model_ has been boostrapped and persisted to the browser's localStorage using Apollo
- https://github.dev/onflow/flow-playground/blob/2e3323aba9504e6a07fc13d1b2cec0e703edce43/src/providers/Project/projectDefault.ts#L216
- https://github.dev/onflow/flow-playground/blob/2e3323aba9504e6a07fc13d1b2cec0e703edce43/src/providers/Project/projectHooks.ts#L10-L11
- When a user performs some action that updates any field in the project, or clicks the save button, the project is read from localStorage, and sent to the API to be persisted.
- https://github.dev/onflow/flow-playground/blob/2e3323aba9504e6a07fc13d1b2cec0e703edce43/src/providers/Project/projectMutator.ts#L54-L55
- Once the mutation has returned successfully (The project state has been saved to the DB), another local value is set using Apollo/localstorage, to reflect the newly generated project's unique `id` (from the database)
- https://github.dev/onflow/flow-playground/blob/2e3323aba9504e6a07fc13d1b2cec0e703edce43/src/providers/Project/projectMutator.ts#L93-L94
- The server response also sets a cookie **that links the current browser session with the new project ID**
- This is done so that if a user _shares_ a link to their new project (eg. https://play.onflow.org/46c7136f-803c-4166-9d46-25d8e927114c), to someone without the session cookie linking the ID and browser session, the UI will recognise (the save button becomes "fork") that this is the case, and on subsequent saves of the shared project, _will send a mutation to generate a new project based on the existing contents of the editor, preventing users from overwriting eachothers projects!_
- The name of the cookie is `flow-playground`
14 changes: 7 additions & 7 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript'
]
};
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript',
],
};
Loading