Skip to content

Commit

Permalink
Add initial e2e workflow with an API healthcheck and required mods to…
Browse files Browse the repository at this point in the history
… the dockerfiles.
  • Loading branch information
Joshua-Douglas committed Apr 15, 2024
1 parent d81ae1b commit 20cea1e
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 10 deletions.
117 changes: 117 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
name: E2E Tests

on:
push:
pull_request:
workflow_dispatch:
jobs:
build-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push API Image
run: |
IMAGE_NAME=ghcr.io/hackforla/homeuniteus/api:latest
docker build -t $IMAGE_NAME ./api
docker push $IMAGE_NAME
build-app:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and Push Testing Image
run: |
IMAGE_NAME=ghcr.io/hackforla/homeuniteus/app:latest-test
docker build --build-arg VITE_HUU_API_BASE_URL=http://127.0.0.1:8080/api --target development --tag $IMAGE_NAME ./app
docker push $IMAGE_NAME
- name: Build Production Image
run: |
IMAGE_NAME=ghcr.io/hackforla/homeuniteus/app:latest
docker build --build-arg VITE_HUU_API_BASE_URL=http://127.0.0.1:8080/api --target production --tag $IMAGE_NAME ./app
docker push $IMAGE_NAME
test-api-mock:
runs-on: ubuntu-latest
needs: [build-api]
steps:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run Tests With 3rd Party Service Mocking
run: docker run --rm --no-healthcheck ghcr.io/hackforla/homeuniteus/api:latest pytest
test-api-nomock:
runs-on: ubuntu-latest
needs: [build-api]
env:
COGNITO_REGION: ${{ secrets.COGNITO_REGION }}
COGNITO_ACCESS_ID: ${{ secrets.COGNITO_ACCESS_ID }}
COGNITO_ACCESS_KEY: ${{ secrets.COGNITO_ACCESS_KEY }}
steps:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run Tests Without Mocking
run: |
docker run --rm -e COGNITO_REGION -e COGNITO_ACCESS_ID -e COGNITO_ACCESS_KEY ghcr.io/hackforla/homeuniteus/api:latest "pytest --mode=release"
test-app-mock:
runs-on: ubuntu-latest
needs: [build-app, build-api]
services:
frontend:
image: ghcr.io/hackforla/homeuniteus/app:latest-test
env:
VITE_HUU_API_BASE_URL: http://127.0.0.1:8080/api
container:
image: ghcr.io/hackforla/homeuniteus/app:latest-test
options: --entrypoint /bin/bash --no-healthcheck
env:
CYPRESS_BASE_URL: http://frontend:4040
CYPRESS_USE_MOCK: true
steps:
- name: Run Tests With Backend Mocking
run: |
cd /app
npx cypress run
test-app-nomock:
runs-on: ubuntu-latest
needs: [build-app, build-api]
services:
backend:
image: ghcr.io/hackforla/homeuniteus/api:latest
env:
ENV: development
HOST: 0.0.0.0
frontend:
image: ghcr.io/hackforla/homeuniteus/app:latest-test
env:
VITE_HUU_API_BASE_URL: http://backend:8080/api
container:
image: ghcr.io/hackforla/homeuniteus/app:latest-test
options: --entrypoint /bin/bash --no-healthcheck
env:
CYPRESS_BASE_URL: http://frontend:4040
CYPRESS_USE_MOCK: false
CYPRESS_REAL_EMAIL: [email protected]
CYPRESS_REAL_PASSWORD: Test!123
steps:
- name: Test using a real backend
run: npx cypress run
working-directory: /app
15 changes: 12 additions & 3 deletions api/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# TODO: Run the openapi_server with nginx as reverse proxy and gunicorn as WSGI server
FROM python:3.10-alpine

RUN apk update && apk add build-base
RUN apk update && apk add build-base && apk add curl

RUN mkdir -p /opt/HomeUniteUs/api
WORKDIR /opt/HomeUniteUs/api
Expand All @@ -10,7 +10,16 @@ COPY . .

RUN python -m pip install --upgrade pip
RUN python -m pip install --no-cache-dir -r requirements-dev.txt
# Create an up-to-date database within the API container
# To-Do: Separate the database to its own container
RUN alembic upgrade head

EXPOSE 8080
ENTRYPOINT ["python"]
CMD ["-m", "openapi_server"]
ENTRYPOINT ["/bin/sh", "-c"]
# We can decrease the number of health checks when
# v25.0 docker engine is release. This engine will
# provide a --start-interval option that allows a custom
# startup health check interval
HEALTHCHECK --interval=5s --timeout=5s --retries=3 \
CMD curl --fail http://${HOST:-localhost}:${PORT:-8080}/api/health || exit 1
CMD ["python -m openapi_server"]
9 changes: 8 additions & 1 deletion api/openapi_server/controllers/admin_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,11 @@ def removeUser(body: dict):
raise AuthError({"message": msg}, 400)
case _:
msg = error.response['Error']['Message']
raise AuthError({"message": msg}, 500)
raise AuthError({"message": msg}, 500)

def health():
'''
The health check endpoint always returns a successful status code.
This is useful for determining whether the API startup was successful.
'''
return 'API is healthy 😎', 200
8 changes: 8 additions & 0 deletions api/openapi_server/openapi/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ paths:
$ref: "./paths/auth/authInvite.yaml"
/auth/confirmInvite:
$ref: "./paths/auth/authConfirmInvite.yaml"
/health:
get:
operationId: openapi_server.controllers.admin_controller.health
summary: Health Check
description: Returns the health status of the API.
responses:
'200':
description: API is healthy.
components:
securitySchemes:
jwt:
Expand Down
24 changes: 18 additions & 6 deletions app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
# Named temprorary image to build client bundles
FROM node:lts-alpine as builder
ARG VITE_HUU_API_BASE_URL
ENV VITE_HUU_API_BASE_URL=${VITE_HUU_API_BASE_URL}

# do all copies/builds within a subdirectory
WORKDIR /app

# move source files into image
COPY . ./

# client package install
# Only install non-development dependencies
RUN npm install

# secrets
COPY .env .

# generate bundles from source
RUN npm run build

# Testing image (consider cypress/included images to get cypress installed by default)
FROM cypress/base as development
WORKDIR /app
RUN apt-get update && apt-get install -y curl

# Copy built assets and all source files from builder
COPY --from=builder /app .
RUN npx cypress install
HEALTHCHECK --interval=5s --timeout=5s --retries=3 \
CMD curl --fail http://127.0.0.1:4040 || exit 1
ENTRYPOINT ["/bin/sh", "-c"]
CMD ["npx vite --host"]

# Runtime image
FROM nginx
FROM nginx as production

# Copy client build to runtime image
COPY --from=builder /app/dist /usr/share/nginx/html/
Expand All @@ -31,4 +43,4 @@ RUN if [ -e "nginx.conf" ]; then \
# publish to a different port at Docker
# runtime environment level
EXPOSE 80

ENTRYPOINT ["/bin/sh", "-c"]

0 comments on commit 20cea1e

Please sign in to comment.