Skip to content

Commit

Permalink
migrate to prisma 2, and manual deploy to Heroku (#82)
Browse files Browse the repository at this point in the history
* expose database port in the docker config

* migrate prisma datamodel to prisma schema by introspection and manual schema edit

prisma-upgrade does not seem to work correctly for now

* upgrade packages, remove prisma1, install prisma client, and generate

* store prisma 1 generated graphql as a legacy

* fix minor bugs in the prisma schema

* migrate core code to test for graphql user query

comment out most of the unmigrated code to avoid tsc errors

* clean

* add missing application level phoenix secret

* fix all tests

* migrate all application code within SDL

* fix github actions dev workflow

* unify all prisma client instances to one module

* fix jest tests running some async call, being unable to terminate due to multiple prisma instances not disconnecting

* reset database to start fresh

* enable graphql playground in production

* fix postbuild script

* fix github actions prod workflow

* fix scripts, and separate dockerfiles into prod and dev

dev docker image does prisma migrate deploy before starting
  • Loading branch information
98sean98 authored Jun 10, 2021
1 parent c354fda commit 6676047
Show file tree
Hide file tree
Showing 53 changed files with 4,014 additions and 3,742 deletions.
12 changes: 8 additions & 4 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
NODE_ENV=development
PRISMA_HOST=
PRISMA_SECRET=
GOOGLE_CLIENT_ID=
# database
DATABASE_URL=postgresql://prisma:prisma@localhost:5432/prisma?schema=prisma$default
DB_USER=prisma
DB_PASSWORD=prisma

# application
PHOENIX_SECRET=
GOOGLE_CLIENT_ID=798725565697-sfibjdadpcan9ks908dnl8p5k1dncmoq.apps.googleusercontent.com
NODEMAILER_PASSWORD=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
Expand Down
13 changes: 5 additions & 8 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ on:
pull_request:

env:
PRISMA_HOST: http://localhost:4466/prisma
PRISMA_MANAGEMENT_API_SECRET: secret123
PRISMA_SECRET: secret123
DB_HOST: postgres
PHOENIX_SECRET: secret123
DATABASE_URL: postgresql://prisma:prisma@localhost:5432/prisma?schema=public
DB_USER: prisma
DB_PASSWORD: prisma
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
Expand All @@ -34,10 +32,9 @@ jobs:

- name: Install
run: |
docker-compose -f prisma/docker-compose.yml up -d
npm install -g prisma1
docker-compose -f docker-compose.yml up -d
npm install
cd prisma && prisma1 generate && prisma1 deploy
npm run prisma:migrate:dev
- name: Test
run: npm run test
Expand All @@ -58,6 +55,6 @@ jobs:
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
file: ./dev.Dockerfile
push: true
tags: rctechclub/phoenix:dev
41 changes: 19 additions & 22 deletions .github/workflows/prod.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ on:
- master

env:
PRISMA_HOST: ${{ secrets.PRISMA_HOST }}
PRISMA_MANAGEMENT_API_SECRET: ${{ secrets.PRISMA_MANAGEMENT_API_SECRET }}
PRISMA_SECRET: ${{ secrets.PRISMA_SECRET }}
DB_HOST: ${{ secrets.DB_HOST }}
PHOENIX_SECRET: ${{ secrets.PHOENIX_SECRET }}
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DB_USER: ${{ secrets.DB_USER }}
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }}
Expand All @@ -30,9 +28,8 @@ jobs:

- name: Build
run: |
npm install -g prisma1
npm install
cd prisma && prisma1 generate && prisma1 deploy
npm run prisma:generate
npm run build
- name: Set up Docker Buildx
Expand All @@ -48,29 +45,29 @@ jobs:
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
file: ./prod.Dockerfile
push: true
tags: rctechclub/phoenix:prod

- name: Push latest to Docker Hub
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
file: ./prod.Dockerfile
push: true
tags: rctechclub/phoenix:latest

aws:
needs: dockerimage
runs-on: ubuntu-latest
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-2

