- Dockerfile: copie du code avant installation (le package installé n'est plus vide — I6), utilisateur non-root, HEALTHCHECK - compose: version: obsolète retiré, variables d'auth, healthcheck - pyproject: version 0.2.0, jinja2 <4, config pytest - LICENSE (MIT), CHANGELOG 0.2.0, README réécrit (configuration, sécurité, API, tests), .dockerignore
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.venv
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
.pytest_cache
|
||||||
|
*.egg-info
|
||||||
|
.env
|
||||||
|
/data/
|
||||||
|
.kanbante/
|
||||||
|
tests/
|
||||||
|
README.md
|
||||||
|
CHANGELOG.md
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
.pytest_cache/
|
||||||
.venv/
|
.venv/
|
||||||
.env
|
.env
|
||||||
*.egg-info/
|
*.egg-info/
|
||||||
|
|||||||
@@ -0,0 +1,73 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 0.2.0 — 2026-10-11
|
||||||
|
|
||||||
|
Consolidation complète à partir d'un audit du code 0.1.0 (chaque correctif
|
||||||
|
marqué « confirmé » avait été reproduit par un test avant correction).
|
||||||
|
|
||||||
|
### Critiques corrigés
|
||||||
|
- **Perte de données en Docker** : `KANBANTE_DB_PATH` est enfin lue par le
|
||||||
|
code — la base SQLite atterrit dans le volume `/data` comme prévu.
|
||||||
|
- **Authentification** : Basic Auth optionnelle mais recommandée
|
||||||
|
(`KANBANTE_AUTH_USER` / `KANBANTE_AUTH_PASSWORD`, `KANBANTE_REQUIRE_AUTH=1`
|
||||||
|
pour refuser de servir sans), protection CSRF (double-submit) sur tous
|
||||||
|
les POST, avertissement bruyant au démarrage quand l'auth est absente.
|
||||||
|
- **Synchro bidirectionnelle** : déplacer une carte vers « Terminé » ferme
|
||||||
|
l'issue dans Gitea, la ressortir la rouvre (`KANBANTE_SYNC_GITEA=0` pour
|
||||||
|
désactiver). L'état local est réconcilié à chaque chargement de board
|
||||||
|
(fermées → Terminé, supprimées → purgées).
|
||||||
|
|
||||||
|
### Importants corrigés
|
||||||
|
- Classification des projets : fenêtre d'activité glissante configurable
|
||||||
|
(`KANBANTE_ACTIVE_WINDOW_DAYS`, défaut 365) et vrai drapeau `archived`
|
||||||
|
de Gitea — fini l'année codée en dur et l'onglet « Archivés » mensonger.
|
||||||
|
- Pagination complète des appels Gitea (le plafond serveur de 50 réponses
|
||||||
|
par page ne tronque plus les dépôts ni les issues, en silence).
|
||||||
|
- `get_board_state` ne plante plus sur une colonne inconnue ; migration
|
||||||
|
automatique des bases 0.1.0 (colonne `position`, `notes.updated_at`,
|
||||||
|
nettoyage des lignes invalides).
|
||||||
|
- Gitea injoignable → page d'erreur 502 propre (JSON pour l'API) au lieu
|
||||||
|
d'un 500 brut ; `/api/readiness` teste réellement SQLite et Gitea,
|
||||||
|
`/api/health` reste un liveness sans dépendance.
|
||||||
|
- Dockerfile : installation après copie du code (le package installé
|
||||||
|
n'est plus vide), utilisateur non-root, `HEALTHCHECK`, `.dockerignore`.
|
||||||
|
|
||||||
|
### Ajouts
|
||||||
|
- **Ordre des cartes persisté** dans chaque colonne (aller-retour
|
||||||
|
glisser-déposer → rechargement).
|
||||||
|
- **Création d'issues** depuis le board (`POST /api/issues`).
|
||||||
|
- **Vue Focus** (`/focus`) : tout ce qui est En cours / En révision,
|
||||||
|
tous projets actifs confondus.
|
||||||
|
- Filtres par texte et par étiquette sur le board ; les cartes lient
|
||||||
|
vers l'issue Gitea ; les pull requests ne sont plus affichées comme
|
||||||
|
des issues.
|
||||||
|
- Suite de tests `pytest` (modèles, client Gitea, API, auth/CSRF) et
|
||||||
|
CI Gitea Actions (`.gitea/workflows/ci.yml`).
|
||||||
|
- Fichier `LICENSE` (MIT, annoncé par le README depuis la 0.1.0).
|
||||||
|
|
||||||
|
### Détails
|
||||||
|
- Client Gitea entièrement asynchrone (les routes ne bloquent plus la
|
||||||
|
boucle d'événements), cache mémoire court des listes, en-tête
|
||||||
|
`Authorization` seulement si un jeton est configuré, uid résolu via
|
||||||
|
`/user` (plus de `uid=1` ni d'utilisateur codés en dur), `.env` chargé
|
||||||
|
depuis la racine du projet seulement.
|
||||||
|
- Bibliothèques JS (HTMX, Alpine, SortableJS) **vendorées** dans
|
||||||
|
`static/vendor/` : plus aucune dépendance CDN à l'exécution.
|
||||||
|
- Glisser-déposer : en cas d'échec serveur, la carte est replacée et le
|
||||||
|
toast d'erreur est rouge ; les déplacements envoient l'ordre complet
|
||||||
|
des colonnes source et destination.
|
||||||
|
- API : codes HTTP corrects (400 colonne invalide, 403 CSRF, 413 note
|
||||||
|
trop longue — limite configurable), `lifespan` FastAPI à la place de
|
||||||
|
`on_event` déprécié, imports nettoyés.
|
||||||
|
- CSS : fond des badges corrigé (`color-mix()` remplace l'invalide
|
||||||
|
`var(--accent)20`).
|
||||||
|
- Recherche du dashboard : le nom des dépôts passe par un attribut
|
||||||
|
`data-search` échappé, plus aucune interpolation dans du JS.
|
||||||
|
- `docker-compose.yml` : clé `version:` obsolète retirée, variables
|
||||||
|
d'auth exposées, healthcheck.
|
||||||
|
|
||||||
|
## 0.1.0 — 2026-07-07
|
||||||
|
|
||||||
|
Version initiale : dashboard des projets Gitea, board Kanban 5 colonnes
|
||||||
|
par dépôt (glisser-déposer SortableJS), notes par projet, état local
|
||||||
|
SQLite, thème sombre, Dockerfile + docker-compose.
|
||||||
+16
-8
@@ -2,19 +2,27 @@ FROM python:3.12-slim
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Install dependencies
|
ENV PYTHONUNBUFFERED=1 \
|
||||||
COPY pyproject.toml .
|
KANBANTE_DB_PATH=/data/kanbante.db \
|
||||||
RUN pip install --no-cache-dir .
|
GITEA_URL=https://git.dracodev.net
|
||||||
|
|
||||||
|
# Copy the package BEFORE installing: with the 0.1.0 layout (install
|
||||||
|
# first, copy app/ afterwards) the installed distribution was empty and
|
||||||
|
# the app only worked by accident of the working directory.
|
||||||
|
COPY pyproject.toml ./
|
||||||
COPY app/ ./app/
|
COPY app/ ./app/
|
||||||
COPY static/ ./static/
|
COPY static/ ./static/
|
||||||
|
RUN pip install --no-cache-dir .
|
||||||
|
|
||||||
# Create data directory
|
# Persistent data directory (volume target) + non-root runtime user
|
||||||
RUN mkdir -p /data
|
RUN mkdir -p /data \
|
||||||
|
&& adduser --disabled-password --gecos "" appuser \
|
||||||
ENV KANBANTE_DB_PATH=/data/kanbante.db
|
&& chown -R appuser:appuser /data /app
|
||||||
ENV GITEA_URL=https://git.dracodev.net
|
USER appuser
|
||||||
|
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
|
|
||||||
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s \
|
||||||
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/api/health', timeout=4)"
|
||||||
|
|
||||||
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
|
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8080"]
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 Bruno Charest
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -4,13 +4,17 @@
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- 📋 **Dashboard** — tous tes projets Gitea en un coup d'œil (actifs / archivés)
|
- 📋 **Dashboard** — tous tes projets Gitea en un coup d'œil (actifs / inactifs / archivés — le vrai drapeau Gitea)
|
||||||
- 🗂️ **Kanban Board** — colonnes Backlog → À faire → En cours → Révision → Terminé
|
- 🗂️ **Kanban Board** — colonnes Backlog → À faire → En cours → Révision → Terminé, ordre des cartes persisté
|
||||||
- 🎯 **Drag & Drop** — glisse les issues entre colonnes
|
- 🎯 **Drag & Drop** — glisse les issues entre colonnes ; en cas d'échec, la carte est replacée
|
||||||
- 🔗 **Gitea Sync** — les issues Gitea deviennent des cartes Kanban
|
- 🔗 **Gitea Sync bidirectionnelle** — « Terminé » ferme l'issue dans Gitea, la ressortir la rouvre ; l'état local est réconcilié à chaque chargement
|
||||||
|
- ➕ **Création d'issues** depuis le board, filtres texte + étiquettes, cartes liées à Gitea
|
||||||
|
- 🎯 **Vue Focus** — tout ce qui est En cours / En révision, tous projets confondus (`/focus`)
|
||||||
- 📝 **Notes** — bloc-notes par projet
|
- 📝 **Notes** — bloc-notes par projet
|
||||||
|
- 🔐 **Authentification** Basic Auth intégrée + protection CSRF (voir Sécurité)
|
||||||
- 🌙 **Dark theme** — conçu pour les longues sessions
|
- 🌙 **Dark theme** — conçu pour les longues sessions
|
||||||
- 🐳 **Docker** — un seul conteneur, déploiement en 30 secondes
|
- 🐳 **Docker** — un seul conteneur, utilisateur non-root, healthcheck
|
||||||
|
- 📴 **Aucun CDN** — les bibliothèques JS sont vendorées dans `static/vendor/`, l'app fonctionne hors-ligne
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
@@ -22,6 +26,9 @@ pip install -e .
|
|||||||
# 2. Configurer les variables d'environnement
|
# 2. Configurer les variables d'environnement
|
||||||
export GITEA_URL=https://git.dracodev.net
|
export GITEA_URL=https://git.dracodev.net
|
||||||
export GITEA_TOKEN=ton_token_gitea
|
export GITEA_TOKEN=ton_token_gitea
|
||||||
|
# Recommandé dès que le service dépasse localhost :
|
||||||
|
export KANBANTE_AUTH_USER=ton_nom
|
||||||
|
export KANBANTE_AUTH_PASSWORD=ton_mot_de_passe
|
||||||
|
|
||||||
# 3. Lancer
|
# 3. Lancer
|
||||||
uvicorn app.main:app --reload --port 8080
|
uvicorn app.main:app --reload --port 8080
|
||||||
@@ -31,29 +38,34 @@ Ouvrir http://localhost:8080
|
|||||||
|
|
||||||
## Docker
|
## Docker
|
||||||
|
|
||||||
### Avec docker-compose (recommandé si docker-compose ≥ v2)
|
### Avec docker-compose (recommandé)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
echo "GITEA_TOKEN=ton_token" > .env
|
cat > .env <<'EOF'
|
||||||
|
GITEA_TOKEN=ton_token
|
||||||
|
KANBANTE_AUTH_USER=ton_nom
|
||||||
|
KANBANTE_AUTH_PASSWORD=ton_mot_de_passe
|
||||||
|
EOF
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
|
La base SQLite vit dans le volume `kanbante_data` (monté sur `/data`,
|
||||||
|
chemin `KANBANTE_DB_PATH`) : les positions de cartes et les notes
|
||||||
|
survivent aux recréations du conteneur.
|
||||||
|
|
||||||
### Avec docker uniquement
|
### Avec docker uniquement
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Builder l'image
|
|
||||||
docker build -t kanbante:latest .
|
docker build -t kanbante:latest .
|
||||||
|
|
||||||
# Créer le volume persistant
|
|
||||||
docker volume create kanbante_data
|
docker volume create kanbante_data
|
||||||
|
|
||||||
# Lancer
|
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name kanbante \
|
--name kanbante \
|
||||||
-p 8080:8080 \
|
-p 8080:8080 \
|
||||||
-v kanbante_data:/data \
|
-v kanbante_data:/data \
|
||||||
-e GITEA_URL=https://git.dracodev.net \
|
-e GITEA_URL=https://git.dracodev.net \
|
||||||
-e GITEA_TOKEN=ton_token \
|
-e GITEA_TOKEN=ton_token \
|
||||||
|
-e KANBANTE_AUTH_USER=ton_nom \
|
||||||
|
-e KANBANTE_AUTH_PASSWORD=ton_mot_de_passe \
|
||||||
--restart unless-stopped \
|
--restart unless-stopped \
|
||||||
kanbante:latest
|
kanbante:latest
|
||||||
```
|
```
|
||||||
@@ -61,26 +73,55 @@ docker run -d \
|
|||||||
### Déploiement sur Deepin 25 (Debian Bookworm)
|
### Déploiement sur Deepin 25 (Debian Bookworm)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Installer Docker
|
|
||||||
sudo apt install -y docker.io docker-compose docker-buildx
|
sudo apt install -y docker.io docker-compose docker-buildx
|
||||||
sudo usermod -aG docker $USER
|
sudo usermod -aG docker $USER
|
||||||
sudo systemctl enable --now docker
|
sudo systemctl enable --now docker
|
||||||
|
|
||||||
# Builder et lancer (voir section "Avec docker uniquement")
|
# Builder et lancer (voir section "Avec docker uniquement")
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
| Variable | Défaut | Rôle |
|
||||||
|
|---|---|---|
|
||||||
|
| `GITEA_URL` | `https://git.dracodev.net` | Instance Gitea |
|
||||||
|
| `GITEA_TOKEN` | *(vide)* | Jeton API Gitea — **portée conseillée : lecture + écriture des issues, sur un compte dédié, pas un jeton admin**. Sans jeton : contenu public seulement |
|
||||||
|
| `KANBANTE_DB_PATH` | `~/.kanbante/kanbante.db` | Base SQLite locale (en Docker : `/data/kanbante.db`) |
|
||||||
|
| `KANBANTE_AUTH_USER` / `KANBANTE_AUTH_PASSWORD` | *(vide)* | Active la Basic Auth dès que les deux sont définis |
|
||||||
|
| `KANBANTE_REQUIRE_AUTH` | `0` | `1` = l'app refuse de servir (503) si l'auth n'est pas configurée |
|
||||||
|
| `KANBANTE_ACTIVE_WINDOW_DAYS` | `365` | Un dépôt non archivé mis à jour depuis moins de N jours est « actif » |
|
||||||
|
| `KANBANTE_CACHE_TTL` | `30` | Secondes de cache des listes Gitea (dépôts, issues) |
|
||||||
|
| `KANBANTE_MAX_NOTE_CHARS` | `20000` | Taille maximale d'une note de projet |
|
||||||
|
| `KANBANTE_SYNC_GITEA` | `1` | `0` = les déplacements ne ferment/rouvrent plus les issues Gitea |
|
||||||
|
|
||||||
|
## Sécurité
|
||||||
|
|
||||||
|
- Sans `KANBANTE_AUTH_*`, **quiconque atteint le port 8080 voit tous les
|
||||||
|
dépôts visibles par le jeton et peut modifier les boards** — l'app
|
||||||
|
l'annonce par un avertissement au démarrage. Définis les identifiants,
|
||||||
|
ou mets Kanbante derrière un reverse proxy authentifiant, et pose
|
||||||
|
`KANBANTE_REQUIRE_AUTH=1` pour échouer fermé.
|
||||||
|
- Tous les POST exigent un jeton CSRF (cookie double-submit posé par les
|
||||||
|
pages) : les appels API directs doivent d'abord charger une page pour
|
||||||
|
obtenir le cookie, puis envoyer le jeton (en-tête `X-CSRF-Token` ou
|
||||||
|
champ `csrf_token`).
|
||||||
|
- Aucun secret n'est versionné : le jeton passe uniquement par
|
||||||
|
l'environnement / le fichier `.env` local (ignoré par git).
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
kanbante/
|
kanbante/
|
||||||
├── app/
|
├── app/
|
||||||
│ ├── main.py # FastAPI app (routes + API)
|
│ ├── main.py # FastAPI app (routes, auth, CSRF, lifespan)
|
||||||
│ ├── gitea_client.py # Client API Gitea
|
│ ├── config.py # Réglages par variables d'environnement
|
||||||
│ ├── models.py # SQLite (état du board local)
|
│ ├── gitea_client.py # Client API Gitea asynchrone, paginé, avec cache
|
||||||
│ └── templates/ # Jinja2 (dashboard.html, board.html)
|
│ ├── models.py # SQLite (état du board local + migrations)
|
||||||
|
│ └── templates/ # Jinja2 (dashboard, board, focus, error)
|
||||||
├── static/
|
├── static/
|
||||||
│ ├── css/style.css # Design system dark theme
|
│ ├── css/style.css # Design system dark theme
|
||||||
│ └── js/board.js # Drag & drop (SortableJS)
|
│ ├── js/board.js # Drag & drop, filtres, création d'issues
|
||||||
|
│ └── vendor/ # HTMX, Alpine, SortableJS (vendorés, aucun CDN)
|
||||||
|
├── tests/ # Suite pytest
|
||||||
├── Dockerfile
|
├── Dockerfile
|
||||||
├── docker-compose.yml
|
├── docker-compose.yml
|
||||||
└── README.md
|
└── README.md
|
||||||
@@ -92,12 +133,29 @@ kanbante/
|
|||||||
|---------|-------|-------------|
|
|---------|-------|-------------|
|
||||||
| GET | `/` | Dashboard tous les projets |
|
| GET | `/` | Dashboard tous les projets |
|
||||||
| GET | `/board/{owner}/{repo}` | Kanban board |
|
| GET | `/board/{owner}/{repo}` | Kanban board |
|
||||||
| POST | `/api/move` | Déplacer une issue |
|
| GET | `/focus` | En cours + En révision, tous projets actifs |
|
||||||
|
| POST | `/api/move` | Déplacer une issue (ordre persisté, synchro Gitea) |
|
||||||
|
| POST | `/api/issues` | Créer une issue Gitea depuis le board |
|
||||||
| POST | `/api/notes` | Sauvegarder des notes |
|
| POST | `/api/notes` | Sauvegarder des notes |
|
||||||
| GET | `/api/stats` | Statistiques JSON |
|
| GET | `/api/stats` | Statistiques JSON |
|
||||||
| GET | `/api/projects` | Projets JSON |
|
| GET | `/api/projects` | Projets JSON (actifs / inactifs / archivés) |
|
||||||
| GET | `/api/health` | Health check |
|
| GET | `/api/health` | Liveness (aucune dépendance) |
|
||||||
|
| GET | `/api/readiness` | Readiness : teste SQLite + Gitea (503 si KO) |
|
||||||
|
|
||||||
|
Les POST répondent avec des codes explicites : `400` entrée invalide,
|
||||||
|
`403` jeton CSRF manquant/invalide, `413` note trop longue, `502` Gitea
|
||||||
|
injoignable.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -e ".[dev]"
|
||||||
|
pytest
|
||||||
|
```
|
||||||
|
|
||||||
|
La CI (`.gitea/workflows/ci.yml`) lance la même suite à chaque push.
|
||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
|
|
||||||
MIT
|
MIT — voir [LICENSE](LICENSE). Historique des versions :
|
||||||
|
[CHANGELOG.md](CHANGELOG.md).
|
||||||
|
|||||||
+9
-2
@@ -1,5 +1,3 @@
|
|||||||
version: '3'
|
|
||||||
|
|
||||||
services:
|
services:
|
||||||
kanbante:
|
kanbante:
|
||||||
build: .
|
build: .
|
||||||
@@ -10,9 +8,18 @@ services:
|
|||||||
- GITEA_URL=${GITEA_URL:-https://git.dracodev.net}
|
- GITEA_URL=${GITEA_URL:-https://git.dracodev.net}
|
||||||
- GITEA_TOKEN=${GITEA_TOKEN}
|
- GITEA_TOKEN=${GITEA_TOKEN}
|
||||||
- KANBANTE_DB_PATH=/data/kanbante.db
|
- KANBANTE_DB_PATH=/data/kanbante.db
|
||||||
|
# Strongly recommended: without these, the app is unauthenticated.
|
||||||
|
- KANBANTE_AUTH_USER=${KANBANTE_AUTH_USER:-}
|
||||||
|
- KANBANTE_AUTH_PASSWORD=${KANBANTE_AUTH_PASSWORD:-}
|
||||||
|
- KANBANTE_REQUIRE_AUTH=${KANBANTE_REQUIRE_AUTH:-0}
|
||||||
volumes:
|
volumes:
|
||||||
- kanbante_data:/data
|
- kanbante_data:/data
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8080/api/health', timeout=4)"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
kanbante_data:
|
kanbante_data:
|
||||||
|
|||||||
+6
-2
@@ -1,12 +1,12 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "kanbante"
|
name = "kanbante"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
description = "Kanban project manager integrated with Gitea"
|
description = "Kanban project manager integrated with Gitea"
|
||||||
requires-python = ">=3.11"
|
requires-python = ">=3.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fastapi>=0.115",
|
"fastapi>=0.115",
|
||||||
"uvicorn[standard]>=0.32",
|
"uvicorn[standard]>=0.32",
|
||||||
"jinja2>=3.1,<3.1.6",
|
"jinja2>=3.1,<4",
|
||||||
"httpx>=0.28",
|
"httpx>=0.28",
|
||||||
"python-dotenv>=1.0",
|
"python-dotenv>=1.0",
|
||||||
"python-multipart>=0.0.18",
|
"python-multipart>=0.0.18",
|
||||||
@@ -20,3 +20,7 @@ dev = [
|
|||||||
"pytest>=8",
|
"pytest>=8",
|
||||||
"pytest-asyncio>=0.24",
|
"pytest-asyncio>=0.24",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
testpaths = ["tests"]
|
||||||
|
asyncio_mode = "auto"
|
||||||
|
|||||||
Reference in New Issue
Block a user