Skip to content

Commit f616327

Browse files
authored
Merge branch 'develop' into fr-bkp
2 parents 19e541f + 2dbad54 commit f616327

40 files changed

+1844
-1583
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Deploy to staging
2+
on:
3+
workflow_run:
4+
workflows: ["Test"]
5+
branches:
6+
- develop
7+
types:
8+
- completed
9+
env:
10+
PROJECT_ID: ${{ secrets.GKE_PROJECT }}
11+
GKE_CLUSTER: p5js-web-editor-cluster
12+
GKE_ZONE: us-east1-c
13+
DEPLOYMENT_NAME: web-editor-node
14+
IMAGE: ${{ secrets.DOCKER_USERNAME }}/p5.js-web-editor-staging
15+
jobs:
16+
push_to_registry:
17+
environment: staging
18+
name: Push Docker image to Docker Hub
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Check out the repo
22+
uses: actions/checkout@v2
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v1
25+
- name: Login to Docker Hub
26+
uses: docker/login-action@v1
27+
with:
28+
username: ${{ secrets.DOCKER_USERNAME }}
29+
password: ${{ secrets.DOCKER_PASSWORD }}
30+
- name: Build and push to Docker Hub
31+
uses: docker/build-push-action@v2
32+
with:
33+
context: .
34+
file: ./Dockerfile
35+
pull: true
36+
push: true
37+
tags: |
38+
${{ env.IMAGE }}:${{ github.sha }}
39+
${{ env.IMAGE }}:latest
40+
target: production
41+
# Setup gcloud CLI
42+
- uses: google-github-actions/setup-gcloud@v0.2.0
43+
with:
44+
service_account_key: ${{ secrets.GKE_SA_KEY }}
45+
project_id: ${{ secrets.GKE_PROJECT }}
46+
47+
# Configure docker to use the gcloud command-line tool as a credential helper
48+
- run: |-
49+
gcloud --quiet auth configure-docker
50+
51+
# Get the GKE credentials so we can deploy to the cluster
52+
- uses: google-github-actions/get-gke-credentials@v0.2.1
53+
with:
54+
cluster_name: ${{ env.GKE_CLUSTER }}
55+
location: ${{ env.GKE_ZONE }}
56+
credentials: ${{ secrets.GKE_SA_KEY }}
57+
58+
# Deploy the Docker image to the GKE cluster
59+
- name: Deploy
60+
run: |-
61+
kubectl set image deployment/$DEPLOYMENT_NAME web-editor-app=index.docker.io/$IMAGE:$GITHUB_SHA --namespace=staging
62+
kubectl get services -o wide

.github/workflows/deploy.yml

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: Deploy to production
2+
on:
3+
workflow_run:
4+
workflows: ["Test"]
5+
branches:
6+
- release
7+
types:
8+
- completed
9+
env:
10+
PROJECT_ID: ${{ secrets.GKE_PROJECT }}
11+
GKE_CLUSTER: p5js-web-editor-cluster
12+
GKE_ZONE: us-east1-c
13+
DEPLOYMENT_NAME: web-editor-node
14+
IMAGE: ${{ secrets.DOCKER_USERNAME }}/p5.js-web-editor
15+
jobs:
16+
push_to_registry:
17+
environment: production
18+
name: Push Docker image to Docker Hub
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Check out the repo
22+
uses: actions/checkout@v2
23+
- name: Set up Docker Buildx
24+
uses: docker/setup-buildx-action@v1
25+
- name: Login to Docker Hub
26+
uses: docker/login-action@v1
27+
with:
28+
username: ${{ secrets.DOCKER_USERNAME }}
29+
password: ${{ secrets.DOCKER_PASSWORD }}
30+
- name: Build and push to Docker Hub
31+
uses: docker/build-push-action@v2
32+
with:
33+
context: .
34+
file: ./Dockerfile
35+
pull: true
36+
push: true
37+
tags: |
38+
${{ env.IMAGE }}:${{ github.sha }}
39+
${{ env.IMAGE }}:latest
40+
target: production
41+
# Setup gcloud CLI
42+
- uses: google-github-actions/setup-gcloud@v0.2.0
43+
with:
44+
service_account_key: ${{ secrets.GKE_SA_KEY }}
45+
project_id: ${{ secrets.GKE_PROJECT }}
46+
47+
# Configure docker to use the gcloud command-line tool as a credential helper
48+
- run: |-
49+
gcloud --quiet auth configure-docker
50+
51+
# Get the GKE credentials so we can deploy to the cluster
52+
- uses: google-github-actions/get-gke-credentials@v0.2.1
53+
with:
54+
cluster_name: ${{ env.GKE_CLUSTER }}
55+
location: ${{ env.GKE_ZONE }}
56+
credentials: ${{ secrets.GKE_SA_KEY }}
57+
58+
# Deploy the Docker image to the GKE cluster
59+
- name: Deploy
60+
run: |-
61+
kubectl set image deployment/$DEPLOYMENT_NAME web-editor-app=index.docker.io/$IMAGE:$GITHUB_SHA
62+
kubectl get services -o wide
63+

