Limpieza automática de versiones en PowerClient y PowerServer con Python

Si trabajas con PowerClient o PowerServer, probablemente ya lo habrás notado: cada vez que publicas una nueva versión de tu aplicación, se genera una carpeta numerada en el servidor con todos los binarios necesarios. Hasta aquí, todo correcto.

El problema: PowerBuilder no limpia lo que publica

El problema es que PowerBuilder no elimina las versiones antiguas. Nunca. Ni una. Se van acumulando carpetas y más carpetas en tu IIS, versión tras versión, ocupando gigas y gigas de espacio en disco que nadie va a necesitar jamás.

El propio deploylist.ini.zip (que en realidad es un archivo INI disfrazado de ZIP) tiene un campo MinimumValidVersion que indica cuál es la versión mínima válida. Cualquier versión por debajo de ese número es basura: el cliente nunca la va a descargar. Pero ahí se queda, ocupando espacio en el servidor.

En un entorno de producción con varios proyectos publicados, esto se convierte en un problema real. He visto servidores con decenas de versiones acumuladas por proyecto, ocupando varios gigas de espacio innecesario.

La solución: scripts Python de limpieza automática

Como PowerBuilder no lo hace, lo hacemos nosotros. He creado dos scripts en Python, uno para PowerClient y otro para PowerServer, que automatizan la limpieza:

  • powerclient_clean.py → limpia C:\inetpub\wwwroot\rsrsystem
  • powerserver_clean.py → limpia C:\inetpub\wwwroot\powerserver

¿Qué hacen exactamente?

  1. Recorren todos los proyectos publicados en la carpeta correspondiente.
  2. Leen el archivo deploylist.ini.zip de cada proyecto y extraen el valor de MinimumValidVersion.
  3. Identifican las carpetas numéricas con versión inferior a la mínima válida.
  4. Las eliminan del disco.
  5. Reescriben el archivo deploylist.ini.zip eliminando las secciones caducadas, dejándolo limpio.

Todo queda registrado en un archivo de log para que puedas revisar qué se ha limpiado y cuándo.

PowerClient: powerclient_clean.py

La estructura de PowerClient es directa: cada proyecto tiene sus carpetas de versión directamente dentro de su directorio.

rsrsystem/
├── MiProyecto/
│   ├── deploylist.ini.zip
│   ├── 12/          ← caducada
│   ├── 13/          ← caducada
│   ├── 14/          ← versión mínima válida
│   └── 15/          ← última versión
└── OtroProyecto/
    ├── deploylist.ini.zip
    └── ...

El script recorre cada proyecto, parsea el INI, y elimina las carpetas y secciones por debajo de MinimumValidVersion. Excluye automáticamente las carpetas .well-known y CloudAppPublisher.

Genera tus propios scripts con Claude Code

En lugar de publicar el código fuente completo, voy a compartir algo más útil: el prompt que le di a Claude Code para que los generara. Así cada uno puede adaptarlo a su entorno, sus rutas y sus necesidades concretas.

Para PowerClient, el prompt fue algo así:

Crea un script Python que limpie las publicaciones caducadas de PowerClient en IIS. Las aplicaciones están en C:\inetpub\wwwroot\powerclient. Cada proyecto tiene un archivo deploylist.ini.zip (que en realidad es un INI en texto plano, no un ZIP) con un campo MinimumValidVersion en la sección [Public]. Las versiones se publican en carpetas numéricas (1, 2, 3...). El script debe: leer MinimumValidVersion, borrar las carpetas con número inferior, y reescribir el deploylist.ini.zip eliminando las secciones caducadas. Que ignore las carpetas .well-known y CloudAppPublisher. Que genere un log con todo lo que hace.


Para PowerServer, el prompt:

Crea un script Python que limpie las publicaciones caducadas de PowerServer en IIS. Las aplicaciones están en C:\inetpub\wwwroot\powerserver. La estructura es un nivel más profunda que PowerClient: cada proyecto contiene subcarpetas (como frontend) y es dentro de esas subcarpetas donde está el deploylist.ini.zip y las carpetas numéricas de versión. El script debe: buscar en cada proyecto las subcarpetas que contengan deploylist.ini.zip, leer MinimumValidVersion, borrar las carpetas con número inferior, y reescribir el deploylist.ini.zip eliminando las secciones caducadas. Que ignore la carpeta CloudAppPublisher en todos los niveles. Que genere un log con todo lo que hace.


Lo bueno de este enfoque es que Claude Code entiende tu entorno. Si tus rutas son diferentes, si quieres que también limpie logs antiguos, o si prefieres que te envíe un email con el resumen... solo tienes que pedírselo. El resultado son scripts adaptados a tu servidor, no un código genérico que tengas que modificar.

El truco del deploylist.ini.zip

Una curiosidad que es clave para que el prompt funcione: el archivo deploylist.ini.zip no es un ZIP. Es un archivo de texto plano con formato INI que por alguna razón Appeon decidió nombrar con extensión .zip. Por eso hay que abrirlo directamente como texto (encoding="utf-8-sig" para gestionar el BOM) en lugar de descomprimirlo.

Su estructura es sencilla:

[Public]
MinimumValidVersion=14
[12]
VersionNo=12
...
[13]
VersionNo=13
...
[14]
VersionNo=14
...

La estructura en disco

Para que tengas claro lo que el script debe limpiar, así es como se organizan las versiones en cada caso:

PowerClient — las carpetas de versión cuelgan directamente del proyecto:

rsrsystem/
├── MiProyecto/
│   ├── deploylist.ini.zip
│   ├── 12/          ← caducada
│   ├── 13/          ← caducada
│   ├── 14/          ← versión mínima válida
│   └── 15/          ← última versión

PowerServer — hay un nivel intermedio (subcarpeta frontend):

powerserver/
├── MiApp/
│   └── frontend/
│       ├── deploylist.ini.zip
│       ├── 5/       ← caducada
│       ├── 6/       ← versión mínima válida
│       └── 7/       ← última versión

Programar la limpieza automática

Ejecutar los scripts a mano está bien para una limpieza puntual, pero lo ideal es programarlos como tarea automática en el Programador de Tareas de Windows. En mi caso los tengo programados a diario, cada uno a una hora diferente para que no se pisen. La frecuencia y el horario ya dependen de cada uno: si publicas a menudo, a diario; si no, con una vez a la semana sobra.

Conclusión

Es una de esas limitaciones de PowerBuilder que te encuentras cuando gestionas un servidor en producción: nadie te avisa de que las versiones se acumulan, y cuando te das cuenta ya tienes el disco lleno de carpetas que nadie necesita.

La solución es sencilla: un buen prompt a Claude Code, un pequeño script en Python y una tarea programada...

Automatización sencilla, servidor limpio… y PowerBuilder funcionando como siempre. 😉

Comentarios