Skip to content

Commit

Permalink
Merge pull request #62 from Clochette-AbsINThe/dev
Browse files Browse the repository at this point in the history
Test of the new CI/CD and integration of patch
  • Loading branch information
SamuelGuillemet authored Nov 19, 2022
2 parents a72a6c8 + c7ead78 commit 9947f32
Show file tree
Hide file tree
Showing 26 changed files with 690 additions and 196 deletions.
38 changes: 38 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: deploy

on:
push:
branches: [main]

jobs:
release-on-push:
runs-on: ubuntu-latest
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- id: release
uses: rymndhng/release-on-push-action@master
with:
bump_version_scheme: patch
tag_prefix: v
release_name: <RELEASE_TAG>
max_commits: 50
- name: Check Output Parameters
run: |
echo "Got tag name ${{ steps.release.outputs.tag_name }}"
echo "Got release version ${{ steps.release.outputs.version }}"
deploy:
runs-on: ubuntu-latest
needs: release-on-push
steps:
- uses: actions/checkout@v3
- name: Deploy
uses: appleboy/ssh-action@dce9d565de8d876c11d93fa4fe677c0285a66d78
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd clochette
./DeployDocker.sh
41 changes: 41 additions & 0 deletions .github/workflows/frontend-checks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: frontend-checks

on:
push:
branches: [dev]

defaults:
run:
working-directory: frontend

jobs:
frontend-checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: "18"
cache-dependency-path: frontend/package.json
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Verify lint
run: npm run lint

- name: Verify format
run: npm run format -- -c

- name: Test frontend and get coverage
run: npm run coverage

- name: Upload coverage reports to Codecov with GitHub Action
uses: codecov/codecov-action@v3
with:
files: ./coverage/coverage-final.json
fail_ci_if_error: true
working-directory: frontend
2 changes: 1 addition & 1 deletion DeployDocker.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
echo "Build the docker image"
echo
cd docker || exit
docker compose -f "docker-compose.yml" up -d --build
docker-compose up -d --build
2 changes: 1 addition & 1 deletion backend/app/api/v1/endpoints/out_of_stock_item.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ async def delete_out_of_stock_item(out_of_stock_item_id: int, db=Depends(get_db)
status_code=status.HTTP_404_NOT_FOUND,
detail="Out of stock item not found"
)
if out_of_stocks.query(db, limit=1, out_of_stock_item_id=out_of_stock_item_id):
if out_of_stocks.query(db, limit=1, item_id=out_of_stock_item_id):
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail="Out of stock item is in use"
Expand Down
23 changes: 19 additions & 4 deletions backend/app/core/config.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import os

from collections.abc import Callable
from humps import camelize
from pydantic import AnyHttpUrl, BaseModel, BaseSettings, EmailStr, validator

from app.core.utils.alert_backend import alert_to_terminal

class DefaultModel(BaseModel):
class Config:
alias_generator = camelize
allow_population_by_field_name = True


class Settings(BaseSettings):
ALERT_BACKEND: Callable[[str, Exception], None] = alert_to_terminal
ALERT_BACKEND: str = os.environ.get('ALERT_BACKEND', default='terminal')

API_V1_PREFIX: str = "/api/v1"

Expand All @@ -30,6 +27,10 @@ def assemble_cors_origins(cls, v: str | list[str]) -> str | list[str]:
return v
raise ValueError(v)

HOST_NAME: str = os.environ.get('HOST_NAME')

### Database config

POSTGRES_HOST = os.environ.get('POSTGRES_HOST')
POSTGRES_PORT = os.environ.get('POSTGRES_PORT')
POSTGRES_DB = os.environ.get('POSTGRES_DB')
Expand All @@ -44,6 +45,20 @@ def assemble_cors_origins(cls, v: str | list[str]) -> str | list[str]:
db=POSTGRES_DB
)

###

### Github config

GITHUB_USER: str = os.environ.get('GITHUB_USER')
GITHUB_TOKEN: str = os.environ.get('GITHUB_TOKEN')

ISSUE_LABELS: str = os.environ.get('ISSUES_LABELS')
REPOSITORY_NAME: str = os.environ.get('REPOSITORY_NAME')
REPOSITORY_OWNER: str = os.environ.get('REPOSITORY_OWNER')


###

class Config:
case_sensitive = True

Expand Down
19 changes: 12 additions & 7 deletions backend/app/core/middleware.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from collections.abc import Callable
from fastapi.requests import Request
from fastapi.responses import Response
from fastapi import status
from starlette.background import BackgroundTask
from starlette.middleware.base import BaseHTTPMiddleware


class ExceptionMonitorMiddleware(BaseHTTPMiddleware):
def __init__(self, app, alert_backend: callable):
def __init__(self, app, alert_backend: Callable[[Exception, dict], None]):
super().__init__(app)
self.alert_backend = alert_backend