.github/workflows/test.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
name: Test
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
test:
7+
name: Test and lint code base
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- name: Use Node.js
12+
uses: actions/setup-node@v1
13+
with:
14+
node-version: '12.x'
15+
- run: npm install
16+
- run: npm run test
17+
- run: npm run lint
18+
19+

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ If you have found a bug in the p5.js Web Editor, you can file it under the ["iss
3131

3232
Please post bugs and feature requests in the correct repository:
3333

34-
* p5.js library and p5.dom: [https://github.com/processing/p5.js/issues](https://github.com/processing/p5.js/issues)
34+
* p5.js library: [https://github.com/processing/p5.js/issues](https://github.com/processing/p5.js/issues)
3535
* p5.accessibility: [https://github.com/processing/p5.accessibility/issues](https://github.com/processing/p5.accessibility/issues)
3636
* p5.sound: [https://github.com/processing/p5.js-sound/issues](https://github.com/processing/p5.js-sound/issues)
3737
* p5.js website: [https://github.com/processing/p5.js-website/issues](https://github.com/processing/p5.js-website/issues)

client/modules/IDE/actions/files.js

Lines changed: 101 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import objectID from 'bson-objectid';
22
import blobUtil from 'blob-util';
3-
import { reset } from 'redux-form';
43
import apiClient from '../../../utils/apiClient';
54
import * as ActionTypes from '../../../constants';
65
import { setUnsavedChanges, closeNewFolderModal, closeNewFileModal } from './ide';
76
import { setProjectSavedTime } from './project';
7+
import { createError } from './ide';
88

99

1010
function appendToFilename(filename, string) {
@@ -36,106 +36,117 @@ export function updateFileContent(id, content) {
3636
};
3737
}
3838

39-
export function createFile(formProps) {
39+
export function createFile(file, parentId) {
40+
return {
41+
type: ActionTypes.CREATE_FILE,
42+
...file,
43+
parentId
44+
};
45+
}
46+
47+
export function submitFile(formProps, files, parentId, projectId) {
48+
if (projectId) {
49+
const postParams = {
50+
name: createUniqueName(formProps.name, parentId, files),
51+
url: formProps.url,
52+
content: formProps.content || '',
53+
parentId,
54+
children: []
55+
};
56+
return apiClient.post(`/projects/${projectId}/files`, postParams)
57+
.then(response => ({
58+
file: response.data.updatedFile,
59+
updatedAt: response.data.project.updatedAt
60+
}));
61+
}
62+
const id = objectID().toHexString();
63+
const file = {
64+
name: createUniqueName(formProps.name, parentId, files),
65+
id,
66+
_id: id,
67+
url: formProps.url,
68+
content: formProps.content || '',
69+
children: []
70+
};
71+
return Promise.resolve({
72+
file
73+
});
74+
}
75+
76+
export function handleCreateFile(formProps) {
4077
return (dispatch, getState) => {
4178
const state = getState();
79+
const { files } = state;
4280
const { parentId } = state.ide;
43-
if (state.project.id) {
44-
const postParams = {
45-
name: createUniqueName(formProps.name, parentId, state.files),
46-
url: formProps.url,
47-
content: formProps.content || '',
48-
parentId,
49-
children: []
50-
};
51-
apiClient.post(`/projects/${state.project.id}/files`, postParams)
52-
.then((response) => {
53-
dispatch({
54-
type: ActionTypes.CREATE_FILE,
55-
...response.data.updatedFile,
56-
parentId
57-
});
58-
dispatch(setProjectSavedTime(response.data.project.updatedAt));
59-
dispatch(closeNewFileModal());
60-
dispatch(reset('new-file'));
61-
// dispatch({
62-
// type: ActionTypes.HIDE_MODAL
63-
// });
64-
dispatch(setUnsavedChanges(true));
65-
})
66-
.catch((error) => {
67-
const { response } = error;
68-
dispatch({
69-
type: ActionTypes.ERROR,
70-
error: response.data
71-
});
72-
});
73-
} else {
74-
const id = objectID().toHexString();
75-
dispatch({
76-
type: ActionTypes.CREATE_FILE,
77-
name: createUniqueName(formProps.name, parentId, state.files),
78-
id,
79-
_id: id,
80-
url: formProps.url,
81-
content: formProps.content || '',
82-
parentId,
83-
children: []
81+
const projectId = state.project.id;
82+
return new Promise((resolve) => {
83+
submitFile(formProps, files, parentId, projectId).then((response) => {
84+
const { file, updatedAt } = response;
85+
dispatch(createFile(file, parentId));
86+
if (updatedAt) dispatch(setProjectSavedTime(updatedAt));
87+
dispatch(closeNewFileModal());
88+
dispatch(setUnsavedChanges(true));
89+
resolve();
90+
}).catch((error) => {
91+
const { response } = error;
92+
dispatch(createError(response.data));
93+
resolve({ error });
8494
});
85-
dispatch(reset('new-file'));
86-
// dispatch({
87-
// type: ActionTypes.HIDE_MODAL
88-
// });
89-
dispatch(setUnsavedChanges(true));
90-
dispatch(closeNewFileModal());
91-
}
95+
});
96+
};
97+
}
98+
99+
export function submitFolder(formProps, files, parentId, projectId) {
100+
if (projectId) {
101+
const postParams = {
102+
name: createUniqueName(formProps.name, parentId, files),
103+
content: '',
104+
children: [],
105+
parentId,
106+
fileType: 'folder'
107+
};
108+
return apiClient.post(`/projects/${projectId}/files`, postParams)
109+
.then(response => ({
110+
file: response.data.updatedFile,
111+
updatedAt: response.data.project.updatedAt
112+
}));
113+
}
114+
const id = objectID().toHexString();
115+
const file = {
116+
type: ActionTypes.CREATE_FILE,
117+
name: createUniqueName(formProps.name, parentId, files),
118+
id,
119+
_id: id,
120+
content: '',
121+
// TODO pass parent id from File Tree
122+
fileType: 'folder',
123+
children: []
92124
};
125+
return Promise.resolve({
126+
file
127+
});
93128
}
94129

95-
export function createFolder(formProps) {
130+
export function handleCreateFolder(formProps) {
96131
return (dispatch, getState) => {
97132
const state = getState();
133+
const { files } = state;
98134
const { parentId } = state.ide;
99-
if (state.project.id) {
100-
const postParams = {
101-
name: createUniqueName(formProps.name, parentId, state.files),
102-
content: '',
103-
children: [],
104-
parentId,
105-
fileType: 'folder'
106-
};
107-
apiClient.post(`/projects/${state.project.id}/files`, postParams)
108-
.then((response) => {
109-
dispatch({
110-
type: ActionTypes.CREATE_FILE,
111-
...response.data.updatedFile,
112-
parentId
113-
});
114-
dispatch(setProjectSavedTime(response.data.project.updatedAt));
115-
dispatch(closeNewFolderModal());
116-
})
117-
.catch((error) => {
118-
const { response } = error;
119-
dispatch({
120-
type: ActionTypes.ERROR,
121-
error: response.data
122-
});
123-
});
124-
} else {
125-
const id = objectID().toHexString();
126-
dispatch({
127-
type: ActionTypes.CREATE_FILE,
128-
name: createUniqueName(formProps.name, parentId, state.files),
129-
id,
130-
_id: id,
131-
content: '',
132-
// TODO pass parent id from File Tree
133-
parentId,
134-
fileType: 'folder',
135-
children: []
135+
const projectId = state.project.id;
136+
return new Promise((resolve) => {
137+
submitFolder(formProps, files, parentId, projectId).then((response) => {
138+
const { file, updatedAt } = response;
139+
dispatch(createFile(file, parentId));
140+
if (updatedAt) dispatch(setProjectSavedTime(updatedAt));
141+
dispatch(closeNewFolderModal());
142+
dispatch(setUnsavedChanges(true));
143+
resolve();
144+
}).catch((error) => {
145+
const { response } = error;
146+
dispatch(createError(response.data));
147+
resolve({ error });
136148
});
137-
dispatch(closeNewFolderModal());
138-
}
149+
});
139150
};
140151
}
141152

client/modules/IDE/actions/ide.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,3 +278,10 @@ export function stopSketch() {
278278
dispatch(stopVisualSketch());
279279
};
280280
}
281+
282+
export function createError(error) {
283+
return {
284+
type: ActionTypes.ERROR,
285+
error
286+
};
287+
}

0 commit comments

Comments
 (0)