Add initial project structure with Docker, CI/CD, and Poetry configuration
This commit is contained in:
commit
e66777e0d1
5
.devcontainer/DockerFile
Normal file
5
.devcontainer/DockerFile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
FROM python:3.14-slim
|
||||||
|
# Instalar git y herramientas básicas
|
||||||
|
RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*
|
||||||
|
# Instalar Poetry
|
||||||
|
RUN pip install poetry
|
||||||
24
.devcontainer/devcontainer.json
Normal file
24
.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
"name": "Python Poetry Dev",
|
||||||
|
"build": { "dockerfile": "Dockerfile" },
|
||||||
|
"customizations": {
|
||||||
|
"vscode": {
|
||||||
|
"extensions": [
|
||||||
|
"ms-python.python",
|
||||||
|
"charliermarsh.ruff",
|
||||||
|
"tamasfe.even-better-toml"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"python.defaultInterpreterPath": "/usr/local/bin/python",
|
||||||
|
"editor.formatOnSave": true,
|
||||||
|
"[python]": {
|
||||||
|
"editor.defaultFormatter": "charliermarsh.ruff",
|
||||||
|
"editor.codeActionsOnSave": {
|
||||||
|
"source.organizeImports": "explicit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"postCreateCommand": "poetry install"
|
||||||
|
}
|
||||||
54
.gitea/ci.yml
Normal file
54
.gitea/ci.yml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
name: CI/CD Pipeline
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
tags: ['v*']
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-and-lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v4
|
||||||
|
with:
|
||||||
|
python-version: '3.14'
|
||||||
|
|
||||||
|
- name: Install Poetry
|
||||||
|
run: pip install poetry
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: poetry install
|
||||||
|
|
||||||
|
- name: Lint with Ruff (PEP-8 & Docstrings)
|
||||||
|
run: poetry run ruff check .
|
||||||
|
|
||||||
|
- name: Run Tests with Coverage
|
||||||
|
run: poetry run pytest --cov=my_project --cov-report=term-missing --cov-fail-under=80
|
||||||
|
|
||||||
|
publish-container:
|
||||||
|
needs: test-and-lint
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Login to Gitea Container Registry
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: ${{ gitea.server_url }}
|
||||||
|
# Nota: Quita 'https://' si server_url lo incluye y falla, suele ser solo dominio:puerto
|
||||||
|
username: ${{ gitea.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and Push Docker Image
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
${{ gitea.server_url }}/${{ gitea.repository }}:latest
|
||||||
|
${{ gitea.server_url }}/${{ gitea.repository }}:${{ gitea.ref_name }}
|
||||||
0
.gitignore
vendored
Normal file
0
.gitignore
vendored
Normal file
39
Dockerfile
Normal file
39
Dockerfile
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# Stage 1: Builder (Compilación y dependencias)
|
||||||
|
FROM python:3.14-slim as builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Variables de entorno para optimizar Poetry y Pip
|
||||||
|
ENV POETRY_NO_INTERACTION=1 \
|
||||||
|
POETRY_VIRTUALENVS_IN_PROJECT=1 \
|
||||||
|
POETRY_VIRTUALENVS_CREATE=1 \
|
||||||
|
PIP_NO_CACHE_DIR=1
|
||||||
|
|
||||||
|
# Instalar Poetry
|
||||||
|
RUN pip install poetry
|
||||||
|
|
||||||
|
# Copiar archivos de configuración primero para aprovechar el caché de capas
|
||||||
|
COPY pyproject.toml poetry.lock ./
|
||||||
|
|
||||||
|
# Instalar dependencias de producción (sin dev)
|
||||||
|
RUN poetry install --without dev --no-root
|
||||||
|
|
||||||
|
# Stage 2: Runtime (Imagen final limpia)
|
||||||
|
FROM python:3.14-slim as runtime
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
ENV VIRTUAL_ENV=/app/.venv \
|
||||||
|
PATH="/app/.venv/bin:$PATH"
|
||||||
|
|
||||||
|
# Copiar el entorno virtual generado en el stage anterior
|
||||||
|
COPY --from=builder /app/.venv /app/.venv
|
||||||
|
|
||||||
|
# Copiar el código fuente
|
||||||
|
COPY ./src /app/src
|
||||||
|
|
||||||
|
# Usuario no privilegiado por seguridad
|
||||||
|
RUN useradd -m appuser && chown -R appuser /app
|
||||||
|
USER appuser
|
||||||
|
|
||||||
|
# Punto de entrada
|
||||||
|
CMD ["python", "-m", "my_project.main"]
|
||||||
41
pyproject.toml
Normal file
41
pyproject.toml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "my-project"
|
||||||
|
version = "0.0.0"
|
||||||
|
description = "Python boilerplate for Gitea with Docker and Poetry"
|
||||||
|
authors = ["Unai Blazquez <unaibg2000@gmail.com>"]
|
||||||
|
readme = "README.md"
|
||||||
|
packages = [{include = "my_project", from = "src"}]
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = "^3.14"
|
||||||
|
|
||||||
|
[tool.poetry.group.dev.dependencies]
|
||||||
|
pytest = "^9.0.2"
|
||||||
|
pytest-cov = "^7.0.0"
|
||||||
|
ruff = "^0.14.14"
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
# --- Configuración de Ruff (Linter & Formatter) ---
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 88
|
||||||
|
target-version = "py314"
|
||||||
|
|
||||||
|
[tool.ruff.lint]
|
||||||
|
# E/F: Errores base, I: Imports (isort), D: Docstrings
|
||||||
|
select = ["E", "F", "I", "D"]
|
||||||
|
ignore = ["D100", "D104"] # Ignorar docstring en modulos/paquetes vacíos si se desea
|
||||||
|
|
||||||
|
[tool.ruff.lint.pydocstyle]
|
||||||
|
convention = "google" # Estilo de docstring (Google, NumPy o PEP 257)
|
||||||
|
|
||||||
|
# --- Configuración de Coverage ---
|
||||||
|
[tool.coverage.run]
|
||||||
|
source = ["src"]
|
||||||
|
branch = true
|
||||||
|
|
||||||
|
[tool.coverage.report]
|
||||||
|
fail_under = 80 # CI falla si el coverage es menor al 80%
|
||||||
|
show_missing = true
|
||||||
0
src/my-project/__init__.py
Normal file
0
src/my-project/__init__.py
Normal file
0
src/my-project/main.py
Normal file
0
src/my-project/main.py
Normal file
0
tests/.gitkeep
Normal file
0
tests/.gitkeep
Normal file
Loading…
x
Reference in New Issue
Block a user