- name: Update phoenix ECS service
run: |
aws ecs update-service --cluster phoenix --service phoenix --force-new-deployment --region us-east-2
# aws:
# needs: dockerimage
# runs-on: ubuntu-latest
# steps:
# - name: Configure AWS credentials
# uses: aws-actions/configure-aws-credentials@v1
# with:
# aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
# aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
# aws-region: us-east-2
#
# - name: Update phoenix ECS service
# run: |
# aws ecs update-service --cluster phoenix --service phoenix --force-new-deployment --region us-east-2
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ node_modules/
.DS_Store

.env
.env.legacy
.env.prod
prisma/.env
env.db
.env.prod.legacy
prisma/.env.legacy
prisma/.env.prod.legacy
*.tfvars
.terraform/
*.tfstate
Expand All @@ -15,4 +17,3 @@ env.db
dist/

src/generated
src/prisma.graphql
62 changes: 25 additions & 37 deletions __tests__/bookings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@ env.config();
import gql from "graphql-tag";
import moment from "moment";
import { createTestServerWithUserLoggedIn } from "./utils/server";
import { Room, User } from "../src/generated/prisma-client";
import { User } from "@prisma/client";
import { createTestClient } from "apollo-server-testing";
import { createUser, deleteUser, deleteUsers } from "./utils/users";
import { createRoom, deleteRoom } from "./utils/rooms";
import { createUser, deleteUsers, TestUserInfo } from "./utils/users";
import { createRoom, deleteRooms, TestRoomInfo } from "./utils/rooms";
import {
createBooking,
deleteBooking,
deleteBookings,
TestBookingInfo,
} from "./utils/bookings";
import { GraphQLResponse } from "apollo-server-types";

const testUserInfo: User = {
id: undefined,
const testUserInfo: TestUserInfo = {
username: "test123",
email: "[email protected]",
image_url: "http://url",
Expand All @@ -27,8 +26,7 @@ const testUserInfo: User = {
role: "USER",
};

const testUserInfo1: User = {
id: undefined,
const testUserInfo1: TestUserInfo = {
username: "test234",
email: "[email protected]",
image_url: "http://url234",
Expand All @@ -39,8 +37,7 @@ const testUserInfo1: User = {
role: "USER",
};

const testRoomInfo: Room = {
id: "",
const testRoomInfo: TestRoomInfo = {
number: "123",
name: "test",
};
Expand Down Expand Up @@ -72,6 +69,18 @@ const testInvalidBookingVariables = {
remark: "Hi",
};

beforeAll(async () => {
await deleteBookings();
await deleteRooms();
await deleteUsers();
});

afterEach(async () => {
await deleteBookings();
await deleteRooms();
await deleteUsers();
});

describe("Booking queries", () => {
test("can query all bookings", async () => {
// Create user in the database
Expand Down Expand Up @@ -110,17 +119,12 @@ describe("Booking queries", () => {
room: {
number: testRoomInfo.number,
},
start: testBookingInfo.start.toISOString(),
end: testBookingInfo.end.toISOString(),
start: testBookingInfo.start,
end: testBookingInfo.end,
remark: testBookingInfo.remark,
},
],
});

// Cleanup after test
await deleteBooking(booking);
await deleteRoom(room);
await deleteUser(user);
});
});

Expand Down Expand Up @@ -160,10 +164,6 @@ describe("Booking validation", () => {
});

expect(response.data).toEqual({ createBooking: null });

await deleteBooking(booking);
await deleteRoom(room);
await deleteUser(user);
});
});