Expand All @@ -26,14 +28,17 @@ async def dispatch(self, request: Request, call_next):
return await call_next(request)
except Exception as e:
body = await self.get_body(request)
self.alert_backend(
exception=e,
print(type(self.alert_backend))
task = BackgroundTask(
self.alert_backend,
e,
method=request.method,
url=request.url,
headers=request.headers,
body=body,
)
return Response(
"Internal Server Error, administrator has been notified",
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
)
return Response(
content="Internal Server Error, admin has been notified",
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
background=task
)
84 changes: 83 additions & 1 deletion backend/app/core/utils/alert_backend.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,91 @@
from collections.abc import Callable
from devtools import pprint
from traceback import format_exception

from app.core.config import settings


def alert_backend() -> Callable[[Exception, dict], None]:
if settings.ALERT_BACKEND == "terminal":
return alert_to_terminal
elif settings.ALERT_BACKEND == "github":
return alert_to_github_issues
else:
print("Invalid alert backend: {backend}".format(
backend=settings.ALERT_BACKEND
))
print("Falling back to terminal alert")
return alert_to_terminal


def alert_to_terminal(exception: Exception, **request: dict) -> None:
print("### An exception has been raised! ###")
print("############## Request ##############")
pprint(request)
print("############# Exception #############")
pprint(exception)
#format_exception(type(exception), exception, exception.__traceback__)
pprint(exception)


def alert_to_github_issues(exception: Exception, **request: dict) -> None:
# Format the exception and request to markdown
body = "# {type}: {msg}\n\n".format(
type=exception.__class__.__name__,
msg=str(exception)
)
body += "{method} {url}\n\n".format(
method=request["method"],
url=request["url"]
)
body += "## Request headers\n"
body += "\n".join(
"- **{key}**: {value}".format(
key=key,
value=value
)
for key, value in request["headers"].items()
)
body += "\n\n"
body += "## Request body\n"
body += "```\n"
body += request["body"].decode()
body += "\n```\n\n"
body += "## Exception traceback\n"
body += "```\n"
body += "".join(format_exception(type(exception), exception, exception.__traceback__))
body += "\n```\n\n"

# Create the issue on github
import requests
import json

url = "https://api.github.com/repos/{owner}/{repo}/issues".format(
owner=settings.REPOSITORY_OWNER,
repo=settings.REPOSITORY_NAME
)

session = requests.Session()
session.auth = (settings.GITHUB_USER, settings.GITHUB_TOKEN)

payload = {
"title": "[bug] [production] {type}: {msg}".format(
type=exception.__class__.__name__,
msg=str(exception)
),
"body": body,
"labels": [label for label in settings.ISSUE_LABELS.split(",") if label],
}

response = session.post(url, data=json.dumps(payload))

if response.status_code != 201:
print("Failed to create issue on github: {status_code}".format(
status_code=response.status_code
))
print(response.content)
print("Falling back to terminal alert")
alert_to_terminal(exception, **request)
else:
print("Issue created on github: {url}".format(
url=response.json()["html_url"]
))
5 changes: 3 additions & 2 deletions backend/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import shlex
import subprocess

from fastapi import FastAPI, APIRouter
from fastapi import APIRouter, FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from time import sleep

from app.api.v1.api import api_v1_router
from app.core.config import settings
from app.core.middleware import ExceptionMonitorMiddleware
from app.core.utils.alert_backend import alert_backend


app = FastAPI(
Expand All @@ -18,7 +19,7 @@
)

app.add_middleware(
ExceptionMonitorMiddleware, alert_backend=settings.ALERT_BACKEND
ExceptionMonitorMiddleware, alert_backend=alert_backend()
)
app.add_middleware(
TrustedHostMiddleware, allowed_hosts=settings.ALLOWED_HOSTS
Expand Down
4 changes: 4 additions & 0 deletions backend/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ alembic==1.8.1
anyio==3.6.2
asttokens==2.1.0
autopep8==2.0.0
certifi==2022.9.24
charset-normalizer==2.1.1
click==8.1.3
colorama==0.4.6
devtools==0.9.0
Expand All @@ -19,13 +21,15 @@ pydantic==1.10.2
pyhumps==3.8.0
python-dotenv==0.21.0
PyYAML==6.0
requests==2.28.1
six==1.16.0
sniffio==1.3.0
SQLAlchemy==1.4.44
starlette==0.21.0
toml==0.10.2
tomli==2.0.1
typing_extensions==4.4.0
urllib3==1.26.12
uvicorn==0.19.0
uvloop==0.17.0
watchfiles==0.18.1
Expand Down
8 changes: 7 additions & 1 deletion docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,13 @@ services:
- POSTGRES_DB=clochette
- POSTGRES_USER=clochette
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- MIGRATE=True
- MIGRATE=${MIGRATE}
- ALERT_BACKEND=github # Default is terminal if not set
- GITHUB_USER=${GITHUB_USER}
- GITHUB_TOKEN=${GITHUB_TOKEN}
- ISSUE_LABELS=Backend,bug,bot
- REPOSITORY_NAME=${REPOSITORY_NAME}
- REPOSITORY_OWNER=${REPOSITORY_OWNER}

database:
image: postgres:14.5-alpine
Expand Down
Loading

0 comments on commit 9947f32

Please sign in to comment.