⚙️ Como automatizar tu librería en PyPI con GitHub Actions

Continuando con un post anterior donde publicamos nuestra librería a PyPI, vamos a ir un paso más allá en el proceso de construcción y despliegue (o, mejor dicho, build y release). En este tutorial, crearemos nuestro propio workflow en GitHub Actions, aprovechando que nuestro repositorio ya está en GitHub, para automatizar este proceso y hacerlo más eficiente y menos propenso a errores.
Al final de este tutorial tendremos configurado un workflow que construye y publica en PyPI de forma automática con cada nueva release que se cree en el repositorio de GitHub.
👉 Si aún no publicaste tu librería en PyPI, te recomiendo comenzar por este tutorial previo:
⚙️ ¿Qué es GitHub Actions?
GitHub Actions es una plataforma de CI/CD (Integración y Entrega Continua) integrada directamente en GitHub. Permite automatizar tareas dentro del ciclo de vida de tu proyecto, como ejecutar tests, construir paquetes, y desplegar código, todo sin salir de tu repositorio.
La magia está en los workflows, que son conjuntos de instrucciones definidas en archivos YAML. Estos workflows se ejecutan en respuesta a eventos específicos, como hacer un push, crear un tag, abrir un pull request o crear un nuevo release.
En el caso de una librería de Python, esto nos permite automatizar pasos como:
Construir los paquetes (
sdistywheel)Publicar automáticamente en PyPI o TestPyPI cuando subimos una nueva versión
Con unas pocas líneas de configuración, podemos lograr que todo esto suceda de forma automática cada vez que haces un release, reduciendo errores y ganando tiempo.
📦 Automatizando la publicación en PyPI con GitHub Actions
✅ Requisitos previos
Antes de iniciar, asegúrate de tener:
Un repositorio de GitHub con tu librería
Una cuenta de PyPI
Un API Token generado de tu cuenta de PyPI
👉 Si ya seguiste el tutorial anterior, deberías tener todo esto listo. Si no, te recomiendo revisarlo antes de seguir.
🔐 Agregar tu token de PyPI como secret en GitHub
Debemos configurar en nuestro repositorio un nuevo secret para usarlo en los workflows, para esto solo debemos seguir los siguientes pasos:
Ir a tu repositorio en GitHub.
Hacer clic en Settings.
En el menú lateral, clic en Secrets and variables → Actions.

Clic en New repository secret.
El nombre será
PYPI_API_TOKENy en el valor pegá tu API key de PyPI.Clic en Add secret.

