Clase 05 · 23 minGratis

Git, deuda técnica y GitHub Actions

Clase 5 del curso gratis de buenas prácticas en Python: subimos el proyecto con git desde la terminal, pagamos la deuda técnica que marcaba Pylint y automatizamos Pylint y pytest con GitHub Actions.

Toca cualquier marca ▸ 0:00 de los apuntes y el video salta a ese momento. Abrir en YouTube

Del computador a GitHub, desde la terminal

Llevamos cuatro clases sin subir nada al repositorio. Cualquier terminal sirve (Git Bash, PowerShell, zsh); los comandos son los mismos:

bash
git branch          # ¿en qué rama estoy?
git status          # ¿qué cambió y qué no tiene seguimiento?
git add --all       # sumar todos los cambios (o: git add ruta/al/archivo.py)
git commit -m "feat: testing criptografia"
git push origin main

add y commit solo existen en tu computador; hasta el push, GitHub no se entera. Antes del add, revisa la lista de git status: los archivos de prueba personales no deberían llegar al repositorio.

Mensajes de commit con convención

Muchos equipos usan un prefijo que dice qué tipo de cambio es:

  • feat: una funcionalidad nueva.
  • fix: un arreglo.
  • docs: documentación.

Es la convención que vas a encontrar en los repositorios de equipos de alto rendimiento, y hace que el historial se lea como una bitácora.

Deuda técnica

Las pruebas pasan, el código funciona… y Pylint sobre tests/ bajó a 7.7/10. Faltan docstrings en las funciones de prueba, la línea vacía final y un import está fuera de orden. En encriptado.py, además, el import de Fernet sube de dentro de las funciones al tope del archivo. Arreglarlo devuelve el 10/10 :

python
"""
Aqui se prueba el modulo de desencriptar un texto
"""
import pytest
from cryptography.fernet import Fernet
from app.funciones.encriptado import desencriptando_texto


@pytest.mark.parametrize("mensaje", [b"a", b"A", b"MeNsAjE", b"@"])
def test_desencriptando_texto(mensaje):
    """
    Funcion para probar la desencriptacion
    Args:
        mensaje: mensaje a ser encriptado y desencriptado con la funcion a probar
    """
    llave = Fernet.generate_key()
    mensaje_encriptado = Fernet(llave).encrypt(mensaje)
    assert desencriptando_texto(mensaje_encriptado, llave) == mensaje

Eso es deuda técnica: cosas que funcionan pero que quedaron pendientes de hacerse bien. Se puede seguir desarrollando encima, pero cada funcionalidad nueva la hace crecer . No te obsesiones con el 10/10; sí con no dejar que los pendientes se acumulen (de estilo, de pruebas y, la peor, de arquitectura).

GitHub Actions: que la máquina revise por ti

Correr pylint y pytest a mano depende de acordarse. GitHub Actions dispara una automatización cada vez que pasa algo en el repositorio, por ejemplo un push a main. Se configura con un archivo YAML en una carpeta oculta de la raíz del proyecto :

text
.github/
└── workflows/
    └── verificacion.yml
yaml
name: verificacion

on:
  push:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.10", "3.9", "3.8"]

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Set up Python ${{ matrix.python-version }}
        uses: actions/setup-python@v2
        with:
          python-version: ${{ matrix.python-version }}

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install pylint
          pip install pytest
          pip install -r requirements.txt

      - name: Analyzing the code with pylint
        run: |
          pylint app

      - name: Analyzing the test code with pylint
        run: |
          pylint tests

      - name: Run unit tests
        run: |
          pytest -v tests

Lo que vale la pena entender:

  • runs-on: ubuntu-latest — la revisión corre en una máquina Linux limpia, como la mayoría de servidores en la nube .
  • matrix — el mismo trabajo se repite en Python 3.10, 3.9 y 3.8 . Si tu código solo funciona en tu versión, aquí lo descubres.
  • steps — exactamente los comandos que correrías en tu computador. No hace falta memorizar la sintaxis: GitHub trae plantillas.

En YAML la indentación es parte de la sintaxis. El primer intento falla por eso : si ves una ✕ roja en la pestaña Actions, abre el paso que falló y lee el error.

Cuando el pipeline falla, te escribe

Cada ejecución fallida manda un correo. Puede volverse molesto, pero es la idea: un recordatorio que no se calla hasta que lo arreglas. Esto es el primer paso de lo que se conoce como integración continua (CI): cada cambio pasa por la misma verificación antes de que alguien lo dé por bueno.

El reto de esta clase

Haz que el workflow corra también cuando alguien abra un pull request hacia main, no solo con push. Así la revisión ocurre antes de mezclar el cambio.

Ver una solución posible
yaml
on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

Sigue con la clase 6

TDD con hash SHA-256 y cobertura

Seguir el canal de WhatsApp