Expand Down Expand Up @@ -198,8 +198,8 @@ describe("Booking mutations", () => {
const testUpdatedBookingInfo = {
id: booking.id,
room: testBookingInfo.room,
start: booking.start,
end: booking.end,
start: booking.start.toISOString(),
end: booking.end.toISOString(),
remark: "HelloWorld",
};
const result: GraphQLResponse = await client.mutate({
Expand All @@ -212,10 +212,6 @@ describe("Booking mutations", () => {
remark: testUpdatedBookingInfo.remark,
},
});

await deleteBooking(booking);
await deleteRoom(room);
await deleteUser(user);
});

test("do not allow to change other user's bookings", async () => {
Expand Down Expand Up @@ -249,8 +245,8 @@ describe("Booking mutations", () => {
const testUpdatedBookingInfo = {
id: booking.id,
room: "123",
start: booking.start,
end: booking.end,
start: booking.start.toISOString(),
end: booking.end.toString(),
remark: "HelloWorld",
};

Expand All @@ -259,9 +255,6 @@ describe("Booking mutations", () => {
variables: testUpdatedBookingInfo,
});
expect(result.errors[0].message).toEqual("Not Authorised!");
await deleteBooking(booking);
await deleteRoom(room);
await deleteUsers(user, user1);
});

test("allow users to delete their own bookings", async () => {
Expand All @@ -287,8 +280,6 @@ describe("Booking mutations", () => {
id: booking.id,
},
});
await deleteRoom(room);
await deleteUser(user);
});

test("do not allow users to delete other user's own bookings", async () => {
Expand All @@ -311,8 +302,5 @@ describe("Booking mutations", () => {
variables: { id: booking.id },
});
expect(result.errors[0].message).toEqual("Not Authorised!");
await deleteBooking(booking);
await deleteRoom(room);
await deleteUsers(user, user1);
});
});
27 changes: 13 additions & 14 deletions __tests__/events/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ env.config();
import gql from "graphql-tag";
import { GraphQLResponse } from "apollo-server-types";
import { createTestServerWithUserLoggedIn } from "../utils/server";
import { Event, User, Comment } from "../../src/generated/prisma-client";
import { Event, User, Comment } from "@prisma/client";
import { createTestClient } from "apollo-server-testing";
import { createUser, deleteUsers } from "../utils/users";
import { createUser, deleteUsers, TestUserInfo } from "../utils/users";
import {
createEvent,
deleteEvents,
Expand All @@ -16,9 +16,9 @@ import {
retrieveEventComments,
RetrieveEventCommentsInfo,
} from "../utils/events";
import { deleteComments } from "../utils/comments";

const testUserInfo: User = {
id: undefined,
const testUserInfo: TestUserInfo = {
username: "test123",
email: "[email protected]",
image_url: "http://url",
Expand All @@ -29,8 +29,7 @@ const testUserInfo: User = {
role: "USER",
};

const testUserInfo1: User = {
id: undefined,
const testUserInfo1: TestUserInfo = {
username: "test234",
email: "[email protected]",
image_url: "http://url234",
Expand All @@ -53,6 +52,12 @@ const testEventInfo: TestEventInfo = {

beforeAll(async () => await deleteUsers());

afterEach(async () => {
await deleteEvents();
await deleteComments();
await deleteUsers();
});

describe("event comment creation", () => {
test("should be able to create a new comment for an event", async () => {
const testUser: User = await createUser(testUserInfo);
Expand Down Expand Up @@ -88,8 +93,6 @@ describe("event comment creation", () => {
user: { id: testUser.id },
event: { id: testEvent.id },
});
await deleteEvents();
await deleteUsers();
});
});

Expand Down Expand Up @@ -125,12 +128,11 @@ describe("event comment deletion", () => {
variables: { id: testComment.id },
});

expect(deleteComment.id).toEqual(testComment.id);

const eventInfo: RetrieveEventCommentsInfo = { event_id: testEvent.id };
const testEventComments: Comment[] = await retrieveEventComments(eventInfo);
expect(testEventComments).toEqual([]);

await deleteEvents();
await deleteUsers();
});
});

Expand Down Expand Up @@ -168,8 +170,5 @@ describe("invalid event comment deletion", () => {
});

expect(response.errors[0].message).toEqual("Not Authorised!");

await deleteEvents();
await deleteUsers();
});
});
Loading

0 comments on commit 6676047

Please sign in to comment.