diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 337181b9..4cf30f72 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -3,12 +3,13 @@ name: e2e on: push: branches: - - main - - production + - main + - production + pull_request: jobs: test: - timeout-minutes: 60 + timeout-minutes: 15 runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 @@ -37,7 +38,7 @@ jobs: run: pnpm i --frozen-lockfile - name: Install Playwright Browsers run: pnpm exec playwright install --with-deps chromium - - name: Start DB and Redis + - name: Start Docker services (PostgreSQL, Redis, and S3) run: docker compose up -d - name: Build the api run: pnpm build:api @@ -45,10 +46,6 @@ jobs: run: pnpm --filter @beep/api db:create - name: Run Playwright tests run: pnpm --filter @beep/test test - env: - S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }} - S3_ACCESS_KEY_SECRET: ${{ secrets.S3_ACCESS_KEY_SECRET }} - S3_ENDPOINT_URL: ${{ secrets.S3_ENDPOINT_URL }} - uses: actions/upload-artifact@v3 if: always() with: diff --git a/README.md b/README.md index 4db06258..f9c00d8a 100644 --- a/README.md +++ b/README.md @@ -56,8 +56,8 @@ To run the development envrionment use in the repo's root pnpm dev ``` -By default, the api will use your local database and redis from docker. You should not need an `.env` to develop locally -You can create a `.env` in `api/` to set the API's env. (`vim api/.env`) +By default, the api will use your local database, redis, and s3 server from docker. You should not need an `.env` to develop locally +You can create a `.env` in `api/` to set the API's env if needed. (`vim api/.env`) ```env S3_ACCESS_KEY_ID=hkjvbyuverbvugfreukgsig diff --git a/api/src/users/resolver.ts b/api/src/users/resolver.ts index 483978de..b7d26b3a 100644 --- a/api/src/users/resolver.ts +++ b/api/src/users/resolver.ts @@ -15,6 +15,7 @@ import { password as bunPassword } from 'bun'; import { VerifyEmail } from '../entities/VerifyEmail'; import { GraphQLUpload } from 'graphql-upload-minimal'; import { setContext } from "@sentry/node"; +import { S3_BUCKET_URL } from '../utils/constants'; @ObjectType() class UsersPerDomain { @@ -188,7 +189,7 @@ export class UserResolver { const result = await s3.upload(uploadParams).promise(); if (ctx.user.photo) { - const key = ctx.user.photo.split("https://beep.us-east-1.linodeobjects.com/")[1]; + const key = ctx.user.photo.split(S3_BUCKET_URL)[1]; deleteObject(key); } diff --git a/api/src/utils/constants.ts b/api/src/utils/constants.ts index 25ec7ee7..7428e8f1 100644 --- a/api/src/utils/constants.ts +++ b/api/src/utils/constants.ts @@ -16,11 +16,15 @@ export const REDIS_HOST = process.env.REDIS_HOST || "localhost"; export const REDIS_PASSWROD = process.env.REDIS_PASSWORD; -export const S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID; +export const S3_ACCESS_KEY_ID = process.env.S3_ACCESS_KEY_ID ?? "beep"; -export const S3_ACCESS_KEY_SECRET = process.env.S3_ACCESS_KEY_SECRET; +export const S3_ACCESS_KEY_SECRET = process.env.S3_ACCESS_KEY_SECRET ?? "beepbeepbeep"; -export const S3_ENDPOINT_URL = process.env.S3_ENDPOINT_URL; +export const S3_ENDPOINT_URL = process.env.S3_ENDPOINT_URL ?? "http://localhost:9000"; + +export const isLocalS3 = S3_ACCESS_KEY_SECRET === "beepbeepbeep"; + +export const S3_BUCKET_URL = isLocalS3 ? "http://localhost:9000/beep/" : "https://beep.us-east-1.linodeobjects.com/"; export const MAIL_HOST = process.env.MAIL_HOST; diff --git a/api/src/utils/s3.ts b/api/src/utils/s3.ts index a5459c80..a04019a0 100644 --- a/api/src/utils/s3.ts +++ b/api/src/utils/s3.ts @@ -1,11 +1,12 @@ import * as Sentry from "@sentry/node"; import { S3 } from "aws-sdk"; -import { S3_ACCESS_KEY_ID, S3_ACCESS_KEY_SECRET, S3_ENDPOINT_URL } from "./constants"; +import { S3_ACCESS_KEY_ID, S3_ACCESS_KEY_SECRET, S3_ENDPOINT_URL, isLocalS3 } from "./constants"; export const s3 = new S3({ accessKeyId: S3_ACCESS_KEY_ID, secretAccessKey: S3_ACCESS_KEY_SECRET, - endpoint: S3_ENDPOINT_URL + endpoint: S3_ENDPOINT_URL, + s3ForcePathStyle: isLocalS3, }); export async function getAllObjects(params: S3.ListObjectsV2Request): Promise { diff --git a/docker-compose.yml b/docker-compose.yml index 0a834d2b..a6e4f4b1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,6 +15,27 @@ services: POSTGRES_USER: beep POSTGRES_PASSWORD: beep TZ: America/New_York + s3: + image: minio/minio + ports: + - "9000:9000" + environment: + MINIO_ACCESS_KEY: beep + MINIO_SECRET_KEY: beepbeepbeep + MINIO_ROOT_USER: beep + MINIO_ROOT_PASSWORD: beepbeepbeep + command: server ./data + bucket: + image: minio/mc + depends_on: + - s3 + entrypoint: > + /bin/sh -c " + /usr/bin/mc alias set beep http://s3:9000 beep beepbeepbeep; + /usr/bin/mc mb beep/beep; + /usr/bin/mc anonymous set public beep/beep; + exit 0; + " volumes: data: \ No newline at end of file