Esto es lo que usa GitHub Actions para autenticar y publicar la librería.
📁 Estructura de archivos
Ya con todo esto listo podemos empezar, lo primero que debemos saber es que para que nuestra Github Actions funcione los workflows deben estar en una carpeta llama .github/workflows en la raíz de nuestro repositorio, dentro de esta carpeta ira nuestro archivo de workflow llamado python-publish.yml.
Podemos crear todo usando los siguientes comandos:
$ mkdir -p .github/workflows
$ touch .github/workflows/python-publish.yml
La estructura de archivos quedaría similar a esta:
rafnixg-lib/
│
├── .github/
│ └── workflows/
│ └── python-publish.yml
├── src/
│ └── rafnixg/
│ ├── __init__.py
│ ├── __main__.py
│ └── rafnixg.py
│
├── LICENSE
├── README.md
└── pyproject.toml
🚀 Configurando el workflow
Vamos a iniciar creando el contenido de nuestro archivo de workflow python-publish.yml.
🎯Activando el workflow al publicar un release
name: Publicar Paquete a PyPI
on:
release:
types: [published]
Esto indica el nombre que tendrá nuestro workflow y también define que solo se va a ejecutar cuando las release sean published con esto limitamos que solo estas acciones sean las que disparen nuestro workflow.
🛡️Definir permisos mínimos necesarios
permissions:
contents: read
Acá le decimos a GitHub Actions que este workflow solo necesita leer el contenido del repositorio. Es una buena práctica limitar los permisos al mínimo necesario.
🛠️Crear el job y configurar el entorno
jobs:
deploy:
runs-on: ubuntu-latest
Creamos un job llamado deploy, que se ejecutará en un entorno virtual Ubuntu. Este job va a encargarse de construir y publicar nuestro paquete.
📋Agregar los pasos del workflow
Los steps son partes del proceso que irán ejecutando de forma secuencia y serán lo que ejecutarán los pasos para publicar nuestra librería en PyPI luego de ser construida.
En los steps se puede hacer uso de otros actions creados por otros usuarios como si de librerías se tratase, solo debemos indicarlo con uses: actions/nombre-del-actions@version y tambien podemos usar comando sobre la máquina virtual donde se está ejecutando la actions con el comando run: comando bash
steps:
- name: Clonando repositorio
uses: actions/checkout@v3
- name: Configurando Python 3
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Instalando dependencias
run: |
python -m pip install --upgrade pip
pip install build
- name: Construir Paquete
run: python -m build
- name: Publicar Paquete
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
📂 Clonando el repositorio
- name: Clonando repositorio
uses: actions/checkout@v3
Usamos la acción oficial para clonar el código del repositorio, paso necesario para poder construir el paquete.
🐍 Configurar el entorno de Python
- name: Configurando Python 3
uses: actions/setup-python@v3
with:
python-version: '3.x'
Le decimos a GitHub Actions que configure un entorno de Python (versión 3.x). Esto es clave para poder instalar dependencias y ejecutar los comandos de build.
📥 Instalando las dependencias necesarias
- name: Instalando dependencias
run: |
python -m pip install --upgrade pip
pip install build
Actualizamos pip y luego instalamos el módulo build, que nos permite crear los archivos .tar.gz y .whl que necesita PyPI.
🏗️Construir el paquete
- name: Construir Paquete
run: python -m build
Este paso ejecuta python -m build, que genera el paquete listo para ser publicado en la carpeta dist/.
📤Publicar el paquete en PyPI
- name: Publicar Paquete
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
Finalmente, usamos la acción oficial para subir el paquete a PyPI. Aquí usamos el API Key que se guarda como Secret en el repositorio de GitHub (PYPI_API_TOKEN), para evitar exponer credenciales.
📄 Archivo completo del workflow (python-publish.yml)
El archivo python-publish.yml finalmente queda de la siguiente manera:
name: Publicar Paquete a PyPI
on:
release:
types: [published]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Clonando repositorio
uses: actions/checkout@v3
- name: Configurando Python 3
uses: actions/setup-python@v3
with:
python-version: '3.x'
- name: Instalando dependencias
run: |
python -m pip install --upgrade pip
pip install build
- name: Construir Paquete
run: python -m build
- name: Publicar Paquete
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
💾 Subiendo los cambios al repositorio
Ya con nuestro archivo creado, solo nos resta subir un commit con los cambios que tenemos:
$ git add .github/workflows/python-publish.yml
$ git commit -m "Add GitHub Actions workflow for PyPI release"
$ git push origin
Creamos un tag y lo subimos:
$ git tag v1.0.1
$ git push origin --tags
Revisamos nuestro repositorio de GitHub y nos aseguramos de que se subió todo correctamente, para seguir con la creación de una nueva release.
🏷️ Crear una nueva release en GitHub
En nuestro repositorio hacemos clic en Releases. para ingresar a la página de todas las releases que vamos a haciendo.

En esta página hacemos clic en “draf a new release“

Esto nos abre el formulario para crear nuevas releases, acá debemos seleccionar el tag correspondiente con la release en “Choose a tag“ y hacer clic en “Generate release notes“, esto genera una descripción usando los commits y los Pull Request.
Por último, revisa la descripción ajusta si lo necesitas y dale clic a “Publish release“.

✅ Verificar el resultado de la publicación
Cada vez que crees una nueva release, se publicará una nueva versión de tu paquete en PyPI. En la tab “Actions“ de nuestro repositorio vamos a ver cómo se ejecuta el workflow que lo publica.

🧠 Conclusión
Automatizar la publicación con GitHub Actions no solo te ahorra tiempo, también reduce errores y hace que todo el proceso sea mucho más limpio y profesional. Una vez configurado, solo tienes que enfocarte en mejorar tu librería y dejar que la publicación se maneje sola ✨





