From 6e24614c547a92139d722916c1cbf5ea6b9fb1b4 Mon Sep 17 00:00:00 2001 From: ebby Date: Mon, 28 Sep 2026 12:28:28 +0200 Subject: [PATCH] added pipeline --- .forgejo/workflows/deploy_backend.yml | 60 ++++++++++++++++++ backend/pyproject.toml | 1 + backend/src/backend/.env | 4 +- .../__pycache__/config.cpython-314.pyc | Bin 629 -> 631 bytes .../backend/__pycache__/main.cpython-314.pyc | Bin 1343 -> 1348 bytes backend/src/backend/config.py | 4 +- .../authentication.cpython-314.pyc | Bin 3877 -> 3822 bytes .../__pycache__/database.cpython-314.pyc | Bin 1282 -> 1253 bytes .../src/backend/internal/authentication.py | 11 ++-- backend/src/backend/internal/database.py | 4 +- backend/src/backend/main.py | 8 ++- backend/src/backend/routers/health.py | 8 +++ backend/uv.lock | 2 + 13 files changed, 87 insertions(+), 15 deletions(-) create mode 100644 .forgejo/workflows/deploy_backend.yml create mode 100644 backend/src/backend/routers/health.py diff --git a/.forgejo/workflows/deploy_backend.yml b/.forgejo/workflows/deploy_backend.yml new file mode 100644 index 0000000..629e6d2 --- /dev/null +++ b/.forgejo/workflows/deploy_backend.yml @@ -0,0 +1,60 @@ +name: Build and Deploy Backend + +on: + push: + branches: + - main + paths: + - "backend/**" + - "pyproject.toml" + - "uv.lock" + - "deploy/deploy-backend.sh" + +jobs: + build_and_deploy: + runs-on: roadrunner + + container: + volumes: + - /opt/blauwasser-api:/opt/blauwasser-api + - /var/lib/blauwasser-api:/var/lib/blauwasser-api + + steps: + - name: Repository auschecken + uses: actions/checkout@v4 + + - name: Python einrichten + uses: actions/setup-python@v5 + with: + python-version: "3.14" + + # - name: Backend testen + # working-directory: backend + # run: | + # python -m pip install -U pip + # python -m pip install -e . + # pytest + + - name: Backend kopieren + run: | + rsync -a --delete \ + --exclude '.venv' \ + --exclude '__pycache__' \ + --exclude '*.db' \ + backend/ /opt/blauwasser-api/backend/ + cp pyproject.toml /opt/blauwasser-api/ + cp uv.lock /opt/blauwasser-api/ + + - name: Abhängigkeiten aktualisieren + run: | + cd /opt/blauwasser-api + uv sync --frozen + + - name: Backend neu starten + run: | + systemctl restart blauwasser-api + systemctl is-active --quiet blauwasser-api + + - name: Deployment prüfen + run: | + curl --fail https://api.blauwasser-mausis.de/health diff --git a/backend/pyproject.toml b/backend/pyproject.toml index f989521..51c677d 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "fastapi-crons==2.5.0", "feedparser==6.0.14", "PyJWT==2.15.0", + "python-dotenv>=1.0.0", ] [project.scripts] diff --git a/backend/src/backend/.env b/backend/src/backend/.env index 5373d21..7adc803 100644 --- a/backend/src/backend/.env +++ b/backend/src/backend/.env @@ -1,6 +1,6 @@ BACKEND_URL="http://localhost:8000" FRONTEND_URL="http://localhost:4321" -SECRET="IamALocalSecretAndMustBeReplacedInProduction" +JWT_SECRET="IamALocalSecretAndMustBeReplacedInProduction" ENVIRONMENT="local" MAILTRAP_API_TOKEN="FakedyFake" -DB_NAME="dev" \ No newline at end of file +DATABASE_URL="sqlite:///dev.db" \ No newline at end of file diff --git a/backend/src/backend/__pycache__/config.cpython-314.pyc b/backend/src/backend/__pycache__/config.cpython-314.pyc index 72a94f4b28abdd90b4e38e7deb6f86530527ab05..35f9faa727140bc2c39c78813a376335a8277a83 100644 GIT binary patch delta 95 zcmey$@|}fGn~#@^fq{YHgxRhvF2;>~DvYdLUg06}lZ_e8czIkLLmZtPgI(i8gM20z zGK#Pku`n<&OrFSC!pJw7jY*4z=PIx2WD_QRA%4OBs?MqzdRO^1n|O+N7#J7;I#(8v delta 108 zcmV-y0F(ds1oZ?CD-I0`00000X=Ax+`~a~IBmn^ilQ#i2CxCFasvPW0NM&uMMF|WR9{O)S(B3ibO8^O2m&eu2-OWClQse`5(*5DDv2tP OS=9<3f(LR90000xM;w&^ diff --git a/backend/src/backend/__pycache__/main.cpython-314.pyc b/backend/src/backend/__pycache__/main.cpython-314.pyc index 76bdec7db25af450b89af9cc8ebf888930edea54..a6b028dd60e5102772106f517e68f75f644226eb 100644 GIT binary patch delta 59 zcmV-B0L1^l3d9NxD-I0`00000+c~;wm$41|0s#_}2?K)x7n6+x84L?#Z**mDb}nsU RX>OCP1M36j03(x|1f=sD5|ID^ delta 54 zcmV-60LlNv3cm^sD-I0`00000CSAE|k+BW?0s#?|2?K)x7L$zw83zVrZ**mDc9XIL M>jT{Y9+RL1q=a!07XSbN diff --git a/backend/src/backend/config.py b/backend/src/backend/config.py index ecc7090..fe5f0c7 100644 --- a/backend/src/backend/config.py +++ b/backend/src/backend/config.py @@ -1,8 +1,8 @@ import os ENVIRONMENT = os.environ["ENVIRONMENT"] -SECRET_KEY = os.environ["SECRET"] +JWT_SECRET = os.environ["JWT_SECRET"] FRONTEND_URL = os.environ["FRONTEND_URL"] BACKEND_URL = os.environ["BACKEND_URL"] MAILTRAP_API_TOKEN = os.environ["MAILTRAP_API_TOKEN"] -DB_NAME = os.environ["DB_NAME"] \ No newline at end of file +DATABASE_URL = os.environ["DATABASE_URL"] \ No newline at end of file diff --git a/backend/src/backend/internal/__pycache__/authentication.cpython-314.pyc b/backend/src/backend/internal/__pycache__/authentication.cpython-314.pyc index 22f024c8d336f1869fc309ef17662dd644f631f8..5733d3569dab8b75229a660808efe20a3a3751f5 100644 GIT binary patch delta 1209 zcmah}L66&15T2LVvEwA(WH*U7akt5`+OE<Mw# z;}^B%lJXO(Ck{Pu7zJ>lZv**eYiE3tmwa70&r3Z&55Noc9afl2}r>;A>u4lohu9iRM*AML7$; z+<`-j2<9?WHHIQUrh`9Y*&stI$~Vu_Rw; zo#iz7*^3{2a4qn+y^mWORsaC2@?E{jYO<%-^y5@VPV~>1D}UB6ZI&q|gItU;e8Q4+ zEU?9J831A$`ZcUk1?sL$gAS?y@DTn6jcu|&m3`KkJ<*jSld!V9X54(!rs+~hVkY`Q z4@DfO0N_|t)l9PcTpuLHnUd_yVq|Gd`aPv!=5 zreNU}+*2zq9VLQzrr73;TM^u^C39xfhMYK`X1eAqj>i z@zeNy-bebVFeh*18)u0%ULxbE^Kr~E)=14`&AFaM(z8ECr*&6g(Fkgm_mI@?#iM3 J!QRuTz(0S@28jRw delta 1247 zcmah{F^n5k5S{P!dUt(ZpU)S2ZQtJ6$AJ$g!YAU;gcHaLCw6rq9Ge3{;X91Icjv^} zb!NYn7zqpwee^{^K}iu&h6bfU6shQdW|2!Gkpe+Qi{{%wqChnB-^~1(|K|Pqef_Hq z^Fr240|5NG|Lu+Fo>^wzz3r_jPac7nbX6zCQ&l(uPjxj%=eooxS9J_-NUXVcuC@%YdR)3C0=n&r_9S$@bbLkt@1U`_Rd-06)YI$hK$=CV-qgXgaE+T zJNhPc)-SQS-(p_T0?%69-SA2lcx4OT8s>PlQ`&^i#?!0PD?IgD39n*-x3(y(dCC?v z)_u-AQq4P!~iA4ZFOVrdFtBAH*RxeN= zajd@2Z1J7?+ChOzQt0zB2KQO4L>wCo%K#A3_|IU4I?(IV)F?qsKY_m>$qv|`(tgvL zpJ=_%UK0oH+O+UcP08kT;wCl_k75%6s zNvZSP3jlBpn^Lp?=2aJ8>)Xs0Kk8rZ*X2lkzZdp>BuVgjiYTW(ZzOP+ur}&WhGDn= zFG87l$%4}rqADI5O=gQH#=*cQ8WmHMgn&znEfAa=fya^#q0-Pq;Io}7XjeI z?Awu#wIJlRlW-jL8-{!hNiZ~sU(&zp_i%~)jM&XoFB5CrBjd{aIPx)~+3NM$LeCuO z*&8GJ0Y9cZUIl>j;`7Y+)6F==C!;}diVBryKj`*u`a!?h3xkuvsT3(rgi)M3=|;Re z8Z;xnH^u>Hq)$ diff --git a/backend/src/backend/internal/__pycache__/database.cpython-314.pyc b/backend/src/backend/internal/__pycache__/database.cpython-314.pyc index d9d2f91712f30420649a2acb91919fcefd408cbc..1cc352573ef6df4aefba49481e9443aea0af73db 100644 GIT binary patch delta 143 zcmZqTddkVG&Bx2dz`(#DVYVyl#YA37#*&HZj=r&sB^*I)LG1dBC7iMBiVU$Fv7A91 z=1d@!3=Ab)L7d_YCEP(=;tWCD;tV+gB|Jeq$_$#kFG13pjJJ4P977zP9D`lsLxX%K s?l9f>Zzr>~B?AM)2WCb_#=8vacNtXgGRWLzkiE;G^nh1#@@*D%08mdM5&!@I delta 173 zcmaFL*~G=G&Bx2dz`(#znY=UW!$e+5#+r%hjsZbzv5Y(nLF`7%B^*H str: raise HTTPException(status_code=403, detail="Invalid authorization format") def decode_token(token: str)-> str | None: - payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) + payload = jwt.decode(token, JWT_SECRET, algorithms=[ALGORITHM]) return payload.get("sub") async def get_current_user(token: str = Depends(get_token), session: Session = Depends(get_session)): diff --git a/backend/src/backend/internal/database.py b/backend/src/backend/internal/database.py index 12ad585..2d051b1 100644 --- a/backend/src/backend/internal/database.py +++ b/backend/src/backend/internal/database.py @@ -1,10 +1,10 @@ -from backend.config import DB_NAME +from backend.config import DATABASE_URL from collections.abc import Generator from sqlmodel import Session from sqlmodel import SQLModel from sqlmodel import create_engine -sqlite_url = f"sqlite:///{DB_NAME}.db" +sqlite_url = DATABASE_URL connect_args = {"check_same_thread": False} engine = create_engine(sqlite_url, connect_args=connect_args) diff --git a/backend/src/backend/main.py b/backend/src/backend/main.py index d81fb80..3bcb65b 100644 --- a/backend/src/backend/main.py +++ b/backend/src/backend/main.py @@ -1,7 +1,8 @@ -from dotenv import load_dotenv + +from dotenv.main import load_dotenv load_dotenv() -from .routers import users, comments, newsletters +from .routers import users, comments, newsletters, health from backend.internal.database import create_db_and_tables from fastapi import FastAPI from fastapi_crons import Crons @@ -26,4 +27,5 @@ def on_startup(): app.include_router(users.router) app.include_router(comments.router) -app.include_router(newsletters.router) \ No newline at end of file +app.include_router(newsletters.router) +app.include_router(health.router) \ No newline at end of file diff --git a/backend/src/backend/routers/health.py b/backend/src/backend/routers/health.py new file mode 100644 index 0000000..fcfe611 --- /dev/null +++ b/backend/src/backend/routers/health.py @@ -0,0 +1,8 @@ +from fastapi import APIRouter + +router = APIRouter() + + +@router.get("/health", include_in_schema=False) +def health(): + return {"status": "ok"} \ No newline at end of file diff --git a/backend/uv.lock b/backend/uv.lock index 573bc4d..6b0c411 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -152,6 +152,7 @@ dependencies = [ { name = "mailtrap" }, { name = "pyjwt" }, { name = "pytest" }, + { name = "python-dotenv" }, { name = "sqlmodel" }, ] @@ -165,6 +166,7 @@ requires-dist = [ { name = "mailtrap", specifier = "==2.10.0" }, { name = "pyjwt", specifier = "==2.15.0" }, { name = "pytest", specifier = ">=9.1.1" }, + { name = "python-dotenv", specifier = ">=1.0.0" }, { name = "sqlmodel", specifier = ">=0.0.42" }, ]