commit e66777e0d1b11d0cba75909ff307553695e52c42 Author: unai_71 Date: Sun Feb 1 17:23:03 2026 +0100 Add initial project structure with Docker, CI/CD, and Poetry configuration diff --git a/.devcontainer/DockerFile b/.devcontainer/DockerFile new file mode 100644 index 0000000..13eb708 --- /dev/null +++ b/.devcontainer/DockerFile @@ -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 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..3a15ffb --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -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" +} diff --git a/.gitea/ci.yml b/.gitea/ci.yml new file mode 100644 index 0000000..0c6e37a --- /dev/null +++ b/.gitea/ci.yml @@ -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 }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..ae6429c --- /dev/null +++ b/Dockerfile @@ -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"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c812d5a --- /dev/null +++ b/pyproject.toml @@ -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 "] +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 diff --git a/src/my-project/__init__.py b/src/my-project/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/my-project/main.py b/src/my-project/main.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/.gitkeep b/tests/.gitkeep new file mode 100644 index 0000000..e69de29